1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-29 05:21:33 +03: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:
Alexander Barkov
2018-06-09 13:38:22 +04:00
parent 9043dd7a2d
commit d60fdb5814
7 changed files with 265 additions and 112 deletions

View File

@ -486,3 +486,44 @@ DROP TABLE t1;
# #
# End of 10.2 tests # 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
#

View File

@ -254,3 +254,30 @@ DROP TABLE t1;
--echo # --echo #
--echo # End of 10.2 tests --echo # End of 10.2 tests
--echo # --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 #

View File

@ -1676,12 +1676,6 @@ public:
return get_date_result(&ltime, fuzzydate) ? 0 : pack_time(&ltime); return get_date_result(&ltime, fuzzydate) ? 0 : pack_time(&ltime);
} }
// 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); bool get_seconds(ulonglong *sec, ulong *sec_part);
virtual bool get_date_result(MYSQL_TIME *ltime, ulonglong fuzzydate) virtual bool get_date_result(MYSQL_TIME *ltime, ulonglong fuzzydate)
{ return get_date(ltime,fuzzydate); } { return get_date(ltime,fuzzydate); }

View File

@ -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_datetime_packed(), a, b;
longlong value= args[0]->val_temporal_packed(f_type), a, b;
if ((null_value= args[0]->null_value)) if ((null_value= args[0]->null_value))
return 0; return 0;
a= args[1]->val_temporal_packed(f_type); a= args[1]->val_datetime_packed();
b= args[2]->val_temporal_packed(f_type); b= args[2]->val_datetime_packed();
if (!args[1]->null_value && !args[2]->null_value) return val_int_cmp_int_finalize(value, a, b);
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) longlong Item_func_between::val_int_cmp_time()
null_value= value <= b; // not null if false range. {
else longlong value= args[0]->val_time_packed(), a, b;
null_value= value >= a; if ((null_value= args[0]->null_value))
return (longlong) (!null_value && negated); 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 */ return 0; /* purecov: inspected */
a= args[1]->val_int(); a= args[1]->val_int();
b= args[2]->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) if (!args[1]->null_value && !args[2]->null_value)
return (longlong) ((value >= a && value <= b) != negated); return (longlong) ((value >= a && value <= b) != negated);
if (args[1]->null_value && args[2]->null_value) if (args[1]->null_value && args[2]->null_value)
null_value= true; null_value= true;
else if (args[1]->null_value) else if (args[1]->null_value)
{
null_value= value <= b; // not null if false range. null_value= value <= b; // not null if false range.
}
else else
{
null_value= value >= a; null_value= value >= a;
}
return (longlong) (!null_value && negated); return (longlong) (!null_value && negated);
} }
@ -3653,9 +3659,18 @@ void in_time::set(uint pos,Item *item)
buff->unsigned_flag= 1L; 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) if (item->null_value)
return 0; return 0;
tmp.unsigned_flag= 1L; 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) int cmp_item_datetime::cmp_not_null(const Value *val)
{ {
DBUG_ASSERT(!val->is_null()); DBUG_ASSERT(!val->is_null());
@ -6262,19 +6269,7 @@ void Item_equal::add_const(THD *thd, Item *c)
equal_items.push_front(c, thd->mem_root); equal_items.push_front(c, thd->mem_root);
return; 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: Suppose we have an expression (with a string type field) like this:
WHERE field=const1 AND field=const2 ... WHERE field=const1 AND field=const2 ...
@ -6318,20 +6313,9 @@ void Item_equal::add_const(THD *thd, Item *c)
SELECT * FROM t1 WHERE a='const' AND a=NULL; SELECT * FROM t1 WHERE a='const' AND a=NULL;
SELECT * FROM t1 WHERE a='const' AND a=(SELECT MAX(a) FROM t2) 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)) || cond_false= !Item_equal::compare_type_handler()->Item_eq_value(thd, this, c,
!str1->eq(str2, compare_collation()); get_const());
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();
}
}
if (with_const && equal_items.elements == 1) if (with_const && equal_items.elements == 1)
cond_true= TRUE; cond_true= TRUE;
if (cond_false || cond_true) if (cond_false || cond_true)

View File

@ -152,7 +152,8 @@ public:
class SEL_ARG; class SEL_ARG;
struct KEY_PART; struct KEY_PART;
class Item_bool_func :public Item_int_func class Item_bool_func :public Item_int_func,
public Type_cmp_attributes
{ {
protected: protected:
/* /*
@ -217,7 +218,7 @@ public:
Item_bool_func(THD *thd, Item_bool_func *item) :Item_int_func(thd, item) {} 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 *type_handler() const { return &type_handler_bool; }
const Type_handler *fixed_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; } void fix_length_and_dec() { decimals=0; max_length=1; }
uint decimal_precision() const { return 1; } uint decimal_precision() const { return 1; }
bool need_parentheses_in_default() { return true; } bool need_parentheses_in_default() { return true; }
@ -891,6 +892,7 @@ class Item_func_between :public Item_func_opt_neg
protected: protected:
SEL_TREE *get_func_mm_tree(RANGE_OPT_PARAM *param, SEL_TREE *get_func_mm_tree(RANGE_OPT_PARAM *param,
Field *field, Item *value); Field *field, Item *value);
bool val_int_cmp_int_finalize(longlong value, longlong a, longlong b);
public: public:
String value0,value1,value2; String value0,value1,value2;
Item_func_between(THD *thd, Item *a, Item *b, Item *c): 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); } { return get_item_copy<Item_func_between>(thd, this); }
longlong val_int_cmp_string(); 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_int();
longlong val_int_cmp_real(); longlong val_int_cmp_real();
longlong val_int_cmp_decimal(); longlong val_int_cmp_decimal();
@ -1404,8 +1407,6 @@ public:
*/ */
class in_temporal :public in_longlong class in_temporal :public in_longlong
{ {
protected:
uchar *get_value_internal(Item *item, enum_field_types f_type);
public: public:
/* Cache for the left item. */ /* Cache for the left item. */
@ -1418,8 +1419,6 @@ public:
Item_datetime *dt= static_cast<Item_datetime*>(item); Item_datetime *dt= static_cast<Item_datetime*>(item);
dt->set(val->val, type_handler()->mysql_timestamp_type()); 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); friend int cmp_longlong(void *cmp_arg, packed_longlong *a,packed_longlong *b);
}; };
@ -1431,6 +1430,7 @@ public:
:in_temporal(thd, elements) :in_temporal(thd, elements)
{} {}
void set(uint pos,Item *item); void set(uint pos,Item *item);
uchar *get_value(Item *item);
const Type_handler *type_handler() const { return &type_handler_datetime2; } const Type_handler *type_handler() const { return &type_handler_datetime2; }
}; };
@ -1442,6 +1442,7 @@ public:
:in_temporal(thd, elements) :in_temporal(thd, elements)
{} {}
void set(uint pos,Item *item); void set(uint pos,Item *item);
uchar *get_value(Item *item);
const Type_handler *type_handler() const { return &type_handler_time2; } const Type_handler *type_handler() const { return &type_handler_time2; }
}; };
@ -1616,7 +1617,6 @@ class cmp_item_temporal: public cmp_item_scalar
{ {
protected: protected:
longlong value; longlong value;
void store_value_internal(Item *item, enum_field_types type);
public: public:
cmp_item_temporal() {} cmp_item_temporal() {}
int compare(cmp_item *ci); int compare(cmp_item *ci);
@ -1631,7 +1631,8 @@ public:
{ } { }
void store_value(Item *item) 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_not_null(const Value *val);
int cmp(Item *arg); int cmp(Item *arg);
@ -1647,7 +1648,8 @@ public:
{ } { }
void store_value(Item *item) 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_not_null(const Value *val);
int cmp(Item *arg); int cmp(Item *arg);
@ -3081,7 +3083,6 @@ class Item_equal: public Item_bool_func
const Type_handler *m_compare_handler; const Type_handler *m_compare_handler;
CHARSET_INFO *m_compare_collation; CHARSET_INFO *m_compare_collation;
String cmp_value1, cmp_value2;
public: public:
COND_EQUAL *upper_levels; /* multiple equalities of upper and levels */ COND_EQUAL *upper_levels; /* multiple equalities of upper and levels */

View File

@ -3739,10 +3739,16 @@ longlong Type_handler_string_result::
return func->val_int_cmp_string(); 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 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:: 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);
}
/***************************************************************************/ /***************************************************************************/

View File

@ -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 class Type_cast_attributes
{ {
CHARSET_INFO *m_charset; CHARSET_INFO *m_charset;
@ -1400,6 +1408,8 @@ public:
{ {
return false; 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, virtual bool Item_hybrid_func_fix_attributes(THD *thd,
const char *name, const char *name,
Type_handler_hybrid_field_type *, Type_handler_hybrid_field_type *,
@ -1623,6 +1633,8 @@ public:
DBUG_ASSERT(0); DBUG_ASSERT(0);
return 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 uint Item_decimal_precision(const Item *item) const
{ {
DBUG_ASSERT(0); DBUG_ASSERT(0);
@ -1878,6 +1890,8 @@ public:
SORT_FIELD_ATTR *attr) const; SORT_FIELD_ATTR *attr) const;
bool Item_const_eq(const Item_const *a, const Item_const *b, bool Item_const_eq(const Item_const *a, const Item_const *b,
bool binary_cmp) const; 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; uint Item_decimal_precision(const Item *item) const;
bool Item_save_in_value(Item *item, st_value *value) const; bool Item_save_in_value(Item *item, st_value *value) const;
bool Item_param_set_from_value(THD *thd, bool Item_param_set_from_value(THD *thd,
@ -1957,6 +1971,8 @@ public:
const Type_cast_attributes &attr) const; const Type_cast_attributes &attr) const;
bool Item_const_eq(const Item_const *a, const Item_const *b, bool Item_const_eq(const Item_const *a, const Item_const *b,
bool binary_cmp) const; 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; uint Item_decimal_precision(const Item *item) const;
bool Item_save_in_value(Item *item, st_value *value) const; bool Item_save_in_value(Item *item, st_value *value) const;
void Item_param_set_param_func(Item_param *param, void Item_param_set_param_func(Item_param *param,
@ -2161,6 +2177,8 @@ public:
SORT_FIELD_ATTR *attr) const; SORT_FIELD_ATTR *attr) const;
bool Item_const_eq(const Item_const *a, const Item_const *b, bool Item_const_eq(const Item_const *a, const Item_const *b,
bool binary_cmp) const; 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; uint Item_decimal_precision(const Item *item) const;
bool Item_save_in_value(Item *item, st_value *value) const; bool Item_save_in_value(Item *item, st_value *value) const;
bool Item_param_set_from_value(THD *thd, bool Item_param_set_from_value(THD *thd,
@ -2282,7 +2300,6 @@ public:
bool Item_func_min_max_get_date(Item_func_min_max*, bool Item_func_min_max_get_date(Item_func_min_max*,
MYSQL_TIME *, ulonglong fuzzydate) const; MYSQL_TIME *, ulonglong fuzzydate) const;
bool Item_func_between_fix_length_and_dec(Item_func_between *func) 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, bool Item_func_in_fix_comparator_compatible_types(THD *thd,
Item_func_in *) const; Item_func_in *) const;
bool Item_func_round_fix_length_and_dec(Item_func_round *) 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; uint32 max_display_length(const Item *item) const;
bool Item_const_eq(const Item_const *a, const Item_const *b, bool Item_const_eq(const Item_const *a, const Item_const *b,
bool binary_cmp) const; 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 uint Item_time_precision(Item *item) const
{ {
return Item_temporal_precision(item, true); return Item_temporal_precision(item, true);
@ -2847,6 +2866,8 @@ public:
} }
Item *create_typecast_item(THD *thd, Item *item, Item *create_typecast_item(THD *thd, Item *item,
const Type_cast_attributes &attr) const; 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 uint Item_decimal_scale(const Item *item) const
{ {
return Item_decimal_scale_with_seconds(item); return Item_decimal_scale_with_seconds(item);
@ -2885,6 +2906,7 @@ public:
ulonglong fuzzydate) const; ulonglong fuzzydate) const;
bool Item_func_min_max_get_date(Item_func_min_max*, bool Item_func_min_max_get_date(Item_func_min_max*,
MYSQL_TIME *, ulonglong fuzzydate) const; 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; Item *make_const_item_for_comparison(THD *, Item *src, const Item *cmp) const;
bool set_comparator_func(Arg_comparator *cmp) const; bool set_comparator_func(Arg_comparator *cmp) const;
cmp_item *make_cmp_item(THD *thd, CHARSET_INFO *cs) 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: public:
virtual ~Type_handler_temporal_with_date() {} 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_save_in_value(Item *item, st_value *value) const;
bool Item_send(Item *item, Protocol *protocol, st_value *buf) 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; bool set_comparator_func(Arg_comparator *cmp) const;
cmp_item *make_cmp_item(THD *thd, CHARSET_INFO *cs) 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; in_vector *make_in_vector(THD *, const Item_func_in *, uint nargs) const;
longlong Item_func_between_val_int(Item_func_between *func) const;
}; };