@@ -383,33 +383,65 @@ class Item_real_func :public Item_func
383
383
};
384
384
385
385
386
- class Item_func_hybrid_field_type : public Item_func ,
387
- public Type_handler_hybrid_field_type
386
+ /* *
387
+ Functions whose returned field type is determined at fix_fields() time.
388
+ */
389
+ class Item_hybrid_func : public Item_func ,
390
+ public Type_handler_hybrid_field_type
391
+ {
392
+ public:
393
+ Item_hybrid_func (THD *thd): Item_func(thd) { }
394
+ Item_hybrid_func (THD *thd, Item *a): Item_func(thd, a) { }
395
+ Item_hybrid_func (THD *thd, Item *a, Item *b): Item_func(thd, a, b) { }
396
+ Item_hybrid_func (THD *thd, Item *a, Item *b, Item *c):
397
+ Item_func (thd, a, b, c) { }
398
+ Item_hybrid_func (THD *thd, List<Item> &list): Item_func(thd, list) { }
399
+ Item_hybrid_func (THD *thd, Item_hybrid_func *item)
400
+ :Item_func(thd, item), Type_handler_hybrid_field_type(item) { }
401
+ enum_field_types field_type () const
402
+ { return Type_handler_hybrid_field_type::field_type (); }
403
+ enum Item_result result_type () const
404
+ { return Type_handler_hybrid_field_type::result_type (); }
405
+ enum Item_result cmp_type () const
406
+ { return Type_handler_hybrid_field_type::cmp_type (); }
407
+ };
408
+
409
+
410
+ /* *
411
+ Functions that at fix_fields() time determine the returned field type,
412
+ trying to preserve the exact data type of the arguments.
413
+
414
+ The descendants have to implement "native" value methods,
415
+ i.e. str_op(), date_op(), int_op(), real_op(), decimal_op().
416
+ fix_fields() chooses which of the above value methods will be
417
+ used during execution time, according to the returned field type.
418
+
419
+ For example, if fix_fields() determines that the returned value type
420
+ is MYSQL_TYPE_LONG, then:
421
+ - int_op() is chosen as the execution time native method.
422
+ - val_int() returns the result of int_op() as is.
423
+ - all other methods, i.e. val_real(), val_decimal(), val_str(), get_date(),
424
+ call int_op() first, then convert the result to the requested data type.
425
+ */
426
+ class Item_func_hybrid_field_type : public Item_hybrid_func
388
427
{
389
428
public:
390
429
Item_func_hybrid_field_type (THD *thd):
391
- Item_func (thd)
430
+ Item_hybrid_func (thd)
392
431
{ collation.set_numeric (); }
393
432
Item_func_hybrid_field_type (THD *thd, Item *a):
394
- Item_func (thd, a)
433
+ Item_hybrid_func (thd, a)
395
434
{ collation.set_numeric (); }
396
435
Item_func_hybrid_field_type (THD *thd, Item *a, Item *b):
397
- Item_func (thd, a, b)
436
+ Item_hybrid_func (thd, a, b)
398
437
{ collation.set_numeric (); }
399
438
Item_func_hybrid_field_type (THD *thd, Item *a, Item *b, Item *c):
400
- Item_func (thd, a, b, c)
439
+ Item_hybrid_func (thd, a, b, c)
401
440
{ collation.set_numeric (); }
402
441
Item_func_hybrid_field_type (THD *thd, List<Item> &list):
403
- Item_func (thd, list)
442
+ Item_hybrid_func (thd, list)
404
443
{ collation.set_numeric (); }
405
444
406
- enum_field_types field_type () const
407
- { return Type_handler_hybrid_field_type::field_type (); }
408
- enum Item_result result_type () const
409
- { return Type_handler_hybrid_field_type::result_type (); }
410
- enum Item_result cmp_type () const
411
- { return Type_handler_hybrid_field_type::cmp_type (); }
412
-
413
445
double val_real ();
414
446
longlong val_int ();
415
447
my_decimal *val_decimal (my_decimal *);
@@ -1007,28 +1039,21 @@ class Item_func_units :public Item_real_func
1007
1039
than strings.
1008
1040
Perhaps this should be changed eventually (see MDEV-5893).
1009
1041
*/
1010
- class Item_func_min_max :public Item_func ,
1011
- public Type_handler_hybrid_field_type
1042
+ class Item_func_min_max :public Item_hybrid_func
1012
1043
{
1013
1044
String tmp_value;
1014
1045
int cmp_sign;
1015
1046
THD *thd;
1016
1047
public:
1017
1048
Item_func_min_max (THD *thd, List<Item> &list, int cmp_sign_arg):
1018
- Item_func (thd, list), cmp_sign(cmp_sign_arg)
1049
+ Item_hybrid_func (thd, list), cmp_sign(cmp_sign_arg)
1019
1050
{}
1020
1051
double val_real ();
1021
1052
longlong val_int ();
1022
1053
String *val_str (String *);
1023
1054
my_decimal *val_decimal (my_decimal *);
1024
1055
bool get_date (MYSQL_TIME *res, ulonglong fuzzy_date);
1025
1056
void fix_length_and_dec ();
1026
- enum Item_result cmp_type () const
1027
- { return Type_handler_hybrid_field_type::cmp_type (); }
1028
- enum Item_result result_type () const
1029
- { return Type_handler_hybrid_field_type::result_type (); }
1030
- enum_field_types field_type () const
1031
- { return Type_handler_hybrid_field_type::field_type (); }
1032
1057
};
1033
1058
1034
1059
class Item_func_min :public Item_func_min_max
@@ -1628,29 +1653,19 @@ class user_var_entry;
1628
1653
/* *
1629
1654
A class to set and get user variables
1630
1655
*/
1631
- class Item_func_user_var :public Item_func ,
1632
- public Type_handler_hybrid_field_type
1656
+ class Item_func_user_var :public Item_hybrid_func
1633
1657
{
1634
1658
protected:
1635
1659
user_var_entry *m_var_entry;
1636
1660
public:
1637
1661
LEX_STRING name; // keep it public
1638
1662
Item_func_user_var (THD *thd, LEX_STRING a)
1639
- :Item_func (thd), m_var_entry(NULL ), name(a) { }
1663
+ :Item_hybrid_func (thd), m_var_entry(NULL ), name(a) { }
1640
1664
Item_func_user_var (THD *thd, LEX_STRING a, Item *b)
1641
- :Item_func (thd, b), m_var_entry(NULL ), name(a) { }
1665
+ :Item_hybrid_func (thd, b), m_var_entry(NULL ), name(a) { }
1642
1666
Item_func_user_var (THD *thd, Item_func_user_var *item)
1643
- :Item_func(thd, item),
1644
- m_var_entry (item->m_var_entry), name(item->name)
1645
- {
1646
- set_handler_by_result_type (item->result_type ());
1647
- }
1648
- enum Item_result cmp_type () const
1649
- { return Type_handler_hybrid_field_type::cmp_type (); }
1650
- enum Item_result result_type () const
1651
- { return Type_handler_hybrid_field_type::result_type (); }
1652
- enum_field_types field_type () const
1653
- { return Type_handler_hybrid_field_type::field_type (); }
1667
+ :Item_hybrid_func(thd, item),
1668
+ m_var_entry (item->m_var_entry), name(item->name) { }
1654
1669
bool check_vcol_func_processor (uchar *int_arg) { return true ; }
1655
1670
};
1656
1671
0 commit comments