Commit fea4af6d authored by evgen@moonbone.local's avatar evgen@moonbone.local

item_cmpfunc.cc, type_datetime.result, type_datetime.test, item_cmpfunc.h:

  After merge fix.
parent df081a3a
...@@ -328,8 +328,8 @@ least(cast('01-01-01' as datetime), '01-01-02') + 0 ...@@ -328,8 +328,8 @@ 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 signed);
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 20010101000000
select cast(least(cast('01-01-01' as datetime), '01-01-02') as decimal); select cast(least(cast('01-01-01' as datetime), '01-01-02') as decimal(16,2));
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(16,2))
20010101000000.00 20010101000000.00
DROP PROCEDURE IF EXISTS test27759 ; DROP PROCEDURE IF EXISTS test27759 ;
CREATE PROCEDURE test27759() CREATE PROCEDURE test27759()
......
...@@ -207,7 +207,7 @@ select least(cast('01-01-01' as date), '01-01-02') + 0; ...@@ -207,7 +207,7 @@ 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 signed);
select cast(least(cast('01-01-01' as datetime), '01-01-02') as decimal); select cast(least(cast('01-01-01' as datetime), '01-01-02') as decimal(16,2));
--disable_warnings --disable_warnings
DROP PROCEDURE IF EXISTS test27759 ; DROP PROCEDURE IF EXISTS test27759 ;
--enable_warnings --enable_warnings
......
...@@ -3238,7 +3238,13 @@ void Item_func_in::fix_length_and_dec() ...@@ -3238,7 +3238,13 @@ void Item_func_in::fix_length_and_dec()
/* TRUE <=> arguments values will be compared as DATETIMEs. */ /* TRUE <=> arguments values will be compared as DATETIMEs. */
bool compare_as_datetime= FALSE; bool compare_as_datetime= FALSE;
Item *date_arg= 0; Item *date_arg= 0;
uint found_types= 0;
uint type_cnt= 0, i;
Item_result cmp_type= STRING_RESULT;
left_result_type= args[0]->result_type();
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++)
{ {
if (!arg[0]->const_item()) if (!arg[0]->const_item())
...@@ -3247,87 +3253,6 @@ void Item_func_in::fix_length_and_dec() ...@@ -3247,87 +3253,6 @@ 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)
...@@ -3344,7 +3269,90 @@ void Item_func_in::fix_length_and_dec() ...@@ -3344,7 +3269,90 @@ void Item_func_in::fix_length_and_dec()
return; return;
arg_types_compatible= TRUE; arg_types_compatible= TRUE;
} }
if (type_cnt == 1)
{
/*
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;
cmp_items[ROW_RESULT]= 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*)cmp_items[ROW_RESULT])->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;
}
}
}
}
/* /*
Row item with NULLs inside can return NULL or FALSE => Row item with NULLs inside can return NULL or FALSE =>
they can't be processed as static they can't be processed as static
...@@ -3424,33 +3432,25 @@ void Item_func_in::fix_length_and_dec() ...@@ -3424,33 +3432,25 @@ void Item_func_in::fix_length_and_dec()
} }
else else
{ {
if (in_item) if (compare_as_datetime)
{ cmp_items[STRING_RESULT]= new cmp_item_datetime(date_arg);
/*
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 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 ((Item_result)i == STRING_RESULT && if (found_types & (1 << i) && !cmp_items[i])
agg_arg_charsets(cmp_collation, args, arg_count, MY_COLL_CMP_CONV, 1)) {
return; if ((Item_result)i == STRING_RESULT &&
if (!(cmp_items[i]= agg_arg_charsets(cmp_collation, args, arg_count,
cmp_item::get_comparator((Item_result)i, MY_COLL_CMP_CONV, 1))
cmp_collation.collation))) return;
return; if (!cmp_items[i] && !(cmp_items[i]=
cmp_item::get_comparator((Item_result)i,
cmp_collation.collation)))
return;
}
} }
} }
}
} }
max_length= 1; max_length= 1;
} }
......
...@@ -1186,7 +1186,7 @@ public: ...@@ -1186,7 +1186,7 @@ public:
*/ */
bool arg_types_compatible; bool arg_types_compatible;
Item_result left_result_type; Item_result left_result_type;
cmp_item *cmp_items[5]; /* One cmp_item for each result type */ cmp_item *cmp_items[6]; /* One cmp_item for each result type */
DTCollation cmp_collation; DTCollation cmp_collation;
Item_func_in(List<Item> &list) Item_func_in(List<Item> &list)
...@@ -1207,7 +1207,7 @@ public: ...@@ -1207,7 +1207,7 @@ public:
Item_int_func::cleanup(); Item_int_func::cleanup();
delete array; delete array;
array= 0; array= 0;
for (i= 0; i <= (uint)DECIMAL_RESULT; i++) for (i= 0; i <= (uint)DECIMAL_RESULT + 1; i++)
{ {
delete cmp_items[i]; delete cmp_items[i];
cmp_items[i]= 0; cmp_items[i]= 0;
...@@ -1251,35 +1251,7 @@ public: ...@@ -1251,35 +1251,7 @@ public:
void set(uint pos,Item *item); void set(uint pos,Item *item);
byte *get_value(Item *item); byte *get_value(Item *item);
friend void Item_func_in::fix_length_and_dec(); friend void Item_func_in::fix_length_and_dec();
Item_resul result_type() { return ROW_RESULT; }; Item_result 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 */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment