Merge moonbone.local:/mnt/gentoo64/work/bk-trees/mysql-5.0-opt
into moonbone.local:/mnt/gentoo64/work/test-5.1-opt-mysql
This commit is contained in:
commit
df081a3a4f
@ -474,6 +474,7 @@ CREATE TABLE t4 (a DATE);
|
|||||||
INSERT INTO t4 VALUES ('1972-02-06'), ('1972-07-29');
|
INSERT INTO t4 VALUES ('1972-02-06'), ('1972-07-29');
|
||||||
SELECT * FROM t4 WHERE a IN ('1972-02-06','19772-07-29');
|
SELECT * FROM t4 WHERE a IN ('1972-02-06','19772-07-29');
|
||||||
a
|
a
|
||||||
|
1972-02-06
|
||||||
Warnings:
|
Warnings:
|
||||||
Warning 1292 Incorrect date value: '19772-07-29' for column 'a' at row 1
|
Warning 1292 Incorrect date value: '19772-07-29' for column 'a' at row 1
|
||||||
DROP TABLE t1,t2,t3,t4;
|
DROP TABLE t1,t2,t3,t4;
|
||||||
|
@ -336,3 +336,25 @@ id f1
|
|||||||
0 test1
|
0 test1
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
SET SQL_MODE='';
|
SET SQL_MODE='';
|
||||||
|
CREATE TABLE t1 (
|
||||||
|
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||||
|
c1 CHAR(1) UNIQUE KEY,
|
||||||
|
cnt INT DEFAULT 1
|
||||||
|
);
|
||||||
|
INSERT INTO t1 (c1) VALUES ('A'), ('B'), ('C');
|
||||||
|
SELECT * FROM t1;
|
||||||
|
id c1 cnt
|
||||||
|
1 A 1
|
||||||
|
2 B 1
|
||||||
|
3 C 1
|
||||||
|
INSERT INTO t1 (c1) VALUES ('A'), ('X'), ('Y'), ('Z')
|
||||||
|
ON DUPLICATE KEY UPDATE cnt=cnt+1;
|
||||||
|
SELECT * FROM t1;
|
||||||
|
id c1 cnt
|
||||||
|
1 A 2
|
||||||
|
2 B 1
|
||||||
|
3 C 1
|
||||||
|
4 X 1
|
||||||
|
5 Y 1
|
||||||
|
6 Z 1
|
||||||
|
DROP TABLE t1;
|
||||||
|
@ -264,6 +264,52 @@ f2
|
|||||||
SELECT 1 from dual where NOW() BETWEEN CURRENT_DATE() - INTERVAL 1 DAY AND CURRENT_DATE();
|
SELECT 1 from dual where NOW() BETWEEN CURRENT_DATE() - INTERVAL 1 DAY AND CURRENT_DATE();
|
||||||
1
|
1
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
create table t1 (f1 date);
|
||||||
|
insert into t1 values('01-01-01'),('01-01-02'),('01-01-03');
|
||||||
|
select * from t1 where f1 in ('01-01-01','2001-01-02','2001-01-03 00:00:00');
|
||||||
|
f1
|
||||||
|
2001-01-01
|
||||||
|
2001-01-02
|
||||||
|
2001-01-03
|
||||||
|
create table t2(f2 datetime);
|
||||||
|
insert into t2 values('01-01-01 00:00:00'),('01-02-03 12:34:56'),('02-04-06 11:22:33');
|
||||||
|
select * from t2 where f2 in ('01-01-01','01-02-03 12:34:56','01-02-03');
|
||||||
|
f2
|
||||||
|
2001-01-01 00:00:00
|
||||||
|
2001-02-03 12:34:56
|
||||||
|
select * from t1,t2 where '01-01-02' in (f1, cast(f2 as date));
|
||||||
|
f1 f2
|
||||||
|
2001-01-02 2001-01-01 00:00:00
|
||||||
|
2001-01-02 2001-02-03 12:34:56
|
||||||
|
2001-01-02 2002-04-06 11:22:33
|
||||||
|
select * from t1,t2 where '01-01-01' in (f1, '01-02-03');
|
||||||
|
f1 f2
|
||||||
|
2001-01-01 2001-01-01 00:00:00
|
||||||
|
2001-01-01 2001-02-03 12:34:56
|
||||||
|
2001-01-01 2002-04-06 11:22:33
|
||||||
|
select * from t1,t2 where if(1,'01-02-03 12:34:56','') in (f1, f2);
|
||||||
|
f1 f2
|
||||||
|
2001-01-01 2001-02-03 12:34:56
|
||||||
|
2001-01-02 2001-02-03 12:34:56
|
||||||
|
2001-01-03 2001-02-03 12:34:56
|
||||||
|
create table t3(f3 varchar(20));
|
||||||
|
insert into t3 select * from t2;
|
||||||
|
select * from t2,t3 where f2 in (f3,'03-04-05');
|
||||||
|
f2 f3
|
||||||
|
2001-01-01 00:00:00 2001-01-01 00:00:00
|
||||||
|
2001-02-03 12:34:56 2001-02-03 12:34:56
|
||||||
|
2002-04-06 11:22:33 2002-04-06 11:22:33
|
||||||
|
select f1,f2,f3 from t1,t2,t3 where (f1,'1') in ((f2,'1'),(f3,'1'));
|
||||||
|
f1 f2 f3
|
||||||
|
2001-01-01 2001-01-01 00:00:00 2001-01-01 00:00:00
|
||||||
|
2001-01-01 2001-02-03 12:34:56 2001-01-01 00:00:00
|
||||||
|
2001-01-01 2002-04-06 11:22:33 2001-01-01 00:00:00
|
||||||
|
2001-01-01 2001-01-01 00:00:00 2001-02-03 12:34:56
|
||||||
|
2001-01-01 2001-01-01 00:00:00 2002-04-06 11:22:33
|
||||||
|
select f1 from t1 where ('1',f1) in (('1','01-01-01'),('1','2001-1-1 0:0:0'),('1','02-02-02'));
|
||||||
|
f1
|
||||||
|
2001-01-01
|
||||||
|
drop table t1,t2,t3;
|
||||||
select least(cast('01-01-01' as date), '01-01-02');
|
select least(cast('01-01-01' as date), '01-01-02');
|
||||||
least(cast('01-01-01' as date), '01-01-02')
|
least(cast('01-01-01' as date), '01-01-02')
|
||||||
2001-01-01
|
2001-01-01
|
||||||
@ -279,6 +325,12 @@ greatest(cast('01-01-01' as date), '01-01-02') + 0
|
|||||||
select least(cast('01-01-01' as datetime), '01-01-02') + 0;
|
select least(cast('01-01-01' as datetime), '01-01-02') + 0;
|
||||||
least(cast('01-01-01' as datetime), '01-01-02') + 0
|
least(cast('01-01-01' as datetime), '01-01-02') + 0
|
||||||
20010101000000
|
20010101000000
|
||||||
|
select cast(least(cast('01-01-01' as datetime), '01-01-02') as signed);
|
||||||
|
cast(least(cast('01-01-01' as datetime), '01-01-02') as signed)
|
||||||
|
20010101000000
|
||||||
|
select cast(least(cast('01-01-01' as datetime), '01-01-02') as decimal);
|
||||||
|
cast(least(cast('01-01-01' as datetime), '01-01-02') as decimal)
|
||||||
|
20010101000000.00
|
||||||
DROP PROCEDURE IF EXISTS test27759 ;
|
DROP PROCEDURE IF EXISTS test27759 ;
|
||||||
CREATE PROCEDURE test27759()
|
CREATE PROCEDURE test27759()
|
||||||
BEGIN
|
BEGIN
|
||||||
|
@ -247,3 +247,20 @@ REPLACE INTO t1 VALUES (0,"test1",null);
|
|||||||
SELECT id, f1 FROM t1;
|
SELECT id, f1 FROM t1;
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
SET SQL_MODE='';
|
SET SQL_MODE='';
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug#27954: multi-row INSERT ... ON DUPLICATE with duplicated
|
||||||
|
# row at the first place into table with AUTO_INCREMENT and
|
||||||
|
# additional UNIQUE key.
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (
|
||||||
|
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||||
|
c1 CHAR(1) UNIQUE KEY,
|
||||||
|
cnt INT DEFAULT 1
|
||||||
|
);
|
||||||
|
INSERT INTO t1 (c1) VALUES ('A'), ('B'), ('C');
|
||||||
|
SELECT * FROM t1;
|
||||||
|
INSERT INTO t1 (c1) VALUES ('A'), ('X'), ('Y'), ('Z')
|
||||||
|
ON DUPLICATE KEY UPDATE cnt=cnt+1;
|
||||||
|
SELECT * FROM t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
@ -179,6 +179,25 @@ select f2 from t1 where DATE(f2) between "2001-4-15" AND "01-4-15";
|
|||||||
SELECT 1 from dual where NOW() BETWEEN CURRENT_DATE() - INTERVAL 1 DAY AND CURRENT_DATE();
|
SELECT 1 from dual where NOW() BETWEEN CURRENT_DATE() - INTERVAL 1 DAY AND CURRENT_DATE();
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug#28133: Wrong DATE/DATETIME comparison in IN() function.
|
||||||
|
#
|
||||||
|
create table t1 (f1 date);
|
||||||
|
insert into t1 values('01-01-01'),('01-01-02'),('01-01-03');
|
||||||
|
select * from t1 where f1 in ('01-01-01','2001-01-02','2001-01-03 00:00:00');
|
||||||
|
create table t2(f2 datetime);
|
||||||
|
insert into t2 values('01-01-01 00:00:00'),('01-02-03 12:34:56'),('02-04-06 11:22:33');
|
||||||
|
select * from t2 where f2 in ('01-01-01','01-02-03 12:34:56','01-02-03');
|
||||||
|
select * from t1,t2 where '01-01-02' in (f1, cast(f2 as date));
|
||||||
|
select * from t1,t2 where '01-01-01' in (f1, '01-02-03');
|
||||||
|
select * from t1,t2 where if(1,'01-02-03 12:34:56','') in (f1, f2);
|
||||||
|
create table t3(f3 varchar(20));
|
||||||
|
insert into t3 select * from t2;
|
||||||
|
select * from t2,t3 where f2 in (f3,'03-04-05');
|
||||||
|
select f1,f2,f3 from t1,t2,t3 where (f1,'1') in ((f2,'1'),(f3,'1'));
|
||||||
|
select f1 from t1 where ('1',f1) in (('1','01-01-01'),('1','2001-1-1 0:0:0'),('1','02-02-02'));
|
||||||
|
drop table t1,t2,t3;
|
||||||
|
|
||||||
#
|
#
|
||||||
# Bug#27759: Wrong DATE/DATETIME comparison in LEAST()/GREATEST() functions.
|
# Bug#27759: Wrong DATE/DATETIME comparison in LEAST()/GREATEST() functions.
|
||||||
#
|
#
|
||||||
@ -187,6 +206,8 @@ select greatest(cast('01-01-01' as date), '01-01-02');
|
|||||||
select least(cast('01-01-01' as date), '01-01-02') + 0;
|
select least(cast('01-01-01' as date), '01-01-02') + 0;
|
||||||
select greatest(cast('01-01-01' as date), '01-01-02') + 0;
|
select greatest(cast('01-01-01' as date), '01-01-02') + 0;
|
||||||
select least(cast('01-01-01' as datetime), '01-01-02') + 0;
|
select least(cast('01-01-01' as datetime), '01-01-02') + 0;
|
||||||
|
select cast(least(cast('01-01-01' as datetime), '01-01-02') as signed);
|
||||||
|
select cast(least(cast('01-01-01' as datetime), '01-01-02') as decimal);
|
||||||
--disable_warnings
|
--disable_warnings
|
||||||
DROP PROCEDURE IF EXISTS test27759 ;
|
DROP PROCEDURE IF EXISTS test27759 ;
|
||||||
--enable_warnings
|
--enable_warnings
|
||||||
|
@ -2830,7 +2830,6 @@ in_row::in_row(uint elements, Item * item)
|
|||||||
base= (char*) new cmp_item_row[count= elements];
|
base= (char*) new cmp_item_row[count= elements];
|
||||||
size= sizeof(cmp_item_row);
|
size= sizeof(cmp_item_row);
|
||||||
compare= (qsort2_cmp) cmp_row;
|
compare= (qsort2_cmp) cmp_row;
|
||||||
tmp.store_value(item);
|
|
||||||
/*
|
/*
|
||||||
We need to reset these as otherwise we will call sort() with
|
We need to reset these as otherwise we will call sort() with
|
||||||
uninitialized (even if not used) elements
|
uninitialized (even if not used) elements
|
||||||
@ -2882,6 +2881,27 @@ byte *in_longlong::get_value(Item *item)
|
|||||||
return (byte*) &tmp;
|
return (byte*) &tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void in_datetime::set(uint pos,Item *item)
|
||||||
|
{
|
||||||
|
Item **tmp= &item;
|
||||||
|
bool is_null;
|
||||||
|
struct packed_longlong *buff= &((packed_longlong*) base)[pos];
|
||||||
|
|
||||||
|
buff->val= get_datetime_value(thd, &tmp, 0, warn_item, &is_null);
|
||||||
|
buff->unsigned_flag= 1L;
|
||||||
|
}
|
||||||
|
|
||||||
|
byte *in_datetime::get_value(Item *item)
|
||||||
|
{
|
||||||
|
bool is_null;
|
||||||
|
Item **tmp_item= lval_cache ? &lval_cache : &item;
|
||||||
|
tmp.val= get_datetime_value(thd, &tmp_item, &lval_cache, warn_item, &is_null);
|
||||||
|
if (item->null_value)
|
||||||
|
return 0;
|
||||||
|
tmp.unsigned_flag= 1L;
|
||||||
|
return (byte*) &tmp;
|
||||||
|
}
|
||||||
|
|
||||||
in_double::in_double(uint elements)
|
in_double::in_double(uint elements)
|
||||||
:in_vector(elements,sizeof(double),(qsort2_cmp) cmp_double, 0)
|
:in_vector(elements,sizeof(double),(qsort2_cmp) cmp_double, 0)
|
||||||
{}
|
{}
|
||||||
@ -2986,12 +3006,18 @@ cmp_item_row::~cmp_item_row()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void cmp_item_row::alloc_comparators()
|
||||||
|
{
|
||||||
|
if (!comparators)
|
||||||
|
comparators= (cmp_item **) current_thd->calloc(sizeof(cmp_item *)*n);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void cmp_item_row::store_value(Item *item)
|
void cmp_item_row::store_value(Item *item)
|
||||||
{
|
{
|
||||||
DBUG_ENTER("cmp_item_row::store_value");
|
DBUG_ENTER("cmp_item_row::store_value");
|
||||||
n= item->cols();
|
n= item->cols();
|
||||||
if (!comparators)
|
alloc_comparators();
|
||||||
comparators= (cmp_item **) current_thd->calloc(sizeof(cmp_item *)*n);
|
|
||||||
if (comparators)
|
if (comparators)
|
||||||
{
|
{
|
||||||
item->bring_value();
|
item->bring_value();
|
||||||
@ -3103,6 +3129,36 @@ cmp_item* cmp_item_decimal::make_same()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void cmp_item_datetime::store_value(Item *item)
|
||||||
|
{
|
||||||
|
bool is_null;
|
||||||
|
Item **tmp_item= lval_cache ? &lval_cache : &item;
|
||||||
|
value= get_datetime_value(thd, &tmp_item, &lval_cache, warn_item, &is_null);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int cmp_item_datetime::cmp(Item *arg)
|
||||||
|
{
|
||||||
|
bool is_null;
|
||||||
|
Item **tmp_item= &arg;
|
||||||
|
return value !=
|
||||||
|
get_datetime_value(thd, &tmp_item, 0, warn_item, &is_null);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int cmp_item_datetime::compare(cmp_item *ci)
|
||||||
|
{
|
||||||
|
cmp_item_datetime *l_cmp= (cmp_item_datetime *)ci;
|
||||||
|
return (value < l_cmp->value) ? -1 : ((value == l_cmp->value) ? 0 : 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
cmp_item *cmp_item_datetime::make_same()
|
||||||
|
{
|
||||||
|
return new cmp_item_datetime(warn_item);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Item_func_in::nulls_in_row()
|
bool Item_func_in::nulls_in_row()
|
||||||
{
|
{
|
||||||
Item **arg,**arg_end;
|
Item **arg,**arg_end;
|
||||||
@ -3178,12 +3234,10 @@ void Item_func_in::fix_length_and_dec()
|
|||||||
Item **arg, **arg_end;
|
Item **arg, **arg_end;
|
||||||
bool const_itm= 1;
|
bool const_itm= 1;
|
||||||
THD *thd= current_thd;
|
THD *thd= current_thd;
|
||||||
uint found_types= 0;
|
bool datetime_found= FALSE;
|
||||||
uint type_cnt= 0, i;
|
/* TRUE <=> arguments values will be compared as DATETIMEs. */
|
||||||
Item_result cmp_type= STRING_RESULT;
|
bool compare_as_datetime= FALSE;
|
||||||
left_result_type= args[0]->result_type();
|
Item *date_arg= 0;
|
||||||
if (!(found_types= collect_cmp_types(args, arg_count)))
|
|
||||||
return;
|
|
||||||
|
|
||||||
for (arg= args + 1, arg_end= args + arg_count; arg != arg_end ; arg++)
|
for (arg= args + 1, arg_end= args + arg_count; arg != arg_end ; arg++)
|
||||||
{
|
{
|
||||||
@ -3193,6 +3247,87 @@ void Item_func_in::fix_length_and_dec()
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
When comparing rows create the row comparator object beforehand to ease
|
||||||
|
the DATETIME comparison detection procedure.
|
||||||
|
*/
|
||||||
|
if (cmp_type == ROW_RESULT)
|
||||||
|
{
|
||||||
|
cmp_item_row *cmp= 0;
|
||||||
|
if (const_itm && !nulls_in_row())
|
||||||
|
{
|
||||||
|
array= new in_row(arg_count-1, 0);
|
||||||
|
cmp= &((in_row*)array)->tmp;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!(cmp= new cmp_item_row))
|
||||||
|
return;
|
||||||
|
in_item= cmp;
|
||||||
|
}
|
||||||
|
cmp->n= args[0]->cols();
|
||||||
|
cmp->alloc_comparators();
|
||||||
|
}
|
||||||
|
/* All DATE/DATETIME fields/functions has the STRING result type. */
|
||||||
|
if (cmp_type == STRING_RESULT || cmp_type == ROW_RESULT)
|
||||||
|
{
|
||||||
|
uint col, cols= args[0]->cols();
|
||||||
|
|
||||||
|
for (col= 0; col < cols; col++)
|
||||||
|
{
|
||||||
|
bool skip_column= FALSE;
|
||||||
|
/*
|
||||||
|
Check that all items to be compared has the STRING result type and at
|
||||||
|
least one of them is a DATE/DATETIME item.
|
||||||
|
*/
|
||||||
|
for (arg= args, arg_end= args + arg_count; arg != arg_end ; arg++)
|
||||||
|
{
|
||||||
|
Item *itm= ((cmp_type == STRING_RESULT) ? arg[0] :
|
||||||
|
arg[0]->element_index(col));
|
||||||
|
if (itm->result_type() != STRING_RESULT)
|
||||||
|
{
|
||||||
|
skip_column= TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (itm->is_datetime())
|
||||||
|
{
|
||||||
|
datetime_found= TRUE;
|
||||||
|
/*
|
||||||
|
Internally all DATE/DATETIME values are converted to the DATETIME
|
||||||
|
type. So try to find a DATETIME item to issue correct warnings.
|
||||||
|
*/
|
||||||
|
if (!date_arg)
|
||||||
|
date_arg= itm;
|
||||||
|
else if (itm->field_type() == MYSQL_TYPE_DATETIME)
|
||||||
|
{
|
||||||
|
date_arg= itm;
|
||||||
|
/* All arguments are already checked to have the STRING result. */
|
||||||
|
if (cmp_type == STRING_RESULT)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (skip_column)
|
||||||
|
continue;
|
||||||
|
if (datetime_found)
|
||||||
|
{
|
||||||
|
if (cmp_type == ROW_RESULT)
|
||||||
|
{
|
||||||
|
cmp_item **cmp= 0;
|
||||||
|
if (array)
|
||||||
|
cmp= ((in_row*)array)->tmp.comparators + col;
|
||||||
|
else
|
||||||
|
cmp= ((cmp_item_row*)in_item)->comparators + col;
|
||||||
|
*cmp= new cmp_item_datetime(date_arg);
|
||||||
|
/* Reset variables for the next column. */
|
||||||
|
date_arg= 0;
|
||||||
|
datetime_found= FALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
compare_as_datetime= TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
for (i= 0; i <= (uint)DECIMAL_RESULT; i++)
|
for (i= 0; i <= (uint)DECIMAL_RESULT; i++)
|
||||||
{
|
{
|
||||||
if (found_types & 1 << i)
|
if (found_types & 1 << i)
|
||||||
@ -3216,51 +3351,61 @@ void Item_func_in::fix_length_and_dec()
|
|||||||
*/
|
*/
|
||||||
if (type_cnt == 1 && const_itm && !nulls_in_row())
|
if (type_cnt == 1 && const_itm && !nulls_in_row())
|
||||||
{
|
{
|
||||||
/*
|
if (compare_as_datetime)
|
||||||
IN must compare INT/DATE/DATETIME/TIMESTAMP columns and constants
|
array= new in_datetime(date_arg, arg_count - 1);
|
||||||
as int values (the same way as equality does).
|
else
|
||||||
So we must check here if the column on the left and all the constant
|
|
||||||
values on the right can be compared as integers and adjust the
|
|
||||||
comparison type accordingly.
|
|
||||||
*/
|
|
||||||
if (args[0]->real_item()->type() == FIELD_ITEM &&
|
|
||||||
thd->lex->sql_command != SQLCOM_CREATE_VIEW &&
|
|
||||||
thd->lex->sql_command != SQLCOM_SHOW_CREATE &&
|
|
||||||
cmp_type != INT_RESULT)
|
|
||||||
{
|
{
|
||||||
Field *field= ((Item_field*) (args[0]->real_item()))->field;
|
/*
|
||||||
if (field->can_be_compared_as_longlong())
|
IN must compare INT columns and constants as int values (the same
|
||||||
|
way as equality does).
|
||||||
|
So we must check here if the column on the left and all the constant
|
||||||
|
values on the right can be compared as integers and adjust the
|
||||||
|
comparison type accordingly.
|
||||||
|
*/
|
||||||
|
if (args[0]->real_item()->type() == FIELD_ITEM &&
|
||||||
|
thd->lex->sql_command != SQLCOM_CREATE_VIEW &&
|
||||||
|
thd->lex->sql_command != SQLCOM_SHOW_CREATE &&
|
||||||
|
cmp_type != INT_RESULT)
|
||||||
{
|
{
|
||||||
bool all_converted= TRUE;
|
Field *field= ((Item_field*) (args[0]->real_item()))->field;
|
||||||
for (arg=args+1, arg_end=args+arg_count; arg != arg_end ; arg++)
|
if (field->can_be_compared_as_longlong())
|
||||||
{
|
{
|
||||||
if (!convert_constant_item (thd, field, &arg[0]))
|
bool all_converted= TRUE;
|
||||||
all_converted= FALSE;
|
for (arg=args+1, arg_end=args+arg_count; arg != arg_end ; arg++)
|
||||||
|
{
|
||||||
|
if (!convert_constant_item (thd, field, &arg[0]))
|
||||||
|
all_converted= FALSE;
|
||||||
|
}
|
||||||
|
if (all_converted)
|
||||||
|
cmp_type= INT_RESULT;
|
||||||
}
|
}
|
||||||
if (all_converted)
|
|
||||||
cmp_type= INT_RESULT;
|
|
||||||
}
|
}
|
||||||
}
|
switch (cmp_type) {
|
||||||
switch (cmp_type) {
|
case STRING_RESULT:
|
||||||
case STRING_RESULT:
|
array=new in_string(arg_count-1,(qsort2_cmp) srtcmp_in,
|
||||||
array=new in_string(arg_count - 1,(qsort2_cmp) srtcmp_in,
|
cmp_collation.collation);
|
||||||
cmp_collation.collation);
|
break;
|
||||||
break;
|
case INT_RESULT:
|
||||||
case INT_RESULT:
|
array= new in_longlong(arg_count-1);
|
||||||
array= new in_longlong(arg_count - 1);
|
break;
|
||||||
break;
|
case REAL_RESULT:
|
||||||
case REAL_RESULT:
|
array= new in_double(arg_count-1);
|
||||||
array= new in_double(arg_count - 1);
|
break;
|
||||||
break;
|
case ROW_RESULT:
|
||||||
case ROW_RESULT:
|
/*
|
||||||
array= new in_row(arg_count - 1, args[0]);
|
The row comparator was created at the beginning but only DATETIME
|
||||||
break;
|
items comparators were initialized. Call store_value() to setup
|
||||||
case DECIMAL_RESULT:
|
others.
|
||||||
array= new in_decimal(arg_count - 1);
|
*/
|
||||||
break;
|
((in_row*)array)->tmp.store_value(args[0]);
|
||||||
default:
|
break;
|
||||||
DBUG_ASSERT(0);
|
case DECIMAL_RESULT:
|
||||||
return;
|
array= new in_decimal(arg_count - 1);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
DBUG_ASSERT(0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (array && !(thd->is_fatal_error)) // If not EOM
|
if (array && !(thd->is_fatal_error)) // If not EOM
|
||||||
{
|
{
|
||||||
@ -3279,6 +3424,19 @@ void Item_func_in::fix_length_and_dec()
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
if (in_item)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
The row comparator was created at the beginning but only DATETIME
|
||||||
|
items comparators were initialized. Call store_value() to setup
|
||||||
|
others.
|
||||||
|
*/
|
||||||
|
in_item->store_value(args[0]);
|
||||||
|
}
|
||||||
|
else if (compare_as_datetime)
|
||||||
|
in_item= new cmp_item_datetime(date_arg);
|
||||||
|
else
|
||||||
|
{
|
||||||
for (i= 0; i <= (uint) DECIMAL_RESULT; i++)
|
for (i= 0; i <= (uint) DECIMAL_RESULT; i++)
|
||||||
{
|
{
|
||||||
if (found_types & (1 << i) && !cmp_items[i])
|
if (found_types & (1 << i) && !cmp_items[i])
|
||||||
@ -3292,6 +3450,7 @@ void Item_func_in::fix_length_and_dec()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
max_length= 1;
|
max_length= 1;
|
||||||
}
|
}
|
||||||
|
@ -798,6 +798,7 @@ public:
|
|||||||
|
|
||||||
class in_longlong :public in_vector
|
class in_longlong :public in_vector
|
||||||
{
|
{
|
||||||
|
protected:
|
||||||
/*
|
/*
|
||||||
Here we declare a temporary variable (tmp) of the same type as the
|
Here we declare a temporary variable (tmp) of the same type as the
|
||||||
elements of this vector. tmp is used in finding if a given value is in
|
elements of this vector. tmp is used in finding if a given value is in
|
||||||
@ -832,6 +833,30 @@ public:
|
|||||||
friend int cmp_longlong(void *cmp_arg, packed_longlong *a,packed_longlong *b);
|
friend int cmp_longlong(void *cmp_arg, packed_longlong *a,packed_longlong *b);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Class to represent a vector of constant DATE/DATETIME values.
|
||||||
|
Values are obtained with help of the get_datetime_value() function.
|
||||||
|
If the left item is a constant one then its value is cached in the
|
||||||
|
lval_cache variable.
|
||||||
|
*/
|
||||||
|
class in_datetime :public in_longlong
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
THD *thd;
|
||||||
|
/* An item used to issue warnings. */
|
||||||
|
Item *warn_item;
|
||||||
|
/* Cache for the left item. */
|
||||||
|
Item *lval_cache;
|
||||||
|
|
||||||
|
in_datetime(Item *warn_item_arg, uint elements)
|
||||||
|
:in_longlong(elements), thd(current_thd), warn_item(warn_item_arg),
|
||||||
|
lval_cache(0) {};
|
||||||
|
void set(uint pos,Item *item);
|
||||||
|
byte *get_value(Item *item);
|
||||||
|
friend int cmp_longlong(void *cmp_arg, packed_longlong *a,packed_longlong *b);
|
||||||
|
};
|
||||||
|
|
||||||
class in_double :public in_vector
|
class in_double :public in_vector
|
||||||
{
|
{
|
||||||
double tmp;
|
double tmp;
|
||||||
@ -964,6 +989,30 @@ public:
|
|||||||
cmp_item *make_same();
|
cmp_item *make_same();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Compare items in the DATETIME context.
|
||||||
|
Values are obtained with help of the get_datetime_value() function.
|
||||||
|
If the left item is a constant one then its value is cached in the
|
||||||
|
lval_cache variable.
|
||||||
|
*/
|
||||||
|
class cmp_item_datetime :public cmp_item
|
||||||
|
{
|
||||||
|
ulonglong value;
|
||||||
|
public:
|
||||||
|
THD *thd;
|
||||||
|
/* Item used for issuing warnings. */
|
||||||
|
Item *warn_item;
|
||||||
|
/* Cache for the left item. */
|
||||||
|
Item *lval_cache;
|
||||||
|
|
||||||
|
cmp_item_datetime(Item *warn_item_arg)
|
||||||
|
:thd(current_thd), warn_item(warn_item_arg), lval_cache(0) {}
|
||||||
|
void store_value(Item *item);
|
||||||
|
int cmp(Item *arg);
|
||||||
|
int compare(cmp_item *ci);
|
||||||
|
cmp_item *make_same();
|
||||||
|
};
|
||||||
|
|
||||||
class cmp_item_real :public cmp_item
|
class cmp_item_real :public cmp_item
|
||||||
{
|
{
|
||||||
double value;
|
double value;
|
||||||
@ -998,32 +1047,6 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class cmp_item_row :public cmp_item
|
|
||||||
{
|
|
||||||
cmp_item **comparators;
|
|
||||||
uint n;
|
|
||||||
public:
|
|
||||||
cmp_item_row(): comparators(0), n(0) {}
|
|
||||||
~cmp_item_row();
|
|
||||||
void store_value(Item *item);
|
|
||||||
int cmp(Item *arg);
|
|
||||||
int compare(cmp_item *arg);
|
|
||||||
cmp_item *make_same();
|
|
||||||
void store_value_by_template(cmp_item *tmpl, Item *);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class in_row :public in_vector
|
|
||||||
{
|
|
||||||
cmp_item_row tmp;
|
|
||||||
public:
|
|
||||||
in_row(uint elements, Item *);
|
|
||||||
~in_row();
|
|
||||||
void set(uint pos,Item *item);
|
|
||||||
byte *get_value(Item *item);
|
|
||||||
Item_result result_type() { return ROW_RESULT; }
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
cmp_item for optimized IN with row (right part string, which never
|
cmp_item for optimized IN with row (right part string, which never
|
||||||
be changed)
|
be changed)
|
||||||
@ -1202,6 +1225,63 @@ public:
|
|||||||
bool check_partition_func_processor(byte *int_arg) {return FALSE;}
|
bool check_partition_func_processor(byte *int_arg) {return FALSE;}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class cmp_item_row :public cmp_item
|
||||||
|
{
|
||||||
|
cmp_item **comparators;
|
||||||
|
uint n;
|
||||||
|
public:
|
||||||
|
cmp_item_row(): comparators(0), n(0) {}
|
||||||
|
~cmp_item_row();
|
||||||
|
void store_value(Item *item);
|
||||||
|
inline void alloc_comparators();
|
||||||
|
int cmp(Item *arg);
|
||||||
|
int compare(cmp_item *arg);
|
||||||
|
cmp_item *make_same();
|
||||||
|
void store_value_by_template(cmp_item *tmpl, Item *);
|
||||||
|
friend void Item_func_in::fix_length_and_dec();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class in_row :public in_vector
|
||||||
|
{
|
||||||
|
cmp_item_row tmp;
|
||||||
|
public:
|
||||||
|
in_row(uint elements, Item *);
|
||||||
|
~in_row();
|
||||||
|
void set(uint pos,Item *item);
|
||||||
|
byte *get_value(Item *item);
|
||||||
|
friend void Item_func_in::fix_length_and_dec();
|
||||||
|
Item_resul result_type() { return ROW_RESULT; };
|
||||||
|
};
|
||||||
|
|
||||||
|
class cmp_item_row :public cmp_item
|
||||||
|
{
|
||||||
|
cmp_item **comparators;
|
||||||
|
uint n;
|
||||||
|
public:
|
||||||
|
cmp_item_row(): comparators(0), n(0) {}
|
||||||
|
~cmp_item_row();
|
||||||
|
void store_value(Item *item);
|
||||||
|
inline void alloc_comparators();
|
||||||
|
int cmp(Item *arg);
|
||||||
|
int compare(cmp_item *arg);
|
||||||
|
cmp_item *make_same();
|
||||||
|
void store_value_by_template(cmp_item *tmpl, Item *);
|
||||||
|
friend void Item_func_in::fix_length_and_dec();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class in_row :public in_vector
|
||||||
|
{
|
||||||
|
cmp_item_row tmp;
|
||||||
|
public:
|
||||||
|
in_row(uint elements, Item *);
|
||||||
|
~in_row();
|
||||||
|
void set(uint pos,Item *item);
|
||||||
|
byte *get_value(Item *item);
|
||||||
|
friend void Item_func_in::fix_length_and_dec();
|
||||||
|
};
|
||||||
|
|
||||||
/* Functions used by where clause */
|
/* Functions used by where clause */
|
||||||
|
|
||||||
class Item_func_isnull :public Item_bool_func
|
class Item_func_isnull :public Item_bool_func
|
||||||
|
@ -2344,7 +2344,7 @@ double Item_func_min_max::val_real()
|
|||||||
double value=0.0;
|
double value=0.0;
|
||||||
if (compare_as_dates)
|
if (compare_as_dates)
|
||||||
{
|
{
|
||||||
ulonglong result;
|
ulonglong result= 0;
|
||||||
(void)cmp_datetimes(&result);
|
(void)cmp_datetimes(&result);
|
||||||
return (double)result;
|
return (double)result;
|
||||||
}
|
}
|
||||||
|
@ -724,6 +724,7 @@ public:
|
|||||||
my_decimal *val_decimal(my_decimal *);
|
my_decimal *val_decimal(my_decimal *);
|
||||||
void fix_length_and_dec();
|
void fix_length_and_dec();
|
||||||
enum Item_result result_type () const { return cmp_type; }
|
enum Item_result result_type () const { return cmp_type; }
|
||||||
|
bool result_as_longlong() { return compare_as_dates; };
|
||||||
bool check_partition_func_processor(byte *int_arg) {return FALSE;}
|
bool check_partition_func_processor(byte *int_arg) {return FALSE;}
|
||||||
uint cmp_datetimes(ulonglong *value);
|
uint cmp_datetimes(ulonglong *value);
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user