mirror of
https://github.com/MariaDB/server.git
synced 2026-04-29 19:55:32 +02:00
Bug#28133: Wrong DATE/DATETIME comparison in IN() function.
The IN function was comparing DATE/DATETIME values either as ints or as strings. Both methods have their disadvantages and may lead to a wrong result. Now IN function checks whether all of its arguments has the STRING result types and at least one of them is a DATE/DATETIME item. If so it uses either an object of the in_datetime class or an object of the cmp_item_datetime class to perform its work. If the IN() function arguments are rows then row columns are checked whether the DATE/DATETIME comparator should be used to compare them. The in_datetime class is used to find occurence of the item to be checked in the vector of the constant DATE/DATETIME values. The cmp_item_datetime class is used to compare items one by one in the DATE/DATETIME context. Both classes obtain values from items with help of the get_datetime_value() function and cache the left item if it is a constant one. mysql-test/t/type_datetime.test: Added a test case for the bug#28133: Wrong DATE/DATETIME comparison in IN() function. mysql-test/r/type_datetime.result: Added a test case for the bug#28133: Wrong DATE/DATETIME comparison in IN() function. mysql-test/r/func_in.result: A test case result is corrected after the fix for the bug#28133. sql/item_cmpfunc.h: Bug#28133: Wrong DATE/DATETIME comparison in IN() function. Two DATE/DATETIME comparison classes are added. The in_datetime class is used to find occurence of the item to be checked in the vector of the constant DATE/DATETIME values. The cmp_item_datetime class is used to compare items one by one in the DATE/DATETIME context. Both classes obtain values from items with help of the get_datetime_value() function and cache the left item if it is a constant one. sql/item_cmpfunc.cc: Bug#28133: Wrong DATE/DATETIME comparison in IN() function. Now IN function checks whether all of its arguments has the STRING result types and at least one of them is a DATE/DATETIME item. If so it uses either an object of the in_datetime class or an object of the cmp_item_datetime class to perform its work. If the IN() function arguments are rows then row columns are checked whether the DATE/DATETIME comparator should be used to compare them.
This commit is contained in:
parent
51d19e3242
commit
0fd2b3ddc6
5 changed files with 351 additions and 71 deletions
|
|
@ -833,6 +833,7 @@ public:
|
|||
|
||||
class in_longlong :public in_vector
|
||||
{
|
||||
protected:
|
||||
/*
|
||||
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
|
||||
|
|
@ -866,6 +867,30 @@ public:
|
|||
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
|
||||
{
|
||||
double tmp;
|
||||
|
|
@ -986,6 +1011,30 @@ public:
|
|||
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
|
||||
{
|
||||
double value;
|
||||
|
|
@ -1020,31 +1069,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);
|
||||
};
|
||||
|
||||
/*
|
||||
cmp_item for optimized IN with row (right part string, which never
|
||||
be changed)
|
||||
|
|
@ -1120,6 +1144,34 @@ public:
|
|||
CHARSET_INFO *compare_collation() { return cmp_collation.collation; }
|
||||
};
|
||||
|
||||
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 */
|
||||
|
||||
class Item_func_isnull :public Item_bool_func
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue