@@ -383,33 +383,65 @@ class Item_real_func :public Item_func
383383};
384384
385385
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
388427{
389428public:
390429 Item_func_hybrid_field_type (THD *thd):
391- Item_func (thd)
430+ Item_hybrid_func (thd)
392431 { collation.set_numeric (); }
393432 Item_func_hybrid_field_type (THD *thd, Item *a):
394- Item_func (thd, a)
433+ Item_hybrid_func (thd, a)
395434 { collation.set_numeric (); }
396435 Item_func_hybrid_field_type (THD *thd, Item *a, Item *b):
397- Item_func (thd, a, b)
436+ Item_hybrid_func (thd, a, b)
398437 { collation.set_numeric (); }
399438 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)
401440 { collation.set_numeric (); }
402441 Item_func_hybrid_field_type (THD *thd, List<Item> &list):
403- Item_func (thd, list)
442+ Item_hybrid_func (thd, list)
404443 { collation.set_numeric (); }
405444
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-
413445 double val_real ();
414446 longlong val_int ();
415447 my_decimal *val_decimal (my_decimal *);
@@ -1007,28 +1039,21 @@ class Item_func_units :public Item_real_func
10071039 than strings.
10081040 Perhaps this should be changed eventually (see MDEV-5893).
10091041*/
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
10121043{
10131044 String tmp_value;
10141045 int cmp_sign;
10151046 THD *thd;
10161047public:
10171048 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)
10191050 {}
10201051 double val_real ();
10211052 longlong val_int ();
10221053 String *val_str (String *);
10231054 my_decimal *val_decimal (my_decimal *);
10241055 bool get_date (MYSQL_TIME *res, ulonglong fuzzy_date);
10251056 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 (); }
10321057};
10331058
10341059class Item_func_min :public Item_func_min_max
@@ -1628,29 +1653,19 @@ class user_var_entry;
16281653/* *
16291654 A class to set and get user variables
16301655*/
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
16331657{
16341658protected:
16351659 user_var_entry *m_var_entry;
16361660public:
16371661 LEX_STRING name; // keep it public
16381662 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) { }
16401664 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) { }
16421666 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) { }
16541669 bool check_vcol_func_processor (uchar *int_arg) { return true ; }
16551670};
16561671
0 commit comments