mirror of
https://github.com/MariaDB/server.git
synced 2025-01-16 12:02:42 +01:00
MDEV-16451 Split Item_equal::add_const() into a virtual method in type_handler()
MDEV-16452 Split TIME and DATETIME handling in Item_func_between, in_temporal, cmp_item_internal
This commit is contained in:
parent
9043dd7a2d
commit
d60fdb5814
7 changed files with 265 additions and 112 deletions
|
@ -486,3 +486,44 @@ DROP TABLE t1;
|
|||
#
|
||||
# End of 10.2 tests
|
||||
#
|
||||
#
|
||||
# Start of 10.4 tests
|
||||
#
|
||||
#
|
||||
# MDEV-16451 Split Item_equal::add_const() into a virtual method in type_handler()
|
||||
#
|
||||
CREATE TABLE t1 (a YEAR(4));
|
||||
INSERT INTO t1 VALUES (93),(94);
|
||||
SELECT * FROM t1;
|
||||
a
|
||||
1993
|
||||
1994
|
||||
SELECT * FROM t1 WHERE a=1993 and a=93;
|
||||
a
|
||||
1993
|
||||
EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=1993 and a=93;
|
||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = 1993
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1 (a YEAR(2));
|
||||
Warnings:
|
||||
Note 1287 'YEAR(2)' is deprecated and will be removed in a future release. Please use YEAR(4) instead
|
||||
INSERT INTO t1 VALUES (93),(94);
|
||||
SELECT * FROM t1;
|
||||
a
|
||||
93
|
||||
94
|
||||
SELECT * FROM t1 WHERE a=1993 and a=93;
|
||||
a
|
||||
93
|
||||
EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=1993 and a=93;
|
||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = 93
|
||||
DROP TABLE t1;
|
||||
#
|
||||
# End of 10.4 tests
|
||||
#
|
||||
|
|
|
@ -254,3 +254,30 @@ DROP TABLE t1;
|
|||
--echo #
|
||||
--echo # End of 10.2 tests
|
||||
--echo #
|
||||
|
||||
|
||||
--echo #
|
||||
--echo # Start of 10.4 tests
|
||||
--echo #
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-16451 Split Item_equal::add_const() into a virtual method in type_handler()
|
||||
--echo #
|
||||
|
||||
CREATE TABLE t1 (a YEAR(4));
|
||||
INSERT INTO t1 VALUES (93),(94);
|
||||
SELECT * FROM t1;
|
||||
SELECT * FROM t1 WHERE a=1993 and a=93;
|
||||
EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=1993 and a=93;
|
||||
DROP TABLE t1;
|
||||
|
||||
CREATE TABLE t1 (a YEAR(2));
|
||||
INSERT INTO t1 VALUES (93),(94);
|
||||
SELECT * FROM t1;
|
||||
SELECT * FROM t1 WHERE a=1993 and a=93;
|
||||
EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=1993 and a=93;
|
||||
DROP TABLE t1;
|
||||
|
||||
--echo #
|
||||
--echo # End of 10.4 tests
|
||||
--echo #
|
||||
|
|
|
@ -1676,12 +1676,6 @@ public:
|
|||
return get_date_result(<ime, fuzzydate) ? 0 : pack_time(<ime);
|
||||
}
|
||||
|
||||
// Get a temporal value in packed DATE/DATETIME or TIME format
|
||||
longlong val_temporal_packed(enum_field_types f_type)
|
||||
{
|
||||
return f_type == MYSQL_TYPE_TIME ? val_time_packed() :
|
||||
val_datetime_packed();
|
||||
}
|
||||
bool get_seconds(ulonglong *sec, ulong *sec_part);
|
||||
virtual bool get_date_result(MYSQL_TIME *ltime, ulonglong fuzzydate)
|
||||
{ return get_date(ltime,fuzzydate); }
|
||||
|
|
|
@ -2117,23 +2117,25 @@ bool Item_func_between::fix_length_and_dec_temporal(THD *thd)
|
|||
}
|
||||
|
||||
|
||||
longlong Item_func_between::val_int_cmp_temporal()
|
||||
longlong Item_func_between::val_int_cmp_datetime()
|
||||
{
|
||||
enum_field_types f_type= m_comparator.type_handler()->field_type();
|
||||
longlong value= args[0]->val_temporal_packed(f_type), a, b;
|
||||
longlong value= args[0]->val_datetime_packed(), a, b;
|
||||
if ((null_value= args[0]->null_value))
|
||||
return 0;
|
||||
a= args[1]->val_temporal_packed(f_type);
|
||||
b= args[2]->val_temporal_packed(f_type);
|
||||
if (!args[1]->null_value && !args[2]->null_value)
|
||||
return (longlong) ((value >= a && value <= b) != negated);
|
||||
if (args[1]->null_value && args[2]->null_value)
|
||||
null_value= true;
|
||||
else if (args[1]->null_value)
|
||||
null_value= value <= b; // not null if false range.
|
||||
else
|
||||
null_value= value >= a;
|
||||
return (longlong) (!null_value && negated);
|
||||
a= args[1]->val_datetime_packed();
|
||||
b= args[2]->val_datetime_packed();
|
||||
return val_int_cmp_int_finalize(value, a, b);
|
||||
}
|
||||
|
||||
|
||||
longlong Item_func_between::val_int_cmp_time()
|
||||
{
|
||||
longlong value= args[0]->val_time_packed(), a, b;
|
||||
if ((null_value= args[0]->null_value))
|
||||
return 0;
|
||||
a= args[1]->val_time_packed();
|
||||
b= args[2]->val_time_packed();
|
||||
return val_int_cmp_int_finalize(value, a, b);
|
||||
}
|
||||
|
||||
|
||||
|
@ -2172,18 +2174,22 @@ longlong Item_func_between::val_int_cmp_int()
|
|||
return 0; /* purecov: inspected */
|
||||
a= args[1]->val_int();
|
||||
b= args[2]->val_int();
|
||||
return val_int_cmp_int_finalize(value, a, b);
|
||||
}
|
||||
|
||||
|
||||
bool Item_func_between::val_int_cmp_int_finalize(longlong value,
|
||||
longlong a,
|
||||
longlong b)
|
||||
{
|
||||
if (!args[1]->null_value && !args[2]->null_value)
|
||||
return (longlong) ((value >= a && value <= b) != negated);
|
||||
if (args[1]->null_value && args[2]->null_value)
|
||||
null_value= true;
|
||||
else if (args[1]->null_value)
|
||||
{
|
||||
null_value= value <= b; // not null if false range.
|
||||
}
|
||||
else
|
||||
{
|
||||
null_value= value >= a;
|
||||
}
|
||||
return (longlong) (!null_value && negated);
|
||||
}
|
||||
|
||||
|
@ -3653,9 +3659,18 @@ void in_time::set(uint pos,Item *item)
|
|||
buff->unsigned_flag= 1L;
|
||||
}
|
||||
|
||||
uchar *in_temporal::get_value_internal(Item *item, enum_field_types f_type)
|
||||
uchar *in_datetime::get_value(Item *item)
|
||||
{
|
||||
tmp.val= item->val_temporal_packed(f_type);
|
||||
tmp.val= item->val_datetime_packed();
|
||||
if (item->null_value)
|
||||
return 0;
|
||||
tmp.unsigned_flag= 1L;
|
||||
return (uchar*) &tmp;
|
||||
}
|
||||
|
||||
uchar *in_time::get_value(Item *item)
|
||||
{
|
||||
tmp.val= item->val_time_packed();
|
||||
if (item->null_value)
|
||||
return 0;
|
||||
tmp.unsigned_flag= 1L;
|
||||
|
@ -4011,14 +4026,6 @@ cmp_item* cmp_item_decimal::make_same()
|
|||
}
|
||||
|
||||
|
||||
void cmp_item_temporal::store_value_internal(Item *item,
|
||||
enum_field_types f_type)
|
||||
{
|
||||
value= item->val_temporal_packed(f_type);
|
||||
m_null_value= item->null_value;
|
||||
}
|
||||
|
||||
|
||||
int cmp_item_datetime::cmp_not_null(const Value *val)
|
||||
{
|
||||
DBUG_ASSERT(!val->is_null());
|
||||
|
@ -6262,76 +6269,53 @@ void Item_equal::add_const(THD *thd, Item *c)
|
|||
equal_items.push_front(c, thd->mem_root);
|
||||
return;
|
||||
}
|
||||
Item *const_item= get_const();
|
||||
switch (Item_equal::compare_type_handler()->cmp_type()) {
|
||||
case TIME_RESULT:
|
||||
{
|
||||
enum_field_types f_type= context_field->field_type();
|
||||
longlong value0= c->val_temporal_packed(f_type);
|
||||
longlong value1= const_item->val_temporal_packed(f_type);
|
||||
cond_false= c->null_value || const_item->null_value || value0 != value1;
|
||||
break;
|
||||
}
|
||||
case STRING_RESULT:
|
||||
{
|
||||
String *str1, *str2;
|
||||
/*
|
||||
Suppose we have an expression (with a string type field) like this:
|
||||
WHERE field=const1 AND field=const2 ...
|
||||
|
||||
For all pairs field=constXXX we know that:
|
||||
/*
|
||||
Suppose we have an expression (with a string type field) like this:
|
||||
WHERE field=const1 AND field=const2 ...
|
||||
|
||||
- Item_func_eq::fix_length_and_dec() performed collation and character
|
||||
set aggregation and added character set converters when needed.
|
||||
Note, the case like:
|
||||
WHERE field=const1 COLLATE latin1_bin AND field=const2
|
||||
is not handled here, because the field would be replaced to
|
||||
Item_func_set_collation, which cannot get into Item_equal.
|
||||
So all constXXX that are handled by Item_equal
|
||||
already have compatible character sets with "field".
|
||||
For all pairs field=constXXX we know that:
|
||||
|
||||
- Also, Field_str::test_if_equality_guarantees_uniqueness() guarantees
|
||||
that the comparison collation of all equalities handled by Item_equal
|
||||
match the the collation of the field.
|
||||
- Item_func_eq::fix_length_and_dec() performed collation and character
|
||||
set aggregation and added character set converters when needed.
|
||||
Note, the case like:
|
||||
WHERE field=const1 COLLATE latin1_bin AND field=const2
|
||||
is not handled here, because the field would be replaced to
|
||||
Item_func_set_collation, which cannot get into Item_equal.
|
||||
So all constXXX that are handled by Item_equal
|
||||
already have compatible character sets with "field".
|
||||
|
||||
Therefore, at Item_equal::add_const() time all constants constXXX
|
||||
should be directly comparable to each other without an additional
|
||||
character set conversion.
|
||||
It's safe to do val_str() for "const_item" and "c" and compare
|
||||
them according to the collation of the *field*.
|
||||
- Also, Field_str::test_if_equality_guarantees_uniqueness() guarantees
|
||||
that the comparison collation of all equalities handled by Item_equal
|
||||
match the the collation of the field.
|
||||
|
||||
So in a script like this:
|
||||
CREATE TABLE t1 (a VARCHAR(10) COLLATE xxx);
|
||||
INSERT INTO t1 VALUES ('a'),('A');
|
||||
SELECT * FROM t1 WHERE a='a' AND a='A';
|
||||
Item_equal::add_const() effectively rewrites the condition to:
|
||||
SELECT * FROM t1 WHERE a='a' AND 'a' COLLATE xxx='A';
|
||||
and then to:
|
||||
SELECT * FROM t1 WHERE a='a'; // if the two constants were equal
|
||||
// e.g. in case of latin1_swedish_ci
|
||||
or to:
|
||||
SELECT * FROM t1 WHERE FALSE; // if the two constants were not equal
|
||||
// e.g. in case of latin1_bin
|
||||
Therefore, at Item_equal::add_const() time all constants constXXX
|
||||
should be directly comparable to each other without an additional
|
||||
character set conversion.
|
||||
It's safe to do val_str() for "const_item" and "c" and compare
|
||||
them according to the collation of the *field*.
|
||||
|
||||
Note, both "const_item" and "c" can return NULL, e.g.:
|
||||
SELECT * FROM t1 WHERE a=NULL AND a='const';
|
||||
SELECT * FROM t1 WHERE a='const' AND a=NULL;
|
||||
SELECT * FROM t1 WHERE a='const' AND a=(SELECT MAX(a) FROM t2)
|
||||
*/
|
||||
cond_false= !(str1= const_item->val_str(&cmp_value1)) ||
|
||||
!(str2= c->val_str(&cmp_value2)) ||
|
||||
!str1->eq(str2, compare_collation());
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
Item_func_eq *func= new (thd->mem_root) Item_func_eq(thd, c, const_item);
|
||||
if (func->set_cmp_func())
|
||||
return;
|
||||
func->quick_fix_field();
|
||||
cond_false= !func->val_int();
|
||||
}
|
||||
}
|
||||
So in a script like this:
|
||||
CREATE TABLE t1 (a VARCHAR(10) COLLATE xxx);
|
||||
INSERT INTO t1 VALUES ('a'),('A');
|
||||
SELECT * FROM t1 WHERE a='a' AND a='A';
|
||||
Item_equal::add_const() effectively rewrites the condition to:
|
||||
SELECT * FROM t1 WHERE a='a' AND 'a' COLLATE xxx='A';
|
||||
and then to:
|
||||
SELECT * FROM t1 WHERE a='a'; // if the two constants were equal
|
||||
// e.g. in case of latin1_swedish_ci
|
||||
or to:
|
||||
SELECT * FROM t1 WHERE FALSE; // if the two constants were not equal
|
||||
// e.g. in case of latin1_bin
|
||||
|
||||
Note, both "const_item" and "c" can return NULL, e.g.:
|
||||
SELECT * FROM t1 WHERE a=NULL AND a='const';
|
||||
SELECT * FROM t1 WHERE a='const' AND a=NULL;
|
||||
SELECT * FROM t1 WHERE a='const' AND a=(SELECT MAX(a) FROM t2)
|
||||
*/
|
||||
|
||||
cond_false= !Item_equal::compare_type_handler()->Item_eq_value(thd, this, c,
|
||||
get_const());
|
||||
if (with_const && equal_items.elements == 1)
|
||||
cond_true= TRUE;
|
||||
if (cond_false || cond_true)
|
||||
|
|
|
@ -152,7 +152,8 @@ public:
|
|||
class SEL_ARG;
|
||||
struct KEY_PART;
|
||||
|
||||
class Item_bool_func :public Item_int_func
|
||||
class Item_bool_func :public Item_int_func,
|
||||
public Type_cmp_attributes
|
||||
{
|
||||
protected:
|
||||
/*
|
||||
|
@ -217,7 +218,7 @@ public:
|
|||
Item_bool_func(THD *thd, Item_bool_func *item) :Item_int_func(thd, item) {}
|
||||
const Type_handler *type_handler() const { return &type_handler_bool; }
|
||||
const Type_handler *fixed_type_handler() const { return &type_handler_bool; }
|
||||
virtual CHARSET_INFO *compare_collation() const { return NULL; }
|
||||
CHARSET_INFO *compare_collation() const { return NULL; }
|
||||
void fix_length_and_dec() { decimals=0; max_length=1; }
|
||||
uint decimal_precision() const { return 1; }
|
||||
bool need_parentheses_in_default() { return true; }
|
||||
|
@ -891,6 +892,7 @@ class Item_func_between :public Item_func_opt_neg
|
|||
protected:
|
||||
SEL_TREE *get_func_mm_tree(RANGE_OPT_PARAM *param,
|
||||
Field *field, Item *value);
|
||||
bool val_int_cmp_int_finalize(longlong value, longlong a, longlong b);
|
||||
public:
|
||||
String value0,value1,value2;
|
||||
Item_func_between(THD *thd, Item *a, Item *b, Item *c):
|
||||
|
@ -931,7 +933,8 @@ public:
|
|||
{ return get_item_copy<Item_func_between>(thd, this); }
|
||||
|
||||
longlong val_int_cmp_string();
|
||||
longlong val_int_cmp_temporal();
|
||||
longlong val_int_cmp_datetime();
|
||||
longlong val_int_cmp_time();
|
||||
longlong val_int_cmp_int();
|
||||
longlong val_int_cmp_real();
|
||||
longlong val_int_cmp_decimal();
|
||||
|
@ -1404,8 +1407,6 @@ public:
|
|||
*/
|
||||
class in_temporal :public in_longlong
|
||||
{
|
||||
protected:
|
||||
uchar *get_value_internal(Item *item, enum_field_types f_type);
|
||||
public:
|
||||
/* Cache for the left item. */
|
||||
|
||||
|
@ -1418,8 +1419,6 @@ public:
|
|||
Item_datetime *dt= static_cast<Item_datetime*>(item);
|
||||
dt->set(val->val, type_handler()->mysql_timestamp_type());
|
||||
}
|
||||
uchar *get_value(Item *item)
|
||||
{ return get_value_internal(item, type_handler()->field_type()); }
|
||||
friend int cmp_longlong(void *cmp_arg, packed_longlong *a,packed_longlong *b);
|
||||
};
|
||||
|
||||
|
@ -1431,6 +1430,7 @@ public:
|
|||
:in_temporal(thd, elements)
|
||||
{}
|
||||
void set(uint pos,Item *item);
|
||||
uchar *get_value(Item *item);
|
||||
const Type_handler *type_handler() const { return &type_handler_datetime2; }
|
||||
};
|
||||
|
||||
|
@ -1442,6 +1442,7 @@ public:
|
|||
:in_temporal(thd, elements)
|
||||
{}
|
||||
void set(uint pos,Item *item);
|
||||
uchar *get_value(Item *item);
|
||||
const Type_handler *type_handler() const { return &type_handler_time2; }
|
||||
};
|
||||
|
||||
|
@ -1616,7 +1617,6 @@ class cmp_item_temporal: public cmp_item_scalar
|
|||
{
|
||||
protected:
|
||||
longlong value;
|
||||
void store_value_internal(Item *item, enum_field_types type);
|
||||
public:
|
||||
cmp_item_temporal() {}
|
||||
int compare(cmp_item *ci);
|
||||
|
@ -1631,7 +1631,8 @@ public:
|
|||
{ }
|
||||
void store_value(Item *item)
|
||||
{
|
||||
store_value_internal(item, MYSQL_TYPE_DATETIME);
|
||||
value= item->val_datetime_packed();
|
||||
m_null_value= item->null_value;
|
||||
}
|
||||
int cmp_not_null(const Value *val);
|
||||
int cmp(Item *arg);
|
||||
|
@ -1647,7 +1648,8 @@ public:
|
|||
{ }
|
||||
void store_value(Item *item)
|
||||
{
|
||||
store_value_internal(item, MYSQL_TYPE_TIME);
|
||||
value= item->val_time_packed();
|
||||
m_null_value= item->null_value;
|
||||
}
|
||||
int cmp_not_null(const Value *val);
|
||||
int cmp(Item *arg);
|
||||
|
@ -3081,7 +3083,6 @@ class Item_equal: public Item_bool_func
|
|||
|
||||
const Type_handler *m_compare_handler;
|
||||
CHARSET_INFO *m_compare_collation;
|
||||
String cmp_value1, cmp_value2;
|
||||
public:
|
||||
|
||||
COND_EQUAL *upper_levels; /* multiple equalities of upper and levels */
|
||||
|
|
|
@ -3739,10 +3739,16 @@ longlong Type_handler_string_result::
|
|||
return func->val_int_cmp_string();
|
||||
}
|
||||
|
||||
longlong Type_handler_temporal_result::
|
||||
longlong Type_handler_temporal_with_date::
|
||||
Item_func_between_val_int(Item_func_between *func) const
|
||||
{
|
||||
return func->val_int_cmp_temporal();
|
||||
return func->val_int_cmp_datetime();
|
||||
}
|
||||
|
||||
longlong Type_handler_time_common::
|
||||
Item_func_between_val_int(Item_func_between *func) const
|
||||
{
|
||||
return func->val_int_cmp_time();
|
||||
}
|
||||
|
||||
longlong Type_handler_int_result::
|
||||
|
@ -6450,4 +6456,79 @@ Type_handler_hex_hybrid::type_handler_for_system_time() const
|
|||
}
|
||||
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
bool Type_handler_row::Item_eq_value(THD *thd, const Type_cmp_attributes *attr,
|
||||
Item *a, Item *b) const
|
||||
{
|
||||
DBUG_ASSERT(0);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool Type_handler_int_result::Item_eq_value(THD *thd,
|
||||
const Type_cmp_attributes *attr,
|
||||
Item *a, Item *b) const
|
||||
{
|
||||
longlong value0= a->val_int();
|
||||
longlong value1= b->val_int();
|
||||
return !a->null_value && !b->null_value && value0 == value1 &&
|
||||
(value0 >= 0 || a->unsigned_flag == b->unsigned_flag);
|
||||
}
|
||||
|
||||
|
||||
bool Type_handler_real_result::Item_eq_value(THD *thd,
|
||||
const Type_cmp_attributes *attr,
|
||||
Item *a, Item *b) const
|
||||
{
|
||||
double value0= a->val_real();
|
||||
double value1= b->val_real();
|
||||
return !a->null_value && !b->null_value && value0 == value1;
|
||||
}
|
||||
|
||||
|
||||
bool Type_handler_time_common::Item_eq_value(THD *thd,
|
||||
const Type_cmp_attributes *attr,
|
||||
Item *a, Item *b) const
|
||||
{
|
||||
longlong value0= a->val_time_packed();
|
||||
longlong value1= b->val_time_packed();
|
||||
return !a->null_value && !b->null_value && value0 == value1;
|
||||
}
|
||||
|
||||
|
||||
bool Type_handler_temporal_with_date::Item_eq_value(THD *thd,
|
||||
const Type_cmp_attributes *attr,
|
||||
Item *a, Item *b) const
|
||||
{
|
||||
longlong value0= a->val_datetime_packed();
|
||||
longlong value1= b->val_datetime_packed();
|
||||
return !a->null_value && !b->null_value && value0 == value1;
|
||||
}
|
||||
|
||||
|
||||
bool Type_handler_string_result::Item_eq_value(THD *thd,
|
||||
const Type_cmp_attributes *attr,
|
||||
Item *a, Item *b) const
|
||||
{
|
||||
String *va, *vb;
|
||||
StringBuffer<128> cmp_value1, cmp_value2;
|
||||
return (va= a->val_str(&cmp_value1)) &&
|
||||
(vb= b->val_str(&cmp_value2)) &&
|
||||
va->eq(vb, attr->compare_collation());
|
||||
}
|
||||
|
||||
|
||||
bool Type_handler_decimal_result::Item_eq_value(THD *thd,
|
||||
const Type_cmp_attributes *attr,
|
||||
Item *a, Item *b) const
|
||||
{
|
||||
my_decimal *va, *vb;
|
||||
my_decimal cmp_value1, cmp_value2;
|
||||
return (va= a->val_decimal(&cmp_value1)) &&
|
||||
(vb= b->val_decimal(&cmp_value2)) &&
|
||||
!my_decimal_cmp(va, vb);
|
||||
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
|
|
@ -836,6 +836,14 @@ public:
|
|||
};
|
||||
|
||||
|
||||
class Type_cmp_attributes
|
||||
{
|
||||
public:
|
||||
virtual ~Type_cmp_attributes() { }
|
||||
virtual CHARSET_INFO *compare_collation() const= 0;
|
||||
};
|
||||
|
||||
|
||||
class Type_cast_attributes
|
||||
{
|
||||
CHARSET_INFO *m_charset;
|
||||
|
@ -1400,6 +1408,8 @@ public:
|
|||
{
|
||||
return false;
|
||||
}
|
||||
virtual bool Item_eq_value(THD *thd, const Type_cmp_attributes *attr,
|
||||
Item *a, Item *b) const= 0;
|
||||
virtual bool Item_hybrid_func_fix_attributes(THD *thd,
|
||||
const char *name,
|
||||
Type_handler_hybrid_field_type *,
|
||||
|
@ -1623,6 +1633,8 @@ public:
|
|||
DBUG_ASSERT(0);
|
||||
return 0;
|
||||
}
|
||||
bool Item_eq_value(THD *thd, const Type_cmp_attributes *attr,
|
||||
Item *a, Item *b) const;
|
||||
uint Item_decimal_precision(const Item *item) const
|
||||
{
|
||||
DBUG_ASSERT(0);
|
||||
|
@ -1878,6 +1890,8 @@ public:
|
|||
SORT_FIELD_ATTR *attr) const;
|
||||
bool Item_const_eq(const Item_const *a, const Item_const *b,
|
||||
bool binary_cmp) const;
|
||||
bool Item_eq_value(THD *thd, const Type_cmp_attributes *attr,
|
||||
Item *a, Item *b) const;
|
||||
uint Item_decimal_precision(const Item *item) const;
|
||||
bool Item_save_in_value(Item *item, st_value *value) const;
|
||||
bool Item_param_set_from_value(THD *thd,
|
||||
|
@ -1957,6 +1971,8 @@ public:
|
|||
const Type_cast_attributes &attr) const;
|
||||
bool Item_const_eq(const Item_const *a, const Item_const *b,
|
||||
bool binary_cmp) const;
|
||||
bool Item_eq_value(THD *thd, const Type_cmp_attributes *attr,
|
||||
Item *a, Item *b) const;
|
||||
uint Item_decimal_precision(const Item *item) const;
|
||||
bool Item_save_in_value(Item *item, st_value *value) const;
|
||||
void Item_param_set_param_func(Item_param *param,
|
||||
|
@ -2161,6 +2177,8 @@ public:
|
|||
SORT_FIELD_ATTR *attr) const;
|
||||
bool Item_const_eq(const Item_const *a, const Item_const *b,
|
||||
bool binary_cmp) const;
|
||||
bool Item_eq_value(THD *thd, const Type_cmp_attributes *attr,
|
||||
Item *a, Item *b) const;
|
||||
uint Item_decimal_precision(const Item *item) const;
|
||||
bool Item_save_in_value(Item *item, st_value *value) const;
|
||||
bool Item_param_set_from_value(THD *thd,
|
||||
|
@ -2282,7 +2300,6 @@ public:
|
|||
bool Item_func_min_max_get_date(Item_func_min_max*,
|
||||
MYSQL_TIME *, ulonglong fuzzydate) const;
|
||||
bool Item_func_between_fix_length_and_dec(Item_func_between *func) const;
|
||||
longlong Item_func_between_val_int(Item_func_between *func) const;
|
||||
bool Item_func_in_fix_comparator_compatible_types(THD *thd,
|
||||
Item_func_in *) const;
|
||||
bool Item_func_round_fix_length_and_dec(Item_func_round *) const;
|
||||
|
@ -2328,6 +2345,8 @@ public:
|
|||
uint32 max_display_length(const Item *item) const;
|
||||
bool Item_const_eq(const Item_const *a, const Item_const *b,
|
||||
bool binary_cmp) const;
|
||||
bool Item_eq_value(THD *thd, const Type_cmp_attributes *attr,
|
||||
Item *a, Item *b) const;
|
||||
uint Item_time_precision(Item *item) const
|
||||
{
|
||||
return Item_temporal_precision(item, true);
|
||||
|
@ -2847,6 +2866,8 @@ public:
|
|||
}
|
||||
Item *create_typecast_item(THD *thd, Item *item,
|
||||
const Type_cast_attributes &attr) const;
|
||||
bool Item_eq_value(THD *thd, const Type_cmp_attributes *attr,
|
||||
Item *a, Item *b) const;
|
||||
uint Item_decimal_scale(const Item *item) const
|
||||
{
|
||||
return Item_decimal_scale_with_seconds(item);
|
||||
|
@ -2885,6 +2906,7 @@ public:
|
|||
ulonglong fuzzydate) const;
|
||||
bool Item_func_min_max_get_date(Item_func_min_max*,
|
||||
MYSQL_TIME *, ulonglong fuzzydate) const;
|
||||
longlong Item_func_between_val_int(Item_func_between *func) const;
|
||||
Item *make_const_item_for_comparison(THD *, Item *src, const Item *cmp) const;
|
||||
bool set_comparator_func(Arg_comparator *cmp) const;
|
||||
cmp_item *make_cmp_item(THD *thd, CHARSET_INFO *cs) const;
|
||||
|
@ -2952,6 +2974,8 @@ class Type_handler_temporal_with_date: public Type_handler_temporal_result
|
|||
{
|
||||
public:
|
||||
virtual ~Type_handler_temporal_with_date() {}
|
||||
bool Item_eq_value(THD *thd, const Type_cmp_attributes *attr,
|
||||
Item *a, Item *b) const;
|
||||
bool Item_save_in_value(Item *item, st_value *value) const;
|
||||
bool Item_send(Item *item, Protocol *protocol, st_value *buf) const
|
||||
{
|
||||
|
@ -2962,6 +2986,7 @@ public:
|
|||
bool set_comparator_func(Arg_comparator *cmp) const;
|
||||
cmp_item *make_cmp_item(THD *thd, CHARSET_INFO *cs) const;
|
||||
in_vector *make_in_vector(THD *, const Item_func_in *, uint nargs) const;
|
||||
longlong Item_func_between_val_int(Item_func_between *func) const;
|
||||
};
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue