1 #ifndef SQL_TYPE_H_INCLUDED
2 #define SQL_TYPE_H_INCLUDED
3 /*
4    Copyright (c) 2015  MariaDB Foundation.
5 
6  This program is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; version 2 of the License.
9 
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with this program; if not, write to the Free Software
17  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335  USA */
18 
19 #ifdef USE_PRAGMA_INTERFACE
20 #pragma interface			/* gcc class implementation */
21 #endif
22 
23 
24 #include "mysqld.h"
25 #include "sql_array.h"
26 #include "sql_const.h"
27 #include "sql_time.h"
28 #include "sql_type_real.h"
29 
30 class Field;
31 class Column_definition;
32 class Item;
33 class Item_param;
34 class Item_cache;
35 class Item_func_or_sum;
36 class Item_sum_hybrid;
37 class Item_sum_sum;
38 class Item_sum_avg;
39 class Item_sum_variance;
40 class Item_func_hex;
41 class Item_hybrid_func;
42 class Item_func_min_max;
43 class Item_func_hybrid_field_type;
44 class Item_bool_func2;
45 class Item_func_between;
46 class Item_func_in;
47 class Item_func_round;
48 class Item_func_int_val;
49 class Item_func_abs;
50 class Item_func_neg;
51 class Item_func_signed;
52 class Item_func_unsigned;
53 class Item_double_typecast;
54 class Item_float_typecast;
55 class Item_decimal_typecast;
56 class Item_char_typecast;
57 class Item_time_typecast;
58 class Item_date_typecast;
59 class Item_datetime_typecast;
60 class Item_func_plus;
61 class Item_func_minus;
62 class Item_func_mul;
63 class Item_func_div;
64 class Item_func_mod;
65 class Item_type_holder;
66 class cmp_item;
67 class in_vector;
68 class Type_handler_hybrid_field_type;
69 class Sort_param;
70 class Arg_comparator;
71 class Spvar_definition;
72 struct st_value;
73 class Protocol;
74 class handler;
75 struct Schema_specification_st;
76 struct TABLE;
77 struct SORT_FIELD_ATTR;
78 class Vers_history_point;
79 class Schema;
80 
81 
82 /**
83   Class Time is designed to store valid TIME values.
84 
85   1. Valid value:
86     a. MYSQL_TIMESTAMP_TIME - a valid TIME within the supported TIME range
87     b. MYSQL_TIMESTAMP_NONE - an undefined value
88 
89   2. Invalid value (internally only):
90     a. MYSQL_TIMESTAMP_TIME outside of the supported TIME range
91     a. MYSQL_TIMESTAMP_{DATE|DATETIME|ERROR}
92 
93   Temporarily Time is allowed to have an invalid value, but only internally,
94   during initialization time. All constructors and modification methods must
95   leave the Time value as described above (see "Valid values").
96 
97   Time derives from MYSQL_TIME privately to make sure it is accessed
98   externally only in the valid state.
99 */
100 class Time: private MYSQL_TIME
101 {
102 public:
103   enum datetime_to_time_mode_t
104   {
105     DATETIME_TO_TIME_YYYYMMDD_000000DD_MIX_TO_HOURS,
106     DATETIME_TO_TIME_YYYYMMDD_TRUNCATE
107   };
108   class Options
109   {
110     sql_mode_t              m_get_date_flags;
111     datetime_to_time_mode_t m_datetime_to_time_mode;
112   public:
Options()113     Options()
114      :m_get_date_flags(flags_for_get_date()),
115       m_datetime_to_time_mode(DATETIME_TO_TIME_YYYYMMDD_000000DD_MIX_TO_HOURS)
116     { }
Options(sql_mode_t flags)117     Options(sql_mode_t flags)
118      :m_get_date_flags(flags),
119       m_datetime_to_time_mode(DATETIME_TO_TIME_YYYYMMDD_000000DD_MIX_TO_HOURS)
120     { }
Options(sql_mode_t flags,datetime_to_time_mode_t dtmode)121     Options(sql_mode_t flags, datetime_to_time_mode_t dtmode)
122      :m_get_date_flags(flags),
123       m_datetime_to_time_mode(dtmode)
124     { }
get_date_flags()125     sql_mode_t get_date_flags() const
126     { return m_get_date_flags; }
datetime_to_time_mode()127     datetime_to_time_mode_t datetime_to_time_mode() const
128     { return m_datetime_to_time_mode; }
129   };
130   /*
131     CAST(AS TIME) historically does not mix days to hours.
132     This is different comparing to how implicit conversion
133     in Field::store_time_dec() works (e.g. on INSERT).
134   */
135   class Options_for_cast: public Options
136   {
137   public:
Options_for_cast()138     Options_for_cast()
139      :Options(flags_for_get_date(), DATETIME_TO_TIME_YYYYMMDD_TRUNCATE)
140     { }
141   };
142 private:
is_valid_value_slow()143   bool is_valid_value_slow() const
144   {
145     return time_type == MYSQL_TIMESTAMP_NONE || is_valid_time_slow();
146   }
is_valid_time_slow()147   bool is_valid_time_slow() const
148   {
149     return time_type == MYSQL_TIMESTAMP_TIME &&
150            year == 0 && month == 0 && day == 0 &&
151            minute <= TIME_MAX_MINUTE &&
152            second <= TIME_MAX_SECOND &&
153            second_part <= TIME_MAX_SECOND_PART;
154   }
155 
156   /*
157     Convert a valid DATE or DATETIME to TIME.
158     Before this call, "this" must be a valid DATE or DATETIME value,
159     e.g. returned from Item::get_date().
160     After this call, "this" is a valid TIME value.
161   */
valid_datetime_to_valid_time(const Options opt)162   void valid_datetime_to_valid_time(const Options opt)
163   {
164     DBUG_ASSERT(time_type == MYSQL_TIMESTAMP_DATE ||
165                 time_type == MYSQL_TIMESTAMP_DATETIME);
166     /*
167       Make sure that day and hour are valid, so the result hour value
168       after mixing days to hours does not go out of the valid TIME range.
169     */
170     DBUG_ASSERT(day < 32);
171     DBUG_ASSERT(hour < 24);
172     if (year == 0 && month == 0 &&
173         opt.datetime_to_time_mode() ==
174         DATETIME_TO_TIME_YYYYMMDD_000000DD_MIX_TO_HOURS)
175     {
176       /*
177         The maximum hour value after mixing days will be 31*24+23=767,
178         which is within the supported TIME range.
179         Thus no adjust_time_range_or_invalidate() is needed here.
180       */
181       hour+= day * 24;
182     }
183     year= month= day= 0;
184     time_type= MYSQL_TIMESTAMP_TIME;
185     DBUG_ASSERT(is_valid_time_slow());
186   }
187   /**
188     Convert valid DATE/DATETIME to valid TIME if needed.
189     This method is called after Item::get_date(),
190     which can return only valid TIME/DATE/DATETIME values.
191     Before this call, "this" is:
192     - either a valid TIME/DATE/DATETIME value
193       (within the supported range for the corresponding type),
194     - or MYSQL_TIMESTAMP_NONE
195     After this call, "this" is:
196     - either a valid TIME (within the supported TIME range),
197     - or MYSQL_TIMESTAMP_NONE
198   */
valid_MYSQL_TIME_to_valid_value(const Options opt)199   void valid_MYSQL_TIME_to_valid_value(const Options opt)
200   {
201     switch (time_type) {
202     case MYSQL_TIMESTAMP_DATE:
203     case MYSQL_TIMESTAMP_DATETIME:
204       valid_datetime_to_valid_time(opt);
205       break;
206     case MYSQL_TIMESTAMP_NONE:
207       break;
208     case MYSQL_TIMESTAMP_ERROR:
209       set_zero_time(this, MYSQL_TIMESTAMP_TIME);
210       break;
211     case MYSQL_TIMESTAMP_TIME:
212       DBUG_ASSERT(is_valid_time_slow());
213       break;
214     }
215   }
216   void make_from_item(class Item *item, const Options opt);
217 public:
Time()218   Time() { time_type= MYSQL_TIMESTAMP_NONE; }
Time(Item * item)219   Time(Item *item) { make_from_item(item, Options()); }
Time(Item * item,const Options opt)220   Time(Item *item, const Options opt) { make_from_item(item, opt); }
flags_for_get_date()221   static sql_mode_t flags_for_get_date()
222   { return TIME_TIME_ONLY | TIME_INVALID_DATES; }
comparison_flags_for_get_date()223   static sql_mode_t comparison_flags_for_get_date()
224   { return TIME_TIME_ONLY | TIME_INVALID_DATES | TIME_FUZZY_DATES; }
is_valid_time()225   bool is_valid_time() const
226   {
227     DBUG_ASSERT(is_valid_value_slow());
228     return time_type == MYSQL_TIMESTAMP_TIME;
229   }
get_mysql_time()230   const MYSQL_TIME *get_mysql_time() const
231   {
232     DBUG_ASSERT(is_valid_time_slow());
233     return this;
234   }
copy_to_mysql_time(MYSQL_TIME * ltime)235   bool copy_to_mysql_time(MYSQL_TIME *ltime) const
236   {
237     if (time_type == MYSQL_TIMESTAMP_NONE)
238     {
239       ltime->time_type= MYSQL_TIMESTAMP_NONE;
240       return true;
241     }
242     DBUG_ASSERT(is_valid_time_slow());
243     *ltime= *this;
244     return false;
245   }
cmp(const Time * other)246   int cmp(const Time *other) const
247   {
248     DBUG_ASSERT(is_valid_time_slow());
249     DBUG_ASSERT(other->is_valid_time_slow());
250     longlong p0= pack_time(this);
251     longlong p1= pack_time(other);
252     if (p0 < p1)
253       return -1;
254     if (p0 > p1)
255       return 1;
256     return 0;
257   }
to_seconds_abs()258   longlong to_seconds_abs() const
259   {
260     DBUG_ASSERT(is_valid_time_slow());
261     return hour * 3600L + minute * 60 + second;
262   }
to_seconds()263   longlong to_seconds() const
264   {
265     return neg ? -to_seconds_abs() : to_seconds_abs();
266   }
267 };
268 
269 
270 /**
271   Class Temporal_with_date is designed to store valid DATE or DATETIME values.
272   See also class Time.
273 
274   1. Valid value:
275     a. MYSQL_TIMESTAMP_{DATE|DATETIME} - a valid DATE or DATETIME value
276     b. MYSQL_TIMESTAMP_NONE            - an undefined value
277 
278   2. Invalid value (internally only):
279     a. MYSQL_TIMESTAMP_{DATE|DATETIME} - a DATE or DATETIME value, but with
280                                          MYSQL_TIME members outside of the
281                                          valid/supported range
282     b. MYSQL_TIMESTAMP_TIME            - a TIME value
283     c. MYSQL_TIMESTAMP_ERROR           - error
284 
285   Temporarily is allowed to have an invalid value, but only internally,
286   during initialization time. All constructors and modification methods must
287   leave the value as described above (see "Valid value").
288 
289   Derives from MYSQL_TIME using "protected" inheritance to make sure
290   it is accessed externally only in the valid state.
291 */
292 
293 class Temporal_with_date: protected MYSQL_TIME
294 {
295 protected:
296   void make_from_item(THD *thd, Item *item, sql_mode_t flags);
297 
daynr()298   ulong daynr() const
299   {
300     return (ulong) ::calc_daynr((uint) year, (uint) month, (uint) day);
301   }
weekday(bool sunday_first_day_of_week)302   int weekday(bool sunday_first_day_of_week) const
303   {
304     return ::calc_weekday(daynr(), sunday_first_day_of_week);
305   }
Temporal_with_date(THD * thd,Item * item,sql_mode_t flags)306   Temporal_with_date(THD *thd, Item *item, sql_mode_t flags)
307   {
308     make_from_item(thd, item, flags);
309   }
310 };
311 
312 
313 /**
314   Class Date is designed to store valid DATE values.
315   All constructors and modification methods leave instances
316   of this class in one of the following valid states:
317     a. MYSQL_TIMESTAMP_DATE - a DATE with all MYSQL_TIME members properly set
318     b. MYSQL_TIMESTAMP_NONE - an undefined value.
319   Other MYSQL_TIMESTAMP_XXX are not possible.
320   MYSQL_TIMESTAMP_DATE with MYSQL_TIME members improperly set is not possible.
321 */
322 class Date: public Temporal_with_date
323 {
is_valid_value_slow()324   bool is_valid_value_slow() const
325   {
326     return time_type == MYSQL_TIMESTAMP_NONE || is_valid_date_slow();
327   }
is_valid_date_slow()328   bool is_valid_date_slow() const
329   {
330     DBUG_ASSERT(time_type == MYSQL_TIMESTAMP_DATE);
331     return !check_datetime_range(this);
332   }
333 public:
Date(THD * thd,Item * item,sql_mode_t flags)334   Date(THD *thd, Item *item, sql_mode_t flags)
335    :Temporal_with_date(thd, item, flags)
336   {
337     if (time_type == MYSQL_TIMESTAMP_DATETIME)
338       datetime_to_date(this);
339     DBUG_ASSERT(is_valid_value_slow());
340   }
Date(const Temporal_with_date * d)341   Date(const Temporal_with_date *d)
342    :Temporal_with_date(*d)
343   {
344     datetime_to_date(this);
345     DBUG_ASSERT(is_valid_date_slow());
346   }
is_valid_date()347   bool is_valid_date() const
348   {
349     DBUG_ASSERT(is_valid_value_slow());
350     return time_type == MYSQL_TIMESTAMP_DATE;
351   }
get_mysql_time()352   const MYSQL_TIME *get_mysql_time() const
353   {
354     DBUG_ASSERT(is_valid_date_slow());
355     return this;
356   }
357 };
358 
359 
360 /**
361   Class Datetime is designed to store valid DATETIME values.
362   All constructors and modification methods leave instances
363   of this class in one of the following valid states:
364     a. MYSQL_TIMESTAMP_DATETIME - a DATETIME with all members properly set
365     b. MYSQL_TIMESTAMP_NONE     - an undefined value.
366   Other MYSQL_TIMESTAMP_XXX are not possible.
367   MYSQL_TIMESTAMP_DATETIME with MYSQL_TIME members
368   improperly set is not possible.
369 */
370 class Datetime: public Temporal_with_date
371 {
is_valid_value_slow()372   bool is_valid_value_slow() const
373   {
374     return time_type == MYSQL_TIMESTAMP_NONE || is_valid_datetime_slow();
375   }
is_valid_datetime_slow()376   bool is_valid_datetime_slow() const
377   {
378     DBUG_ASSERT(time_type == MYSQL_TIMESTAMP_DATETIME);
379     return !check_datetime_range(this);
380   }
381 public:
Datetime(THD * thd,Item * item,sql_mode_t flags)382   Datetime(THD *thd, Item *item, sql_mode_t flags)
383    :Temporal_with_date(thd, item, flags)
384   {
385     if (time_type == MYSQL_TIMESTAMP_DATE)
386       date_to_datetime(this);
387     DBUG_ASSERT(is_valid_value_slow());
388   }
is_valid_datetime()389   bool is_valid_datetime() const
390   {
391     /*
392       Here we quickly check for the type only.
393       If the type is valid, the rest of value must also be valid.
394     */
395     DBUG_ASSERT(is_valid_value_slow());
396     return time_type == MYSQL_TIMESTAMP_DATETIME;
397   }
hhmmssff_is_zero()398   bool hhmmssff_is_zero() const
399   {
400     DBUG_ASSERT(is_valid_datetime_slow());
401     return hour == 0 && minute == 0 && second == 0 && second_part == 0;
402   }
weekday(bool sunday_first_day_of_week)403   int weekday(bool sunday_first_day_of_week) const
404   {
405     DBUG_ASSERT(is_valid_datetime_slow());
406     return Temporal_with_date::weekday(sunday_first_day_of_week);
407   }
get_mysql_time()408   const MYSQL_TIME *get_mysql_time() const
409   {
410     DBUG_ASSERT(is_valid_datetime_slow());
411     return this;
412   }
copy_to_mysql_time(MYSQL_TIME * ltime)413   bool copy_to_mysql_time(MYSQL_TIME *ltime) const
414   {
415     if (time_type == MYSQL_TIMESTAMP_NONE)
416     {
417       ltime->time_type= MYSQL_TIMESTAMP_NONE;
418       return true;
419     }
420     DBUG_ASSERT(is_valid_datetime_slow());
421     *ltime= *this;
422     return false;
423   }
424   /**
425     Copy without data loss, with an optional DATETIME to DATE conversion.
426     If the value of the "type" argument is MYSQL_TIMESTAMP_DATE,
427     then "this" must be a datetime with a zero hhmmssff part.
428   */
copy_to_mysql_time(MYSQL_TIME * ltime,timestamp_type type)429   bool copy_to_mysql_time(MYSQL_TIME *ltime, timestamp_type type)
430   {
431     DBUG_ASSERT(type == MYSQL_TIMESTAMP_DATE ||
432                 type == MYSQL_TIMESTAMP_DATETIME);
433     if (copy_to_mysql_time(ltime))
434       return true;
435     DBUG_ASSERT(type != MYSQL_TIMESTAMP_DATE || hhmmssff_is_zero());
436     ltime->time_type= type;
437     return false;
438   }
439 };
440 
441 /*
442   Flags for collation aggregation modes, used in TDCollation::agg():
443 
444   MY_COLL_ALLOW_SUPERSET_CONV  - allow conversion to a superset
445   MY_COLL_ALLOW_COERCIBLE_CONV - allow conversion of a coercible value
446                                  (i.e. constant).
447   MY_COLL_ALLOW_CONV           - allow any kind of conversion
448                                  (combination of the above two)
449   MY_COLL_ALLOW_NUMERIC_CONV   - if all items were numbers, convert to
450                                  @@character_set_connection
451   MY_COLL_DISALLOW_NONE        - don't allow return DERIVATION_NONE
452                                  (e.g. when aggregating for comparison)
453   MY_COLL_CMP_CONV             - combination of MY_COLL_ALLOW_CONV
454                                  and MY_COLL_DISALLOW_NONE
455 */
456 
457 #define MY_COLL_ALLOW_SUPERSET_CONV   1
458 #define MY_COLL_ALLOW_COERCIBLE_CONV  2
459 #define MY_COLL_DISALLOW_NONE         4
460 #define MY_COLL_ALLOW_NUMERIC_CONV    8
461 
462 #define MY_COLL_ALLOW_CONV (MY_COLL_ALLOW_SUPERSET_CONV | MY_COLL_ALLOW_COERCIBLE_CONV)
463 #define MY_COLL_CMP_CONV   (MY_COLL_ALLOW_CONV | MY_COLL_DISALLOW_NONE)
464 
465 
466 #define my_charset_numeric      my_charset_latin1
467 #define MY_REPERTOIRE_NUMERIC   MY_REPERTOIRE_ASCII
468 
469 
470 enum Derivation
471 {
472   DERIVATION_IGNORABLE= 6,
473   DERIVATION_NUMERIC= 5,
474   DERIVATION_COERCIBLE= 4,
475   DERIVATION_SYSCONST= 3,
476   DERIVATION_IMPLICIT= 2,
477   DERIVATION_NONE= 1,
478   DERIVATION_EXPLICIT= 0
479 };
480 
481 
482 /**
483    "Declared Type Collation"
484    A combination of collation and its derivation.
485 */
486 
487 class DTCollation {
488 public:
489   CHARSET_INFO     *collation;
490   enum Derivation derivation;
491   uint repertoire;
492 
set_repertoire_from_charset(CHARSET_INFO * cs)493   void set_repertoire_from_charset(CHARSET_INFO *cs)
494   {
495     repertoire= cs->state & MY_CS_PUREASCII ?
496                 MY_REPERTOIRE_ASCII : MY_REPERTOIRE_UNICODE30;
497   }
DTCollation()498   DTCollation()
499   {
500     collation= &my_charset_bin;
501     derivation= DERIVATION_NONE;
502     repertoire= MY_REPERTOIRE_UNICODE30;
503   }
DTCollation(CHARSET_INFO * collation_arg)504   DTCollation(CHARSET_INFO *collation_arg)
505   {
506     /*
507       This constructor version is used in combination with Field constructors,
508       to pass "CHARSET_INFO" instead of the full DTCollation.
509       Therefore, derivation is set to DERIVATION_IMPLICIT, which is the
510       proper derivation for table fields.
511       We should eventually remove all code pieces that pass "CHARSET_INFO"
512       (e.g. in storage engine sources) and fix to pass the full DTCollation
513       instead. Then, this constructor can be removed.
514     */
515     collation= collation_arg;
516     derivation= DERIVATION_IMPLICIT;
517     repertoire= my_charset_repertoire(collation_arg);
518   }
DTCollation(CHARSET_INFO * collation_arg,Derivation derivation_arg)519   DTCollation(CHARSET_INFO *collation_arg, Derivation derivation_arg)
520   {
521     collation= collation_arg;
522     derivation= derivation_arg;
523     set_repertoire_from_charset(collation_arg);
524   }
DTCollation(CHARSET_INFO * collation_arg,Derivation derivation_arg,uint repertoire_arg)525   DTCollation(CHARSET_INFO *collation_arg,
526               Derivation derivation_arg,
527               uint repertoire_arg)
528    :collation(collation_arg),
529     derivation(derivation_arg),
530     repertoire(repertoire_arg)
531   { }
set(const DTCollation & dt)532   void set(const DTCollation &dt)
533   {
534     collation= dt.collation;
535     derivation= dt.derivation;
536     repertoire= dt.repertoire;
537   }
set(CHARSET_INFO * collation_arg,Derivation derivation_arg)538   void set(CHARSET_INFO *collation_arg, Derivation derivation_arg)
539   {
540     collation= collation_arg;
541     derivation= derivation_arg;
542     set_repertoire_from_charset(collation_arg);
543   }
set(CHARSET_INFO * collation_arg,Derivation derivation_arg,uint repertoire_arg)544   void set(CHARSET_INFO *collation_arg,
545            Derivation derivation_arg,
546            uint repertoire_arg)
547   {
548     collation= collation_arg;
549     derivation= derivation_arg;
550     repertoire= repertoire_arg;
551   }
set_numeric()552   void set_numeric()
553   {
554     collation= &my_charset_numeric;
555     derivation= DERIVATION_NUMERIC;
556     repertoire= MY_REPERTOIRE_NUMERIC;
557   }
set(CHARSET_INFO * collation_arg)558   void set(CHARSET_INFO *collation_arg)
559   {
560     collation= collation_arg;
561     set_repertoire_from_charset(collation_arg);
562   }
set(Derivation derivation_arg)563   void set(Derivation derivation_arg)
564   { derivation= derivation_arg; }
565   bool aggregate(const DTCollation &dt, uint flags= 0);
566   bool set(DTCollation &dt1, DTCollation &dt2, uint flags= 0)
567   { set(dt1); return aggregate(dt2, flags); }
derivation_name()568   const char *derivation_name() const
569   {
570     switch(derivation)
571     {
572       case DERIVATION_NUMERIC:   return "NUMERIC";
573       case DERIVATION_IGNORABLE: return "IGNORABLE";
574       case DERIVATION_COERCIBLE: return "COERCIBLE";
575       case DERIVATION_IMPLICIT:  return "IMPLICIT";
576       case DERIVATION_SYSCONST:  return "SYSCONST";
577       case DERIVATION_EXPLICIT:  return "EXPLICIT";
578       case DERIVATION_NONE:      return "NONE";
579       default: return "UNKNOWN";
580     }
581   }
sortcmp(const String * s,const String * t)582   int sortcmp(const String *s, const String *t) const
583   {
584     return collation->coll->strnncollsp(collation,
585                                         (uchar *) s->ptr(), s->length(),
586                                         (uchar *) t->ptr(), t->length());
587   }
588 };
589 
590 
591 static inline uint32
char_to_byte_length_safe(size_t char_length_arg,uint32 mbmaxlen_arg)592 char_to_byte_length_safe(size_t char_length_arg, uint32 mbmaxlen_arg)
593 {
594   ulonglong tmp= ((ulonglong) char_length_arg) * mbmaxlen_arg;
595   return tmp > UINT_MAX32 ? (uint32) UINT_MAX32 : static_cast<uint32>(tmp);
596 }
597 
598 /**
599   A class to store type attributes for the standard data types.
600   Does not include attributes for the extended data types
601   such as ENUM, SET, GEOMETRY.
602 */
603 class Type_std_attributes
604 {
605 public:
606   DTCollation collation;
607   uint decimals;
608   /*
609     The maximum value length in characters multiplied by collation->mbmaxlen.
610     Almost always it's the maximum value length in bytes.
611   */
612   uint32 max_length;
613   bool unsigned_flag;
Type_std_attributes()614   Type_std_attributes()
615    :collation(&my_charset_bin, DERIVATION_COERCIBLE),
616     decimals(0), max_length(0), unsigned_flag(false)
617   { }
Type_std_attributes(const Type_std_attributes * other)618   Type_std_attributes(const Type_std_attributes *other)
619    :collation(other->collation),
620     decimals(other->decimals),
621     max_length(other->max_length),
622     unsigned_flag(other->unsigned_flag)
623   { }
Type_std_attributes(uint32 max_length_arg,uint decimals_arg,bool unsigned_flag_arg,const DTCollation & dtc)624   Type_std_attributes(uint32 max_length_arg, uint decimals_arg,
625                       bool unsigned_flag_arg, const DTCollation &dtc)
626     :collation(dtc),
627      decimals(decimals_arg),
628      max_length(max_length_arg),
629      unsigned_flag(unsigned_flag_arg)
630   { }
set(const Type_std_attributes * other)631   void set(const Type_std_attributes *other)
632   {
633     *this= *other;
634   }
set(const Type_std_attributes & other)635   void set(const Type_std_attributes &other)
636   {
637     *this= other;
638   }
max_char_length()639   uint32 max_char_length() const
640   { return max_length / collation.collation->mbmaxlen; }
fix_length_and_charset(uint32 max_char_length_arg,CHARSET_INFO * cs)641   void fix_length_and_charset(uint32 max_char_length_arg, CHARSET_INFO *cs)
642   {
643     max_length= char_to_byte_length_safe(max_char_length_arg, cs->mbmaxlen);
644     collation.collation= cs;
645   }
fix_char_length(uint32 max_char_length_arg)646   void fix_char_length(uint32 max_char_length_arg)
647   {
648     max_length= char_to_byte_length_safe(max_char_length_arg,
649                                          collation.collation->mbmaxlen);
650   }
fix_char_length_temporal_not_fixed_dec(uint int_part_length,uint dec)651   void fix_char_length_temporal_not_fixed_dec(uint int_part_length, uint dec)
652   {
653     uint char_length= int_part_length;
654     if ((decimals= dec))
655     {
656       if (decimals == NOT_FIXED_DEC)
657         char_length+= TIME_SECOND_PART_DIGITS + 1;
658       else
659       {
660         set_if_smaller(decimals, TIME_SECOND_PART_DIGITS);
661         char_length+= decimals + 1;
662       }
663     }
664     fix_char_length(char_length);
665   }
fix_attributes_temporal_not_fixed_dec(uint int_part_length,uint dec)666   void fix_attributes_temporal_not_fixed_dec(uint int_part_length, uint dec)
667   {
668     collation.set_numeric();
669     unsigned_flag= 0;
670     fix_char_length_temporal_not_fixed_dec(int_part_length, dec);
671   }
fix_attributes_time_not_fixed_dec(uint dec)672   void fix_attributes_time_not_fixed_dec(uint dec)
673   {
674     fix_attributes_temporal_not_fixed_dec(MIN_TIME_WIDTH, dec);
675   }
fix_attributes_datetime_not_fixed_dec(uint dec)676   void fix_attributes_datetime_not_fixed_dec(uint dec)
677   {
678     fix_attributes_temporal_not_fixed_dec(MAX_DATETIME_WIDTH, dec);
679   }
fix_attributes_temporal(uint int_part_length,uint dec)680   void fix_attributes_temporal(uint int_part_length, uint dec)
681   {
682     collation.set_numeric();
683     unsigned_flag= 0;
684     decimals= MY_MIN(dec, TIME_SECOND_PART_DIGITS);
685     max_length= decimals + int_part_length + (dec ? 1 : 0);
686   }
fix_attributes_date()687   void fix_attributes_date()
688   {
689     fix_attributes_temporal(MAX_DATE_WIDTH, 0);
690   }
fix_attributes_time(uint dec)691   void fix_attributes_time(uint dec)
692   {
693     fix_attributes_temporal(MIN_TIME_WIDTH, dec);
694   }
fix_attributes_datetime(uint dec)695   void fix_attributes_datetime(uint dec)
696   {
697     fix_attributes_temporal(MAX_DATETIME_WIDTH, dec);
698   }
699 
700   void count_only_length(Item **item, uint nitems);
701   void count_octet_length(Item **item, uint nitems);
702   void count_real_length(Item **item, uint nitems);
703   void count_decimal_length(Item **item, uint nitems);
704   bool count_string_length(const char *func_name, Item **item, uint nitems);
705   uint count_max_decimals(Item **item, uint nitems);
706 
aggregate_attributes_int(Item ** items,uint nitems)707   void aggregate_attributes_int(Item **items, uint nitems)
708   {
709     collation.set_numeric();
710     count_only_length(items, nitems);
711     decimals= 0;
712   }
aggregate_attributes_real(Item ** items,uint nitems)713   void aggregate_attributes_real(Item **items, uint nitems)
714   {
715     collation.set_numeric();
716     count_real_length(items, nitems);
717   }
aggregate_attributes_decimal(Item ** items,uint nitems)718   void aggregate_attributes_decimal(Item **items, uint nitems)
719   {
720     collation.set_numeric();
721     count_decimal_length(items, nitems);
722   }
aggregate_attributes_string(const char * func_name,Item ** item,uint nitems)723   bool aggregate_attributes_string(const char *func_name,
724                                    Item **item, uint nitems)
725   {
726     return count_string_length(func_name, item, nitems);
727   }
aggregate_attributes_temporal(uint int_part_length,Item ** item,uint nitems)728   void aggregate_attributes_temporal(uint int_part_length,
729                                      Item **item, uint nitems)
730   {
731     fix_attributes_temporal(int_part_length, count_max_decimals(item, nitems));
732   }
733 
734   bool agg_item_collations(DTCollation &c, const char *name,
735                            Item **items, uint nitems,
736                            uint flags, int item_sep);
737   bool agg_item_set_converter(const DTCollation &coll, const char *fname,
738                               Item **args, uint nargs,
739                               uint flags, int item_sep);
740 
741   /*
742     Collect arguments' character sets together.
743     We allow to apply automatic character set conversion in some cases.
744     The conditions when conversion is possible are:
745     - arguments A and B have different charsets
746     - A wins according to coercibility rules
747       (i.e. a column is stronger than a string constant,
748        an explicit COLLATE clause is stronger than a column)
749     - character set of A is either superset for character set of B,
750       or B is a string constant which can be converted into the
751       character set of A without data loss.
752 
753     If all of the above is true, then it's possible to convert
754     B into the character set of A, and then compare according
755     to the collation of A.
756 
757     For functions with more than two arguments:
758 
759       collect(A,B,C) ::= collect(collect(A,B),C)
760 
761     Since this function calls THD::change_item_tree() on the passed Item **
762     pointers, it is necessary to pass the original Item **'s, not copies.
763     Otherwise their values will not be properly restored (see BUG#20769).
764     If the items are not consecutive (eg. args[2] and args[5]), use the
765     item_sep argument, ie.
766 
767       agg_item_charsets(coll, fname, &args[2], 2, flags, 3)
768   */
agg_arg_charsets(DTCollation & c,const char * func_name,Item ** items,uint nitems,uint flags,int item_sep)769   bool agg_arg_charsets(DTCollation &c, const char *func_name,
770                         Item **items, uint nitems,
771                         uint flags, int item_sep)
772   {
773     if (agg_item_collations(c, func_name, items, nitems, flags, item_sep))
774       return true;
775     return agg_item_set_converter(c, func_name, items, nitems, flags, item_sep);
776   }
777   /*
778     Aggregate arguments for string result, e.g: CONCAT(a,b)
779     - convert to @@character_set_connection if all arguments are numbers
780     - allow DERIVATION_NONE
781   */
agg_arg_charsets_for_string_result(DTCollation & c,const char * func_name,Item ** items,uint nitems,int item_sep)782   bool agg_arg_charsets_for_string_result(DTCollation &c, const char *func_name,
783                                           Item **items, uint nitems,
784                                           int item_sep)
785   {
786     uint flags= MY_COLL_ALLOW_SUPERSET_CONV |
787                 MY_COLL_ALLOW_COERCIBLE_CONV |
788                 MY_COLL_ALLOW_NUMERIC_CONV;
789     return agg_arg_charsets(c, func_name, items, nitems, flags, item_sep);
790   }
791   /*
792     Aggregate arguments for string result, when some comparison
793     is involved internally, e.g: REPLACE(a,b,c)
794     - convert to @@character_set_connection if all arguments are numbers
795     - disallow DERIVATION_NONE
796   */
agg_arg_charsets_for_string_result_with_comparison(DTCollation & c,const char * func_name,Item ** items,uint nitems,int item_sep)797   bool agg_arg_charsets_for_string_result_with_comparison(DTCollation &c,
798                                                           const char *func_name,
799                                                           Item **items,
800                                                           uint nitems,
801                                                           int item_sep)
802   {
803     uint flags= MY_COLL_ALLOW_SUPERSET_CONV |
804                 MY_COLL_ALLOW_COERCIBLE_CONV |
805                 MY_COLL_ALLOW_NUMERIC_CONV |
806                 MY_COLL_DISALLOW_NONE;
807     return agg_arg_charsets(c, func_name, items, nitems, flags, item_sep);
808   }
809 
810   /*
811     Aggregate arguments for comparison, e.g: a=b, a LIKE b, a RLIKE b
812     - don't convert to @@character_set_connection if all arguments are numbers
813     - don't allow DERIVATION_NONE
814   */
agg_arg_charsets_for_comparison(DTCollation & c,const char * func_name,Item ** items,uint nitems,int item_sep)815   bool agg_arg_charsets_for_comparison(DTCollation &c,
816                                        const char *func_name,
817                                        Item **items, uint nitems,
818                                        int item_sep)
819   {
820     uint flags= MY_COLL_ALLOW_SUPERSET_CONV |
821                 MY_COLL_ALLOW_COERCIBLE_CONV |
822                 MY_COLL_DISALLOW_NONE;
823     return agg_arg_charsets(c, func_name, items, nitems, flags, item_sep);
824   }
825 
826 };
827 
828 
829 class Type_all_attributes: public Type_std_attributes
830 {
831 public:
Type_all_attributes()832   Type_all_attributes()
833    :Type_std_attributes()
834   { }
Type_all_attributes(const Type_all_attributes * other)835   Type_all_attributes(const Type_all_attributes *other)
836    :Type_std_attributes(other)
837   { }
~Type_all_attributes()838   virtual ~Type_all_attributes() {}
839   virtual void set_maybe_null(bool maybe_null_arg)= 0;
840   // Returns total number of decimal digits
841   virtual uint decimal_precision() const= 0;
842   /*
843     Field::geometry_type is not visible here.
844     Let's use an "uint" wrapper for now. Later when we move Field_geom
845     into a plugin, this method will be replaced to some generic
846     datatype indepented method.
847   */
848   virtual uint uint_geometry_type() const= 0;
849   virtual void set_geometry_type(uint type)= 0;
850   virtual TYPELIB *get_typelib() const= 0;
851   virtual void set_typelib(TYPELIB *typelib)= 0;
852 };
853 
854 
855 class Type_cast_attributes
856 {
857   CHARSET_INFO *m_charset;
858   ulonglong m_length;
859   ulonglong m_decimals;
860   bool m_length_specified;
861   bool m_decimals_specified;
862 public:
Type_cast_attributes(const char * c_len,const char * c_dec,CHARSET_INFO * cs)863   Type_cast_attributes(const char *c_len, const char *c_dec, CHARSET_INFO *cs)
864     :m_charset(cs), m_length(0), m_decimals(0),
865      m_length_specified(false), m_decimals_specified(false)
866   {
867     set_length_and_dec(c_len, c_dec);
868   }
Type_cast_attributes(CHARSET_INFO * cs)869   Type_cast_attributes(CHARSET_INFO *cs)
870     :m_charset(cs), m_length(0), m_decimals(0),
871      m_length_specified(false), m_decimals_specified(false)
872   { }
set_length_and_dec(const char * c_len,const char * c_dec)873   void set_length_and_dec(const char *c_len, const char *c_dec)
874   {
875     int error;
876     /*
877       We don't have to check for error here as sql_yacc.yy has guaranteed
878       that the values are in range of ulonglong
879     */
880     if ((m_length_specified= (c_len != NULL)))
881       m_length= (ulonglong) my_strtoll10(c_len, NULL, &error);
882     if ((m_decimals_specified= (c_dec != NULL)))
883       m_decimals= (ulonglong) my_strtoll10(c_dec, NULL, &error);
884   }
charset()885   CHARSET_INFO *charset() const { return m_charset; }
length_specified()886   bool length_specified() const { return m_length_specified; }
decimals_specified()887   bool decimals_specified() const { return m_decimals_specified; }
length()888   ulonglong length() const { return m_length; }
decimals()889   ulonglong decimals() const { return m_decimals; }
890 };
891 
892 
893 class Name: private LEX_CSTRING
894 {
895 public:
Name(const char * str_arg,uint length_arg)896   Name(const char *str_arg, uint length_arg)
897   {
898     DBUG_ASSERT(length_arg < UINT_MAX32);
899     LEX_CSTRING::str= str_arg;
900     LEX_CSTRING::length= length_arg;
901   }
ptr()902   const char *ptr() const { return LEX_CSTRING::str; }
length()903   uint length() const { return (uint) LEX_CSTRING::length; }
904 };
905 
906 
907 class Record_addr
908 {
909 public:
910   uchar *ptr;      // Position to field in record
911   /**
912      Byte where the @c NULL bit is stored inside a record. If this Field is a
913      @c NOT @c NULL field, this member is @c NULL.
914   */
915   uchar *null_ptr;
916   uchar null_bit;  // Bit used to test null bit
Record_addr(uchar * ptr_arg,uchar * null_ptr_arg,uchar null_bit_arg)917   Record_addr(uchar *ptr_arg,
918               uchar *null_ptr_arg,
919               uchar null_bit_arg)
920    :ptr(ptr_arg),
921     null_ptr(null_ptr_arg),
922     null_bit(null_bit_arg)
923   { }
Record_addr(bool maybe_null)924   Record_addr(bool maybe_null)
925    :ptr(NULL),
926     null_ptr(maybe_null ? (uchar*) "" : 0),
927     null_bit(0)
928   { }
929 };
930 
931 
932 class Information_schema_numeric_attributes
933 {
934   enum enum_attr
935   {
936     ATTR_NONE= 0,
937     ATTR_PRECISION= 1,
938     ATTR_SCALE= 2,
939     ATTR_PRECISION_AND_SCALE= (ATTR_PRECISION|ATTR_SCALE)
940   };
941   uint m_precision;
942   uint m_scale;
943   enum_attr m_available_attributes;
944 public:
Information_schema_numeric_attributes()945   Information_schema_numeric_attributes()
946    :m_precision(0), m_scale(0),
947     m_available_attributes(ATTR_NONE)
948   { }
Information_schema_numeric_attributes(uint precision)949   Information_schema_numeric_attributes(uint precision)
950    :m_precision(precision), m_scale(0),
951     m_available_attributes(ATTR_PRECISION)
952   { }
Information_schema_numeric_attributes(uint precision,uint scale)953   Information_schema_numeric_attributes(uint precision, uint scale)
954    :m_precision(precision), m_scale(scale),
955     m_available_attributes(ATTR_PRECISION_AND_SCALE)
956   { }
has_precision()957   bool has_precision() const { return m_available_attributes & ATTR_PRECISION; }
has_scale()958   bool has_scale() const { return m_available_attributes & ATTR_SCALE; }
precision()959   uint precision() const
960   {
961     DBUG_ASSERT(has_precision());
962     return (uint) m_precision;
963   }
scale()964   uint scale() const
965   {
966     DBUG_ASSERT(has_scale());
967     return (uint) m_scale;
968   }
969 };
970 
971 
972 class Information_schema_character_attributes
973 {
974   uint32 m_octet_length;
975   uint32 m_char_length;
976   bool m_is_set;
977 public:
Information_schema_character_attributes()978   Information_schema_character_attributes()
979    :m_octet_length(0), m_char_length(0), m_is_set(false)
980   { }
Information_schema_character_attributes(uint32 octet_length,uint32 char_length)981   Information_schema_character_attributes(uint32 octet_length,
982                                           uint32 char_length)
983    :m_octet_length(octet_length), m_char_length(char_length), m_is_set(true)
984   { }
has_octet_length()985   bool has_octet_length() const { return m_is_set; }
has_char_length()986   bool has_char_length() const { return m_is_set; }
octet_length()987   uint32 octet_length() const
988   {
989     DBUG_ASSERT(has_octet_length());
990     return m_octet_length;
991   }
char_length()992   uint char_length() const
993   {
994     DBUG_ASSERT(has_char_length());
995     return m_char_length;
996   }
997 };
998 
999 
1000 class Type_handler
1001 {
1002 protected:
1003   String *print_item_value_csstr(THD *thd, Item *item, String *str) const;
1004   String *print_item_value_temporal(THD *thd, Item *item, String *str,
1005                                      const Name &type_name, String *buf) const;
1006   void make_sort_key_longlong(uchar *to,
1007                               bool maybe_null, bool null_value,
1008                               bool unsigned_flag,
1009                               longlong value) const;
1010   bool
1011   Item_func_or_sum_illegal_param(const char *name) const;
1012   bool
1013   Item_func_or_sum_illegal_param(const Item_func_or_sum *) const;
1014   bool check_null(const Item *item, st_value *value) const;
1015   bool Item_send_str(Item *item, Protocol *protocol, st_value *buf) const;
1016   bool Item_send_tiny(Item *item, Protocol *protocol, st_value *buf) const;
1017   bool Item_send_short(Item *item, Protocol *protocol, st_value *buf) const;
1018   bool Item_send_long(Item *item, Protocol *protocol, st_value *buf) const;
1019   bool Item_send_longlong(Item *item, Protocol *protocol, st_value *buf) const;
1020   bool Item_send_float(Item *item, Protocol *protocol, st_value *buf) const;
1021   bool Item_send_double(Item *item, Protocol *protocol, st_value *buf) const;
1022   bool Item_send_time(Item *item, Protocol *protocol, st_value *buf) const;
1023   bool Item_send_date(Item *item, Protocol *protocol, st_value *buf) const;
1024   bool Item_send_datetime(Item *item, Protocol *protocol, st_value *buf) const;
1025   bool Column_definition_prepare_stage2_legacy(Column_definition *c,
1026                                                enum_field_types type)
1027                                                const;
1028   bool Column_definition_prepare_stage2_legacy_num(Column_definition *c,
1029                                                    enum_field_types type)
1030                                                    const;
1031   bool Column_definition_prepare_stage2_legacy_real(Column_definition *c,
1032                                                     enum_field_types type)
1033                                                     const;
1034 public:
1035   static const Type_handler *blob_type_handler(uint max_octet_length);
1036   static const Type_handler *string_type_handler(uint max_octet_length);
1037   static const Type_handler *bit_and_int_mixture_handler(uint max_char_len);
1038   static const Type_handler *type_handler_long_or_longlong(uint max_char_len);
1039   /**
1040     Return a string type handler for Item
1041     If too_big_for_varchar() returns a BLOB variant, according to length.
1042     If max_length > 0 create a VARCHAR(n)
1043     If max_length == 0 create a CHAR(0)
1044     @param item - the Item to get the handler to.
1045   */
1046   static const Type_handler *varstring_type_handler(const Item *item);
1047   static const Type_handler *blob_type_handler(const Item *item);
1048   static const Type_handler *get_handler_by_field_type(enum_field_types type);
1049   static const Type_handler *get_handler_by_real_type(enum_field_types type);
1050   static const Type_handler *get_handler_by_cmp_type(Item_result type);
get_handler_by_result_type(Item_result type)1051   static const Type_handler *get_handler_by_result_type(Item_result type)
1052   {
1053     /*
1054       As result_type() returns STRING_RESULT for temporal Items,
1055       type should never be equal to TIME_RESULT here.
1056     */
1057     DBUG_ASSERT(type != TIME_RESULT);
1058     return get_handler_by_cmp_type(type);
1059   }
1060   static const
1061   Type_handler *aggregate_for_result_traditional(const Type_handler *h1,
1062                                                  const Type_handler *h2);
1063   static const
1064   Type_handler *aggregate_for_num_op_traditional(const Type_handler *h1,
1065                                                  const Type_handler *h2);
1066 
1067   virtual Schema *schema() const;
1068   virtual const Name name() const= 0;
1069   virtual enum_field_types field_type() const= 0;
real_field_type()1070   virtual enum_field_types real_field_type() const { return field_type(); }
1071   virtual Item_result result_type() const= 0;
1072   virtual Item_result cmp_type() const= 0;
mysql_timestamp_type()1073   virtual enum_mysql_timestamp_type mysql_timestamp_type() const
1074   {
1075     return MYSQL_TIMESTAMP_ERROR;
1076   }
is_timestamp_type()1077   virtual bool is_timestamp_type() const
1078   {
1079     return false;
1080   }
1081   /**
1082     Check whether a field type can be partially indexed by a key.
1083     @param  type   field type
1084     @retval true   Type can have a prefixed key
1085     @retval false  Type can not have a prefixed key
1086   */
type_can_have_key_part()1087   virtual bool type_can_have_key_part() const
1088   {
1089     return false;
1090   }
type_can_have_auto_increment_attribute()1091   virtual bool type_can_have_auto_increment_attribute() const
1092   {
1093     return false;
1094   }
1095   /**
1096     Prepared statement long data:
1097     Check whether this parameter data type is compatible with long data.
1098     Used to detect whether a long data stream has been supplied to a
1099     incompatible data type.
1100   */
is_param_long_data_type()1101   virtual bool is_param_long_data_type() const { return false; }
1102   virtual const Type_handler *type_handler_for_comparison() const= 0;
type_handler_for_item_field()1103   virtual const Type_handler *type_handler_for_item_field() const
1104   {
1105     return this;
1106   }
type_handler_for_tmp_table(const Item *)1107   virtual const Type_handler *type_handler_for_tmp_table(const Item *) const
1108   {
1109     return this;
1110   }
type_handler_for_union(const Item *)1111   virtual const Type_handler *type_handler_for_union(const Item *) const
1112   {
1113     return this;
1114   }
cast_to_int_type_handler()1115   virtual const Type_handler *cast_to_int_type_handler() const
1116   {
1117     return this;
1118   }
1119   virtual CHARSET_INFO *charset_for_protocol(const Item *item) const;
1120   virtual const Type_handler*
type_handler_adjusted_to_max_octet_length(uint max_octet_length,CHARSET_INFO * cs)1121   type_handler_adjusted_to_max_octet_length(uint max_octet_length,
1122                                             CHARSET_INFO *cs) const
1123   { return this; }
adjust_spparam_type(Spvar_definition * def,Item * from)1124   virtual bool adjust_spparam_type(Spvar_definition *def, Item *from) const
1125   {
1126     return false;
1127   }
~Type_handler()1128   virtual ~Type_handler() {}
1129   /**
1130     Determines MariaDB traditional data types that always present
1131     in the server.
1132   */
is_traditional_type()1133   virtual bool is_traditional_type() const
1134   {
1135     return true;
1136   }
is_scalar_type()1137   virtual bool is_scalar_type() const { return true; }
can_return_int()1138   virtual bool can_return_int() const { return true; }
can_return_decimal()1139   virtual bool can_return_decimal() const { return true; }
can_return_real()1140   virtual bool can_return_real() const { return true; }
can_return_str()1141   virtual bool can_return_str() const { return true; }
can_return_text()1142   virtual bool can_return_text() const { return true; }
can_return_date()1143   virtual bool can_return_date() const { return true; }
can_return_time()1144   virtual bool can_return_time() const { return true; }
is_general_purpose_string_type()1145   virtual bool is_general_purpose_string_type() const { return false; }
1146   virtual uint Item_time_precision(Item *item) const;
1147   virtual uint Item_datetime_precision(Item *item) const;
1148   virtual uint Item_decimal_scale(const Item *item) const;
1149   virtual uint Item_decimal_precision(const Item *item) const= 0;
1150   /*
1151     Returns how many digits a divisor adds into a division result.
1152     See Item::divisor_precision_increment() in item.h for more comments.
1153   */
1154   virtual uint Item_divisor_precision_increment(const Item *) const;
1155   /**
1156     Makes a temporary table Field to handle numeric aggregate functions,
1157     e.g. SUM(DISTINCT expr), AVG(DISTINCT expr), etc.
1158   */
1159   virtual Field *make_num_distinct_aggregator_field(MEM_ROOT *,
1160                                                     const Item *) const;
1161   /**
1162     Makes a temporary table Field to handle RBR replication type conversion.
1163     @param TABLE    - The conversion table the field is going to be added to.
1164                       It's used to access to table->in_use->mem_root,
1165                       to create the new field on the table memory root,
1166                       as well as to increment statistics in table->share
1167                       (e.g. table->s->blob_count).
1168     @param metadata - Metadata from the binary log.
1169     @param target   - The field in the target table on the slave.
1170 
1171     Note, the data types of "target" and of "this" are not necessarily
1172     always the same, in general case it's possible that:
1173             this->field_type() != target->field_type()
1174     and/or
1175             this->real_type( ) != target->real_type()
1176 
1177     This method decodes metadata according to this->real_type()
1178     and creates a new field also according to this->real_type().
1179 
1180     In some cases it lurks into "target", to get some extra information, e.g.:
1181     - unsigned_flag for numeric fields
1182     - charset() for string fields
1183     - typelib and field_length for SET and ENUM
1184     - geom_type and srid for GEOMETRY
1185     This information is not available in the binary log, so
1186     we assume that these fields are the same on the master and on the slave.
1187   */
1188   virtual Field *make_conversion_table_field(TABLE *TABLE,
1189                                              uint metadata,
1190                                              const Field *target) const= 0;
1191   /*
1192     Performs the final data type validation for a UNION element,
1193     after the regular "aggregation for result" was done.
1194   */
union_element_finalize(Item_type_holder * item)1195   virtual bool union_element_finalize(Item_type_holder *item) const
1196   {
1197     return false;
1198   }
1199   virtual bool Column_definition_fix_attributes(Column_definition *c) const= 0;
1200   virtual bool Column_definition_prepare_stage1(THD *thd,
1201                                                 MEM_ROOT *mem_root,
1202                                                 Column_definition *c,
1203                                                 handler *file,
1204                                                 ulonglong table_flags) const;
1205   /*
1206     This method is called on queries like:
1207       CREATE TABLE t2 (a INT) AS SELECT a FROM t1;
1208     I.e. column "a" is queried from another table,
1209     but its data type is redefined.
1210     @param OUT def   - The column definition to be redefined
1211     @param IN  dup   - The column definition to take the data type from
1212                        (i.e. "a INT" in the above example).
1213     @param IN file   - Table owner handler. If it does not support certain
1214                        data types, some conversion can be applied.
1215                        I.g. true BIT to BIT-AS-CHAR.
1216     @param IN schema - the owner schema definition, e.g. for the default
1217                        character set and collation.
1218     @retval true     - on error
1219     @retval false    - on success
1220   */
1221   virtual bool Column_definition_redefine_stage1(Column_definition *def,
1222                                                  const Column_definition *dup,
1223                                                  const handler *file,
1224                                                  const Schema_specification_st *
1225                                                        schema)
1226                                                  const;
1227   virtual bool Column_definition_prepare_stage2(Column_definition *c,
1228                                                 handler *file,
1229                                                 ulonglong table_flags) const= 0;
1230   virtual Field *make_table_field(const LEX_CSTRING *name,
1231                                   const Record_addr &addr,
1232                                   const Type_all_attributes &attr,
1233                                   TABLE *table) const= 0;
1234   Field *make_and_init_table_field(const LEX_CSTRING *name,
1235                                    const Record_addr &addr,
1236                                    const Type_all_attributes &attr,
1237                                    TABLE *table) const;
1238   virtual void make_sort_key(uchar *to, Item *item,
1239                              const SORT_FIELD_ATTR *sort_field,
1240                              Sort_param *param) const= 0;
1241   virtual void sortlength(THD *thd,
1242                           const Type_std_attributes *item,
1243                           SORT_FIELD_ATTR *attr) const= 0;
1244 
1245   virtual uint32 max_display_length(const Item *item) const= 0;
1246   virtual uint32 calc_pack_length(uint32 length) const= 0;
1247   virtual bool Item_save_in_value(Item *item, st_value *value) const= 0;
Item_param_setup_conversion(THD * thd,Item_param *)1248   virtual void Item_param_setup_conversion(THD *thd, Item_param *) const {}
1249   virtual void Item_param_set_param_func(Item_param *param,
1250                                          uchar **pos, ulong len) const;
1251   virtual bool Item_param_set_from_value(THD *thd,
1252                                          Item_param *param,
1253                                          const Type_all_attributes *attr,
1254                                          const st_value *value) const= 0;
1255   virtual bool Item_send(Item *item, Protocol *p, st_value *buf) const= 0;
1256   virtual int Item_save_in_field(Item *item, Field *field,
1257                                  bool no_conversions) const= 0;
1258 
1259   /**
1260     Return a string representation of the Item value.
1261 
1262     @param thd     thread handle
1263     @param str     string buffer for representation of the value
1264 
1265     @note
1266       If the item has a string result type, the string is escaped
1267       according to its character set.
1268 
1269     @retval
1270       NULL      on error
1271     @retval
1272       non-NULL  a pointer to a a valid string on success
1273   */
1274   virtual String *print_item_value(THD *thd, Item *item, String *str) const= 0;
1275 
1276   /**
1277     Check if
1278       WHERE expr=value AND expr=const
1279     can be rewritten as:
1280       WHERE const=value AND expr=const
1281 
1282     "this" is the comparison handler that is used by "target".
1283 
1284     @param target       - the predicate expr=value,
1285                           whose "expr" argument will be replaced to "const".
1286     @param target_expr  - the target's "expr" which will be replaced to "const".
1287     @param target_value - the target's second argument, it will remain unchanged.
1288     @param source       - the equality predicate expr=const (or expr<=>const)
1289                           that can be used to rewrite the "target" part
1290                           (under certain conditions, see the code).
1291     @param source_expr  - the source's "expr". It should be exactly equal to
1292                           the target's "expr" to make condition rewrite possible.
1293     @param source_const - the source's "const" argument, it will be inserted
1294                           into "target" instead of "expr".
1295   */
1296   virtual bool
1297   can_change_cond_ref_to_const(Item_bool_func2 *target,
1298                                Item *target_expr, Item *target_value,
1299                                Item_bool_func2 *source,
1300                                Item *source_expr, Item *source_const) const= 0;
1301 
1302   /*
1303     @brief
1304       Check if an IN subquery allows materialization or not
1305     @param
1306       inner              expression on the inner side of the IN subquery
1307       outer              expression on the outer side of the IN subquery
1308       is_in_predicate    SET to true if IN subquery was converted from an
1309                          IN predicate or we are checking if materialization
1310                          strategy can be used for an IN predicate
1311   */
1312   virtual bool
1313   subquery_type_allows_materialization(const Item *inner,
1314                                        const Item *outer,
1315                                        bool is_in_predicate) const= 0;
1316   /**
1317     Make a simple constant replacement item for a constant "src",
1318     so the new item can futher be used for comparison with "cmp", e.g.:
1319       src = cmp   ->  replacement = cmp
1320 
1321     "this" is the type handler that is used to compare "src" and "cmp".
1322 
1323     @param thd - current thread, for mem_root
1324     @param src - The item that we want to replace. It's a const item,
1325                  but it can be complex enough to calculate on every row.
1326     @param cmp - The src's comparand.
1327     @retval    - a pointer to the created replacement Item
1328     @retval    - NULL, if could not create a replacement (e.g. on EOM).
1329                  NULL is also returned for ROWs, because instead of replacing
1330                  a Item_row to a new Item_row, Type_handler_row just replaces
1331                  its elements.
1332   */
1333   virtual Item *make_const_item_for_comparison(THD *thd,
1334                                                Item *src,
1335                                                const Item *cmp) const= 0;
1336   virtual Item_cache *Item_get_cache(THD *thd, const Item *item) const= 0;
create_typecast_item(THD * thd,Item * item,const Type_cast_attributes & attr)1337   virtual Item *create_typecast_item(THD *thd, Item *item,
1338                                      const Type_cast_attributes &attr) const
1339   {
1340     DBUG_ASSERT(0);
1341     return NULL;
1342   }
1343   virtual bool set_comparator_func(Arg_comparator *cmp) const= 0;
1344   virtual bool Item_hybrid_func_fix_attributes(THD *thd,
1345                                                const char *name,
1346                                                Type_handler_hybrid_field_type *,
1347                                                Type_all_attributes *atrr,
1348                                                Item **items,
1349                                                uint nitems) const= 0;
1350   virtual bool Item_func_min_max_fix_attributes(THD *thd,
1351                                                 Item_func_min_max *func,
1352                                                 Item **items,
1353                                                 uint nitems) const;
1354   virtual bool Item_sum_hybrid_fix_length_and_dec(Item_sum_hybrid *) const= 0;
1355   virtual bool Item_sum_sum_fix_length_and_dec(Item_sum_sum *) const= 0;
1356   virtual bool Item_sum_avg_fix_length_and_dec(Item_sum_avg *) const= 0;
1357   virtual
1358   bool Item_sum_variance_fix_length_and_dec(Item_sum_variance *) const= 0;
1359 
1360   virtual bool Item_val_bool(Item *item) const= 0;
1361   virtual bool Item_get_date(Item *item, MYSQL_TIME *ltime,
1362                              ulonglong fuzzydate) const= 0;
1363   virtual longlong Item_val_int_signed_typecast(Item *item) const= 0;
1364   virtual longlong Item_val_int_unsigned_typecast(Item *item) const= 0;
1365 
1366   virtual String *Item_func_hex_val_str_ascii(Item_func_hex *item,
1367                                               String *str) const= 0;
1368 
1369   virtual
1370   String *Item_func_hybrid_field_type_val_str(Item_func_hybrid_field_type *,
1371                                               String *) const= 0;
1372   virtual
1373   double Item_func_hybrid_field_type_val_real(Item_func_hybrid_field_type *)
1374                                               const= 0;
1375   virtual
1376   longlong Item_func_hybrid_field_type_val_int(Item_func_hybrid_field_type *)
1377                                                const= 0;
1378   virtual
1379   my_decimal *Item_func_hybrid_field_type_val_decimal(
1380                                               Item_func_hybrid_field_type *,
1381                                               my_decimal *) const= 0;
1382   virtual
1383   bool Item_func_hybrid_field_type_get_date(Item_func_hybrid_field_type *,
1384                                             MYSQL_TIME *,
1385                                             ulonglong fuzzydate) const= 0;
1386   virtual
1387   String *Item_func_min_max_val_str(Item_func_min_max *, String *) const= 0;
1388   virtual
1389   double Item_func_min_max_val_real(Item_func_min_max *) const= 0;
1390   virtual
1391   longlong Item_func_min_max_val_int(Item_func_min_max *) const= 0;
1392   virtual
1393   my_decimal *Item_func_min_max_val_decimal(Item_func_min_max *,
1394                                             my_decimal *) const= 0;
1395   virtual
1396   bool Item_func_min_max_get_date(Item_func_min_max*,
1397                                   MYSQL_TIME *, ulonglong fuzzydate) const= 0;
1398   virtual bool
1399   Item_func_between_fix_length_and_dec(Item_func_between *func) const= 0;
1400   virtual longlong
1401   Item_func_between_val_int(Item_func_between *func) const= 0;
1402 
1403   virtual cmp_item *
1404   make_cmp_item(THD *thd, CHARSET_INFO *cs) const= 0;
1405 
1406   virtual in_vector *
1407   make_in_vector(THD *thd, const Item_func_in *func, uint nargs) const= 0;
1408 
1409   virtual bool
1410   Item_func_in_fix_comparator_compatible_types(THD *thd, Item_func_in *)
1411                                                                const= 0;
1412 
1413   virtual bool
1414   Item_func_round_fix_length_and_dec(Item_func_round *round) const= 0;
1415 
1416   virtual bool
1417   Item_func_int_val_fix_length_and_dec(Item_func_int_val *func) const= 0;
1418 
1419   virtual bool
1420   Item_func_abs_fix_length_and_dec(Item_func_abs *func) const= 0;
1421 
1422   virtual bool
1423   Item_func_neg_fix_length_and_dec(Item_func_neg *func) const= 0;
1424 
1425   virtual bool
1426   Item_func_signed_fix_length_and_dec(Item_func_signed *item) const;
1427   virtual bool
1428   Item_func_unsigned_fix_length_and_dec(Item_func_unsigned *item) const;
1429   virtual bool
1430   Item_double_typecast_fix_length_and_dec(Item_double_typecast *item) const;
1431   virtual bool
1432   Item_float_typecast_fix_length_and_dec(Item_float_typecast *item) const;
1433   virtual bool
1434   Item_decimal_typecast_fix_length_and_dec(Item_decimal_typecast *item) const;
1435   virtual bool
1436   Item_char_typecast_fix_length_and_dec(Item_char_typecast *item) const;
1437   virtual bool
1438   Item_time_typecast_fix_length_and_dec(Item_time_typecast *item) const;
1439   virtual bool
1440   Item_date_typecast_fix_length_and_dec(Item_date_typecast *item) const;
1441   virtual bool
1442   Item_datetime_typecast_fix_length_and_dec(Item_datetime_typecast *item) const;
1443 
1444   virtual bool
1445   Item_func_plus_fix_length_and_dec(Item_func_plus *func) const= 0;
1446   virtual bool
1447   Item_func_minus_fix_length_and_dec(Item_func_minus *func) const= 0;
1448   virtual bool
1449   Item_func_mul_fix_length_and_dec(Item_func_mul *func) const= 0;
1450   virtual bool
1451   Item_func_div_fix_length_and_dec(Item_func_div *func) const= 0;
1452   virtual bool
1453   Item_func_mod_fix_length_and_dec(Item_func_mod *func) const= 0;
1454 
1455   virtual bool
1456   Vers_history_point_resolve_unit(THD *thd, Vers_history_point *point) const;
1457 };
1458 
1459 
1460 /*
1461   Special handler for ROW
1462 */
1463 class Type_handler_row: public Type_handler
1464 {
1465   static const Name m_name_row;
1466 public:
~Type_handler_row()1467   virtual ~Type_handler_row() {}
name()1468   const Name name() const { return m_name_row; }
is_scalar_type()1469   bool is_scalar_type() const { return false; }
can_return_int()1470   bool can_return_int() const { return false; }
can_return_decimal()1471   bool can_return_decimal() const { return false; }
can_return_real()1472   bool can_return_real() const { return false; }
can_return_str()1473   bool can_return_str() const { return false; }
can_return_text()1474   bool can_return_text() const { return false; }
can_return_date()1475   bool can_return_date() const { return false; }
can_return_time()1476   bool can_return_time() const { return false; }
field_type()1477   enum_field_types field_type() const
1478   {
1479     DBUG_ASSERT(0);
1480     return MYSQL_TYPE_NULL;
1481   };
result_type()1482   Item_result result_type() const
1483   {
1484     return ROW_RESULT;
1485   }
cmp_type()1486   Item_result cmp_type() const
1487   {
1488     return ROW_RESULT;
1489   }
1490   const Type_handler *type_handler_for_comparison() const;
subquery_type_allows_materialization(const Item * inner,const Item * outer,bool is_in_predicate)1491   bool subquery_type_allows_materialization(const Item *inner,
1492                                             const Item *outer,
1493                                             bool is_in_predicate) const
1494   {
1495     DBUG_ASSERT(0);
1496     return false;
1497   }
make_num_distinct_aggregator_field(MEM_ROOT *,const Item *)1498   Field *make_num_distinct_aggregator_field(MEM_ROOT *, const Item *) const
1499   {
1500     DBUG_ASSERT(0);
1501     return NULL;
1502   }
make_conversion_table_field(TABLE * TABLE,uint metadata,const Field * target)1503   Field *make_conversion_table_field(TABLE *TABLE,
1504                                      uint metadata,
1505                                      const Field *target) const
1506   {
1507     DBUG_ASSERT(0);
1508     return NULL;
1509   }
Column_definition_fix_attributes(Column_definition * c)1510   bool Column_definition_fix_attributes(Column_definition *c) const
1511   {
1512     return false;
1513   }
1514   bool Column_definition_prepare_stage1(THD *thd,
1515                                         MEM_ROOT *mem_root,
1516                                         Column_definition *c,
1517                                         handler *file,
1518                                         ulonglong table_flags) const;
Column_definition_redefine_stage1(Column_definition * def,const Column_definition * dup,const handler * file,const Schema_specification_st * schema)1519   bool Column_definition_redefine_stage1(Column_definition *def,
1520                                          const Column_definition *dup,
1521                                          const handler *file,
1522                                          const Schema_specification_st *schema)
1523                                          const
1524   {
1525     DBUG_ASSERT(0);
1526     return true;
1527   }
Column_definition_prepare_stage2(Column_definition * c,handler * file,ulonglong table_flags)1528   bool Column_definition_prepare_stage2(Column_definition *c,
1529                                         handler *file,
1530                                         ulonglong table_flags) const
1531   {
1532     return false;
1533   }
make_table_field(const LEX_CSTRING * name,const Record_addr & addr,const Type_all_attributes & attr,TABLE * table)1534   Field *make_table_field(const LEX_CSTRING *name,
1535                           const Record_addr &addr,
1536                           const Type_all_attributes &attr,
1537                           TABLE *table) const
1538   {
1539     DBUG_ASSERT(0);
1540     return NULL;
1541   }
make_sort_key(uchar * to,Item * item,const SORT_FIELD_ATTR * sort_field,Sort_param * param)1542   void make_sort_key(uchar *to, Item *item,
1543                      const SORT_FIELD_ATTR *sort_field,
1544                      Sort_param *param) const
1545   {
1546     DBUG_ASSERT(0);
1547   }
sortlength(THD * thd,const Type_std_attributes * item,SORT_FIELD_ATTR * attr)1548   void sortlength(THD *thd, const Type_std_attributes *item,
1549                             SORT_FIELD_ATTR *attr) const
1550   {
1551     DBUG_ASSERT(0);
1552   }
max_display_length(const Item * item)1553   uint32 max_display_length(const Item *item) const
1554   {
1555     DBUG_ASSERT(0);
1556     return 0;
1557   }
calc_pack_length(uint32 length)1558   uint32 calc_pack_length(uint32 length) const
1559   {
1560     DBUG_ASSERT(0);
1561     return 0;
1562   }
Item_decimal_precision(const Item * item)1563   uint Item_decimal_precision(const Item *item) const
1564   {
1565     DBUG_ASSERT(0);
1566     return DECIMAL_MAX_PRECISION;
1567   }
1568   bool Item_save_in_value(Item *item, st_value *value) const;
1569   bool Item_param_set_from_value(THD *thd,
1570                                  Item_param *param,
1571                                  const Type_all_attributes *attr,
1572                                  const st_value *value) const;
Item_send(Item * item,Protocol * protocol,st_value * buf)1573   bool Item_send(Item *item, Protocol *protocol, st_value *buf) const
1574   {
1575     DBUG_ASSERT(0);
1576     return true;
1577   }
Item_save_in_field(Item * item,Field * field,bool no_conversions)1578   int Item_save_in_field(Item *item, Field *field, bool no_conversions) const
1579   {
1580     DBUG_ASSERT(0);
1581     return 1;
1582   }
1583   String *print_item_value(THD *thd, Item *item, String *str) const;
can_change_cond_ref_to_const(Item_bool_func2 * target,Item * target_expr,Item * target_value,Item_bool_func2 * source,Item * source_expr,Item * source_const)1584   bool can_change_cond_ref_to_const(Item_bool_func2 *target,
1585                                    Item *target_expr, Item *target_value,
1586                                    Item_bool_func2 *source,
1587                                    Item *source_expr, Item *source_const) const
1588   {
1589     DBUG_ASSERT(0);
1590     return false;
1591   }
1592   Item *make_const_item_for_comparison(THD *, Item *src, const Item *cmp) const;
1593   Item_cache *Item_get_cache(THD *thd, const Item *item) const;
1594   bool set_comparator_func(Arg_comparator *cmp) const;
Item_hybrid_func_fix_attributes(THD * thd,const char * name,Type_handler_hybrid_field_type *,Type_all_attributes * atrr,Item ** items,uint nitems)1595   bool Item_hybrid_func_fix_attributes(THD *thd,
1596                                        const char *name,
1597                                        Type_handler_hybrid_field_type *,
1598                                        Type_all_attributes *atrr,
1599                                        Item **items, uint nitems) const
1600   {
1601     DBUG_ASSERT(0);
1602     return true;
1603   }
Item_sum_hybrid_fix_length_and_dec(Item_sum_hybrid * func)1604   bool Item_sum_hybrid_fix_length_and_dec(Item_sum_hybrid *func) const
1605   {
1606     DBUG_ASSERT(0);
1607     return true;
1608   }
Item_sum_sum_fix_length_and_dec(Item_sum_sum *)1609   bool Item_sum_sum_fix_length_and_dec(Item_sum_sum *) const
1610   {
1611     DBUG_ASSERT(0);
1612     return true;
1613   }
Item_sum_avg_fix_length_and_dec(Item_sum_avg *)1614   bool Item_sum_avg_fix_length_and_dec(Item_sum_avg *) const
1615   {
1616     DBUG_ASSERT(0);
1617     return true;
1618   }
Item_sum_variance_fix_length_and_dec(Item_sum_variance *)1619   bool Item_sum_variance_fix_length_and_dec(Item_sum_variance *) const
1620   {
1621     DBUG_ASSERT(0);
1622     return true;
1623   }
Item_val_bool(Item * item)1624   bool Item_val_bool(Item *item) const
1625   {
1626     DBUG_ASSERT(0);
1627     return false;
1628   }
Item_get_date(Item * item,MYSQL_TIME * ltime,ulonglong fuzzydate)1629   bool Item_get_date(Item *item, MYSQL_TIME *ltime, ulonglong fuzzydate) const
1630   {
1631     DBUG_ASSERT(0);
1632     return true;
1633   }
Item_val_int_signed_typecast(Item * item)1634   longlong Item_val_int_signed_typecast(Item *item) const
1635   {
1636     DBUG_ASSERT(0);
1637     return 0;
1638   }
Item_val_int_unsigned_typecast(Item * item)1639   longlong Item_val_int_unsigned_typecast(Item *item) const
1640   {
1641     DBUG_ASSERT(0);
1642     return 0;
1643   }
Item_func_hex_val_str_ascii(Item_func_hex * item,String * str)1644   String *Item_func_hex_val_str_ascii(Item_func_hex *item, String *str) const
1645   {
1646     DBUG_ASSERT(0);
1647     return NULL;
1648   }
Item_func_hybrid_field_type_val_str(Item_func_hybrid_field_type *,String *)1649   String *Item_func_hybrid_field_type_val_str(Item_func_hybrid_field_type *,
1650                                               String *) const
1651   {
1652     DBUG_ASSERT(0);
1653     return NULL;
1654   }
Item_func_hybrid_field_type_val_real(Item_func_hybrid_field_type *)1655   double Item_func_hybrid_field_type_val_real(Item_func_hybrid_field_type *)
1656                                               const
1657   {
1658     DBUG_ASSERT(0);
1659     return 0.0;
1660   }
Item_func_hybrid_field_type_val_int(Item_func_hybrid_field_type *)1661   longlong Item_func_hybrid_field_type_val_int(Item_func_hybrid_field_type *)
1662                                                const
1663   {
1664     DBUG_ASSERT(0);
1665     return 0;
1666   }
Item_func_hybrid_field_type_val_decimal(Item_func_hybrid_field_type *,my_decimal *)1667   my_decimal *Item_func_hybrid_field_type_val_decimal(
1668                                               Item_func_hybrid_field_type *,
1669                                               my_decimal *) const
1670   {
1671     DBUG_ASSERT(0);
1672     return NULL;
1673   }
Item_func_hybrid_field_type_get_date(Item_func_hybrid_field_type *,MYSQL_TIME *,ulonglong fuzzydate)1674   bool Item_func_hybrid_field_type_get_date(Item_func_hybrid_field_type *,
1675                                             MYSQL_TIME *,
1676                                             ulonglong fuzzydate) const
1677   {
1678     DBUG_ASSERT(0);
1679     return true;
1680   }
1681 
Item_func_min_max_val_str(Item_func_min_max *,String *)1682   String *Item_func_min_max_val_str(Item_func_min_max *, String *) const
1683   {
1684     DBUG_ASSERT(0);
1685     return NULL;
1686   }
Item_func_min_max_val_real(Item_func_min_max *)1687   double Item_func_min_max_val_real(Item_func_min_max *) const
1688   {
1689     DBUG_ASSERT(0);
1690     return 0;
1691   }
Item_func_min_max_val_int(Item_func_min_max *)1692   longlong Item_func_min_max_val_int(Item_func_min_max *) const
1693   {
1694     DBUG_ASSERT(0);
1695     return 0;
1696   }
Item_func_min_max_val_decimal(Item_func_min_max *,my_decimal *)1697   my_decimal *Item_func_min_max_val_decimal(Item_func_min_max *,
1698                                             my_decimal *) const
1699   {
1700     DBUG_ASSERT(0);
1701     return NULL;
1702   }
Item_func_min_max_get_date(Item_func_min_max *,MYSQL_TIME *,ulonglong fuzzydate)1703   bool Item_func_min_max_get_date(Item_func_min_max*,
1704                                   MYSQL_TIME *, ulonglong fuzzydate) const
1705   {
1706     DBUG_ASSERT(0);
1707     return true;
1708   }
Item_func_between_fix_length_and_dec(Item_func_between * func)1709   bool Item_func_between_fix_length_and_dec(Item_func_between *func) const
1710   {
1711     DBUG_ASSERT(0);
1712     return true;
1713   }
1714   longlong Item_func_between_val_int(Item_func_between *func) const;
1715   cmp_item *make_cmp_item(THD *thd, CHARSET_INFO *cs) const;
1716   in_vector *make_in_vector(THD *thd, const Item_func_in *f, uint nargs) const;
1717   bool Item_func_in_fix_comparator_compatible_types(THD *thd,
1718                                                     Item_func_in *) const;
1719   bool Item_func_round_fix_length_and_dec(Item_func_round *) const;
1720   bool Item_func_int_val_fix_length_and_dec(Item_func_int_val *) const;
1721   bool Item_func_abs_fix_length_and_dec(Item_func_abs *) const;
1722   bool Item_func_neg_fix_length_and_dec(Item_func_neg *) const;
1723 
Item_func_signed_fix_length_and_dec(Item_func_signed *)1724   bool Item_func_signed_fix_length_and_dec(Item_func_signed *) const
1725   {
1726     DBUG_ASSERT(0);
1727     return true;
1728   }
Item_func_unsigned_fix_length_and_dec(Item_func_unsigned *)1729   bool Item_func_unsigned_fix_length_and_dec(Item_func_unsigned *) const
1730   {
1731     DBUG_ASSERT(0);
1732     return true;
1733   }
Item_double_typecast_fix_length_and_dec(Item_double_typecast *)1734   bool Item_double_typecast_fix_length_and_dec(Item_double_typecast *) const
1735   {
1736     DBUG_ASSERT(0);
1737     return true;
1738   }
Item_float_typecast_fix_length_and_dec(Item_float_typecast *)1739   bool Item_float_typecast_fix_length_and_dec(Item_float_typecast *) const
1740   {
1741     DBUG_ASSERT(0);
1742     return true;
1743   }
Item_decimal_typecast_fix_length_and_dec(Item_decimal_typecast *)1744   bool Item_decimal_typecast_fix_length_and_dec(Item_decimal_typecast *) const
1745   {
1746     DBUG_ASSERT(0);
1747     return true;
1748   }
Item_char_typecast_fix_length_and_dec(Item_char_typecast *)1749   bool Item_char_typecast_fix_length_and_dec(Item_char_typecast *) const
1750   {
1751     DBUG_ASSERT(0);
1752     return true;
1753   }
Item_time_typecast_fix_length_and_dec(Item_time_typecast *)1754   bool Item_time_typecast_fix_length_and_dec(Item_time_typecast *) const
1755   {
1756     DBUG_ASSERT(0);
1757     return true;
1758   }
Item_date_typecast_fix_length_and_dec(Item_date_typecast *)1759   bool Item_date_typecast_fix_length_and_dec(Item_date_typecast *) const
1760   {
1761     DBUG_ASSERT(0);
1762     return true;
1763   }
Item_datetime_typecast_fix_length_and_dec(Item_datetime_typecast *)1764   bool Item_datetime_typecast_fix_length_and_dec(Item_datetime_typecast *) const
1765   {
1766     DBUG_ASSERT(0);
1767     return true;
1768   }
1769 
1770   bool Item_func_plus_fix_length_and_dec(Item_func_plus *) const;
1771   bool Item_func_minus_fix_length_and_dec(Item_func_minus *) const;
1772   bool Item_func_mul_fix_length_and_dec(Item_func_mul *) const;
1773   bool Item_func_div_fix_length_and_dec(Item_func_div *) const;
1774   bool Item_func_mod_fix_length_and_dec(Item_func_mod *) const;
1775 };
1776 
1777 
1778 /*
1779   A common parent class for numeric data type handlers
1780 */
1781 class Type_handler_numeric: public Type_handler
1782 {
1783 public:
1784   String *print_item_value(THD *thd, Item *item, String *str) const;
1785   double Item_func_min_max_val_real(Item_func_min_max *) const;
1786   longlong Item_func_min_max_val_int(Item_func_min_max *) const;
1787   my_decimal *Item_func_min_max_val_decimal(Item_func_min_max *,
1788                                             my_decimal *) const;
1789   bool Item_func_min_max_get_date(Item_func_min_max*,
1790                                   MYSQL_TIME *, ulonglong fuzzydate) const;
~Type_handler_numeric()1791   virtual ~Type_handler_numeric() { }
1792   bool can_change_cond_ref_to_const(Item_bool_func2 *target,
1793                                    Item *target_expr, Item *target_value,
1794                                    Item_bool_func2 *source,
1795                                    Item *source_expr, Item *source_const) const;
1796   bool Item_func_between_fix_length_and_dec(Item_func_between *func) const;
1797   bool Item_char_typecast_fix_length_and_dec(Item_char_typecast *) const;
1798 };
1799 
1800 
1801 /*** Abstract classes for every XXX_RESULT */
1802 
1803 class Type_handler_real_result: public Type_handler_numeric
1804 {
1805 public:
result_type()1806   Item_result result_type() const { return REAL_RESULT; }
cmp_type()1807   Item_result cmp_type() const { return REAL_RESULT; }
~Type_handler_real_result()1808   virtual ~Type_handler_real_result() {}
1809   const Type_handler *type_handler_for_comparison() const;
1810   bool subquery_type_allows_materialization(const Item *inner,
1811                                             const Item *outer,
1812                                             bool is_in_predicate) const;
1813   void make_sort_key(uchar *to, Item *item, const SORT_FIELD_ATTR *sort_field,
1814                      Sort_param *param) const;
1815   void sortlength(THD *thd,
1816                   const Type_std_attributes *item,
1817                   SORT_FIELD_ATTR *attr) const;
1818   uint Item_decimal_precision(const Item *item) const;
1819   bool Item_save_in_value(Item *item, st_value *value) const;
1820   bool Item_param_set_from_value(THD *thd,
1821                                  Item_param *param,
1822                                  const Type_all_attributes *attr,
1823                                  const st_value *value) const;
1824   int Item_save_in_field(Item *item, Field *field, bool no_conversions) const;
1825   Item *make_const_item_for_comparison(THD *, Item *src, const Item *cmp) const;
1826   bool set_comparator_func(Arg_comparator *cmp) const;
1827   bool Item_hybrid_func_fix_attributes(THD *thd,
1828                                        const char *name,
1829                                        Type_handler_hybrid_field_type *,
1830                                        Type_all_attributes *atrr,
1831                                        Item **items, uint nitems) const;
1832   bool Item_func_min_max_fix_attributes(THD *thd, Item_func_min_max *func,
1833                                         Item **items, uint nitems) const;
1834   bool Item_sum_hybrid_fix_length_and_dec(Item_sum_hybrid *func) const;
1835   bool Item_sum_sum_fix_length_and_dec(Item_sum_sum *) const;
1836   bool Item_sum_avg_fix_length_and_dec(Item_sum_avg *) const;
1837   bool Item_sum_variance_fix_length_and_dec(Item_sum_variance *) const;
1838   bool Item_func_signed_fix_length_and_dec(Item_func_signed *item) const;
1839   bool Item_func_unsigned_fix_length_and_dec(Item_func_unsigned *item) const;
1840   bool Item_val_bool(Item *item) const;
1841   bool Item_get_date(Item *item, MYSQL_TIME *ltime, ulonglong fuzzydate) const;
1842   longlong Item_val_int_signed_typecast(Item *item) const;
1843   longlong Item_val_int_unsigned_typecast(Item *item) const;
1844   String *Item_func_hex_val_str_ascii(Item_func_hex *item, String *str) const;
1845   double Item_func_hybrid_field_type_val_real(Item_func_hybrid_field_type *)
1846                                               const;
1847   longlong Item_func_hybrid_field_type_val_int(Item_func_hybrid_field_type *)
1848                                                const;
1849   my_decimal *Item_func_hybrid_field_type_val_decimal(
1850                                               Item_func_hybrid_field_type *,
1851                                               my_decimal *) const;
1852   bool Item_func_hybrid_field_type_get_date(Item_func_hybrid_field_type *,
1853                                             MYSQL_TIME *,
1854                                             ulonglong fuzzydate) const;
1855   longlong Item_func_between_val_int(Item_func_between *func) const;
1856   cmp_item *make_cmp_item(THD *thd, CHARSET_INFO *cs) const;
1857   in_vector *make_in_vector(THD *, const Item_func_in *, uint nargs) const;
1858   bool Item_func_in_fix_comparator_compatible_types(THD *thd,
1859                                                     Item_func_in *) const;
1860 
1861   bool Item_func_round_fix_length_and_dec(Item_func_round *) const;
1862   bool Item_func_int_val_fix_length_and_dec(Item_func_int_val *) const;
1863   bool Item_func_abs_fix_length_and_dec(Item_func_abs *) const;
1864   bool Item_func_neg_fix_length_and_dec(Item_func_neg *) const;
1865   bool Item_func_plus_fix_length_and_dec(Item_func_plus *) const;
1866   bool Item_func_minus_fix_length_and_dec(Item_func_minus *) const;
1867   bool Item_func_mul_fix_length_and_dec(Item_func_mul *) const;
1868   bool Item_func_div_fix_length_and_dec(Item_func_div *) const;
1869   bool Item_func_mod_fix_length_and_dec(Item_func_mod *) const;
1870 };
1871 
1872 
1873 class Type_handler_decimal_result: public Type_handler_numeric
1874 {
1875 public:
result_type()1876   Item_result result_type() const { return DECIMAL_RESULT; }
cmp_type()1877   Item_result cmp_type() const { return DECIMAL_RESULT; }
~Type_handler_decimal_result()1878   virtual ~Type_handler_decimal_result() {};
1879   const Type_handler *type_handler_for_comparison() const;
1880   bool subquery_type_allows_materialization(const Item *inner,
1881                                             const Item *outer,
1882                                             bool is_in_predicate) const;
1883   Field *make_num_distinct_aggregator_field(MEM_ROOT *, const Item *) const;
1884   void make_sort_key(uchar *to, Item *item, const SORT_FIELD_ATTR *sort_field,
1885                      Sort_param *param) const;
1886   void sortlength(THD *thd,
1887                   const Type_std_attributes *item,
1888                   SORT_FIELD_ATTR *attr) const;
1889   uint32 max_display_length(const Item *item) const;
1890   Item *create_typecast_item(THD *thd, Item *item,
1891                              const Type_cast_attributes &attr) const;
1892   uint Item_decimal_precision(const Item *item) const;
1893   bool Item_save_in_value(Item *item, st_value *value) const;
1894   void Item_param_set_param_func(Item_param *param,
1895                                  uchar **pos, ulong len) const;
1896   bool Item_param_set_from_value(THD *thd,
1897                                  Item_param *param,
1898                                  const Type_all_attributes *attr,
1899                                  const st_value *value) const;
Item_send(Item * item,Protocol * protocol,st_value * buf)1900   bool Item_send(Item *item, Protocol *protocol, st_value *buf) const
1901   {
1902     return Item_send_str(item, protocol, buf);
1903   }
1904   int Item_save_in_field(Item *item, Field *field, bool no_conversions) const;
1905   Item *make_const_item_for_comparison(THD *, Item *src, const Item *cmp) const;
1906   Item_cache *Item_get_cache(THD *thd, const Item *item) const;
1907   bool set_comparator_func(Arg_comparator *cmp) const;
1908   bool Item_hybrid_func_fix_attributes(THD *thd,
1909                                        const char *name,
1910                                        Type_handler_hybrid_field_type *,
1911                                        Type_all_attributes *atrr,
1912                                        Item **items, uint nitems) const;
1913   bool Item_sum_hybrid_fix_length_and_dec(Item_sum_hybrid *func) const;
1914   bool Item_sum_sum_fix_length_and_dec(Item_sum_sum *) const;
1915   bool Item_sum_avg_fix_length_and_dec(Item_sum_avg *) const;
1916   bool Item_sum_variance_fix_length_and_dec(Item_sum_variance *) const;
1917   bool Item_val_bool(Item *item) const;
1918   bool Item_get_date(Item *item, MYSQL_TIME *ltime, ulonglong fuzzydate) const;
1919   longlong Item_val_int_signed_typecast(Item *item) const;
1920   longlong Item_val_int_unsigned_typecast(Item *item) const;
1921   String *Item_func_hex_val_str_ascii(Item_func_hex *item, String *str) const;
1922   String *Item_func_hybrid_field_type_val_str(Item_func_hybrid_field_type *,
1923                                               String *) const;
1924   double Item_func_hybrid_field_type_val_real(Item_func_hybrid_field_type *)
1925                                               const;
1926   longlong Item_func_hybrid_field_type_val_int(Item_func_hybrid_field_type *)
1927                                                const;
1928   my_decimal *Item_func_hybrid_field_type_val_decimal(
1929                                               Item_func_hybrid_field_type *,
1930                                               my_decimal *) const;
1931   bool Item_func_hybrid_field_type_get_date(Item_func_hybrid_field_type *,
1932                                             MYSQL_TIME *,
1933                                             ulonglong fuzzydate) const;
1934   String *Item_func_min_max_val_str(Item_func_min_max *, String *) const;
1935   longlong Item_func_between_val_int(Item_func_between *func) const;
1936   cmp_item *make_cmp_item(THD *thd, CHARSET_INFO *cs) const;
1937   in_vector *make_in_vector(THD *, const Item_func_in *, uint nargs) const;
1938   bool Item_func_in_fix_comparator_compatible_types(THD *thd,
1939                                                     Item_func_in *) const;
1940   bool Item_func_round_fix_length_and_dec(Item_func_round *) const;
1941   bool Item_func_int_val_fix_length_and_dec(Item_func_int_val *) const;
1942   bool Item_func_abs_fix_length_and_dec(Item_func_abs *) const;
1943   bool Item_func_neg_fix_length_and_dec(Item_func_neg *) const;
1944   bool Item_func_plus_fix_length_and_dec(Item_func_plus *) const;
1945   bool Item_func_minus_fix_length_and_dec(Item_func_minus *) const;
1946   bool Item_func_mul_fix_length_and_dec(Item_func_mul *) const;
1947   bool Item_func_div_fix_length_and_dec(Item_func_div *) const;
1948   bool Item_func_mod_fix_length_and_dec(Item_func_mod *) const;
1949 };
1950 
1951 
1952 class Type_limits_int
1953 {
1954 private:
1955   uint32 m_precision;
1956   uint32 m_char_length;
1957 public:
Type_limits_int(uint32 prec,uint32 nchars)1958   Type_limits_int(uint32 prec, uint32 nchars)
1959    :m_precision(prec), m_char_length(nchars)
1960   { }
precision()1961   uint32 precision() const { return m_precision; }
char_length()1962   uint32 char_length() const { return m_char_length; }
1963 };
1964 
1965 
1966 /*
1967   UNDIGNED TINYINT:    0..255   digits=3 nchars=3
1968   SIGNED TINYINT  : -128..127   digits=3 nchars=4
1969 */
1970 class Type_limits_uint8: public Type_limits_int
1971 {
1972 public:
Type_limits_uint8()1973   Type_limits_uint8()
1974    :Type_limits_int(MAX_TINYINT_WIDTH, MAX_TINYINT_WIDTH)
1975   { }
1976 };
1977 
1978 
1979 class Type_limits_sint8: public Type_limits_int
1980 {
1981 public:
Type_limits_sint8()1982   Type_limits_sint8()
1983    :Type_limits_int(MAX_TINYINT_WIDTH, MAX_TINYINT_WIDTH + 1)
1984   { }
1985 };
1986 
1987 
1988 /*
1989   UNDIGNED SMALLINT:       0..65535  digits=5 nchars=5
1990   SIGNED SMALLINT:    -32768..32767  digits=5 nchars=6
1991 */
1992 class Type_limits_uint16: public Type_limits_int
1993 {
1994 public:
Type_limits_uint16()1995   Type_limits_uint16()
1996    :Type_limits_int(MAX_SMALLINT_WIDTH, MAX_SMALLINT_WIDTH)
1997   { }
1998 };
1999 
2000 
2001 class Type_limits_sint16: public Type_limits_int
2002 {
2003 public:
Type_limits_sint16()2004   Type_limits_sint16()
2005    :Type_limits_int(MAX_SMALLINT_WIDTH, MAX_SMALLINT_WIDTH + 1)
2006   { }
2007 };
2008 
2009 
2010 /*
2011   MEDIUMINT UNSIGNED         0 .. 16777215  digits=8 char_length=8
2012   MEDIUMINT SIGNED:   -8388608 ..  8388607  digits=7 char_length=8
2013 */
2014 class Type_limits_uint24: public Type_limits_int
2015 {
2016 public:
Type_limits_uint24()2017   Type_limits_uint24()
2018    :Type_limits_int(MAX_MEDIUMINT_WIDTH, MAX_MEDIUMINT_WIDTH)
2019   { }
2020 };
2021 
2022 
2023 class Type_limits_sint24: public Type_limits_int
2024 {
2025 public:
Type_limits_sint24()2026   Type_limits_sint24()
2027    :Type_limits_int(MAX_MEDIUMINT_WIDTH - 1, MAX_MEDIUMINT_WIDTH)
2028   { }
2029 };
2030 
2031 
2032 /*
2033   UNSIGNED INT:           0..4294967295  digits=10 nchars=10
2034   SIGNED INT:   -2147483648..2147483647  digits=10 nchars=11
2035 */
2036 class Type_limits_uint32: public Type_limits_int
2037 {
2038 public:
Type_limits_uint32()2039   Type_limits_uint32()
2040    :Type_limits_int(MAX_INT_WIDTH, MAX_INT_WIDTH)
2041   { }
2042 };
2043 
2044 
2045 
2046 class Type_limits_sint32: public Type_limits_int
2047 {
2048 public:
Type_limits_sint32()2049   Type_limits_sint32()
2050    :Type_limits_int(MAX_INT_WIDTH, MAX_INT_WIDTH + 1)
2051   { }
2052 };
2053 
2054 
2055 /*
2056   UNSIGNED BIGINT:                  0..18446744073709551615 digits=20 nchars=20
2057   SIGNED BIGINT:  -9223372036854775808..9223372036854775807 digits=19 nchars=20
2058 */
2059 class Type_limits_uint64: public Type_limits_int
2060 {
2061 public:
Type_limits_uint64()2062   Type_limits_uint64(): Type_limits_int(MAX_BIGINT_WIDTH, MAX_BIGINT_WIDTH)
2063   { }
2064 };
2065 
2066 
2067 class Type_limits_sint64: public Type_limits_int
2068 {
2069 public:
Type_limits_sint64()2070   Type_limits_sint64()
2071    :Type_limits_int(MAX_BIGINT_WIDTH - 1, MAX_BIGINT_WIDTH)
2072   { }
2073 };
2074 
2075 
2076 
2077 class Type_handler_int_result: public Type_handler_numeric
2078 {
2079 public:
result_type()2080   Item_result result_type() const { return INT_RESULT; }
cmp_type()2081   Item_result cmp_type() const { return INT_RESULT; }
~Type_handler_int_result()2082   virtual ~Type_handler_int_result() {}
2083   const Type_handler *type_handler_for_comparison() const;
2084   bool subquery_type_allows_materialization(const Item *inner,
2085                                             const Item *outer,
2086                                             bool is_in_predicate) const;
2087   Field *make_num_distinct_aggregator_field(MEM_ROOT *, const Item *) const;
2088   void make_sort_key(uchar *to, Item *item, const SORT_FIELD_ATTR *sort_field,
2089                      Sort_param *param) const;
2090   void sortlength(THD *thd,
2091                   const Type_std_attributes *item,
2092                   SORT_FIELD_ATTR *attr) const;
2093   uint Item_decimal_precision(const Item *item) const;
2094   bool Item_save_in_value(Item *item, st_value *value) const;
2095   bool Item_param_set_from_value(THD *thd,
2096                                  Item_param *param,
2097                                  const Type_all_attributes *attr,
2098                                  const st_value *value) const;
2099   int Item_save_in_field(Item *item, Field *field, bool no_conversions) const;
2100   Item *make_const_item_for_comparison(THD *, Item *src, const Item *cmp) const;
2101   Item_cache *Item_get_cache(THD *thd, const Item *item) const;
2102   bool set_comparator_func(Arg_comparator *cmp) const;
2103   bool Item_hybrid_func_fix_attributes(THD *thd,
2104                                        const char *name,
2105                                        Type_handler_hybrid_field_type *,
2106                                        Type_all_attributes *atrr,
2107                                        Item **items, uint nitems) const;
2108   bool Item_sum_hybrid_fix_length_and_dec(Item_sum_hybrid *func) const;
2109   bool Item_sum_sum_fix_length_and_dec(Item_sum_sum *) const;
2110   bool Item_sum_avg_fix_length_and_dec(Item_sum_avg *) const;
2111   bool Item_sum_variance_fix_length_and_dec(Item_sum_variance *) const;
2112   bool Item_val_bool(Item *item) const;
2113   bool Item_get_date(Item *item, MYSQL_TIME *ltime, ulonglong fuzzydate) const;
2114   longlong Item_val_int_signed_typecast(Item *item) const;
2115   longlong Item_val_int_unsigned_typecast(Item *item) const;
2116   String *Item_func_hex_val_str_ascii(Item_func_hex *item, String *str) const;
2117   String *Item_func_hybrid_field_type_val_str(Item_func_hybrid_field_type *,
2118                                               String *) const;
2119   double Item_func_hybrid_field_type_val_real(Item_func_hybrid_field_type *)
2120                                               const;
2121   longlong Item_func_hybrid_field_type_val_int(Item_func_hybrid_field_type *)
2122                                                const;
2123   my_decimal *Item_func_hybrid_field_type_val_decimal(
2124                                               Item_func_hybrid_field_type *,
2125                                               my_decimal *) const;
2126   bool Item_func_hybrid_field_type_get_date(Item_func_hybrid_field_type *,
2127                                             MYSQL_TIME *,
2128                                             ulonglong fuzzydate) const;
2129   String *Item_func_min_max_val_str(Item_func_min_max *, String *) const;
2130   longlong Item_func_between_val_int(Item_func_between *func) const;
2131   cmp_item *make_cmp_item(THD *thd, CHARSET_INFO *cs) const;
2132   in_vector *make_in_vector(THD *, const Item_func_in *, uint nargs) const;
2133   bool Item_func_in_fix_comparator_compatible_types(THD *thd,
2134                                                     Item_func_in *) const;
2135   bool Item_func_round_fix_length_and_dec(Item_func_round *) const;
2136   bool Item_func_int_val_fix_length_and_dec(Item_func_int_val *) const;
2137   bool Item_func_abs_fix_length_and_dec(Item_func_abs *) const;
2138   bool Item_func_neg_fix_length_and_dec(Item_func_neg *) const;
2139   bool Item_func_plus_fix_length_and_dec(Item_func_plus *) const;
2140   bool Item_func_minus_fix_length_and_dec(Item_func_minus *) const;
2141   bool Item_func_mul_fix_length_and_dec(Item_func_mul *) const;
2142   bool Item_func_div_fix_length_and_dec(Item_func_div *) const;
2143   bool Item_func_mod_fix_length_and_dec(Item_func_mod *) const;
2144 };
2145 
2146 
2147 class Type_handler_general_purpose_int: public Type_handler_int_result
2148 {
2149 public:
type_can_have_auto_increment_attribute()2150   bool type_can_have_auto_increment_attribute() const { return true; }
2151   virtual const Type_limits_int *
2152     type_limits_int_by_unsigned_flag(bool unsigned_flag) const= 0;
2153   uint32 max_display_length(const Item *item) const;
2154   bool Vers_history_point_resolve_unit(THD *thd, Vers_history_point *p) const;
2155 };
2156 
2157 
2158 class Type_handler_temporal_result: public Type_handler
2159 {
2160 protected:
2161   uint Item_decimal_scale_with_seconds(const Item *item) const;
2162   uint Item_divisor_precision_increment_with_seconds(const Item *) const;
2163 public:
result_type()2164   Item_result result_type() const { return STRING_RESULT; }
cmp_type()2165   Item_result cmp_type() const { return TIME_RESULT; }
~Type_handler_temporal_result()2166   virtual ~Type_handler_temporal_result() {}
2167   void make_sort_key(uchar *to, Item *item,  const SORT_FIELD_ATTR *sort_field,
2168                      Sort_param *param) const;
2169   void sortlength(THD *thd,
2170                   const Type_std_attributes *item,
2171                   SORT_FIELD_ATTR *attr) const;
2172   bool Item_param_set_from_value(THD *thd,
2173                                  Item_param *param,
2174                                  const Type_all_attributes *attr,
2175                                  const st_value *value) const;
2176   uint32 max_display_length(const Item *item) const;
2177   bool can_change_cond_ref_to_const(Item_bool_func2 *target,
2178                                    Item *target_expr, Item *target_value,
2179                                    Item_bool_func2 *source,
2180                                    Item *source_expr, Item *source_const) const;
2181   bool subquery_type_allows_materialization(const Item *inner,
2182                                             const Item *outer,
2183                                             bool is_in_predicate) const;
2184   bool Item_func_min_max_fix_attributes(THD *thd, Item_func_min_max *func,
2185                                         Item **items, uint nitems) const;
2186   bool Item_sum_hybrid_fix_length_and_dec(Item_sum_hybrid *func) const;
2187   bool Item_sum_sum_fix_length_and_dec(Item_sum_sum *) const;
2188   bool Item_sum_avg_fix_length_and_dec(Item_sum_avg *) const;
2189   bool Item_sum_variance_fix_length_and_dec(Item_sum_variance *) const;
2190   bool Item_val_bool(Item *item) const;
2191   bool Item_get_date(Item *item, MYSQL_TIME *ltime, ulonglong fuzzydate) const;
2192   longlong Item_val_int_signed_typecast(Item *item) const;
2193   longlong Item_val_int_unsigned_typecast(Item *item) const;
2194   String *Item_func_hex_val_str_ascii(Item_func_hex *item, String *str) const;
2195   String *Item_func_hybrid_field_type_val_str(Item_func_hybrid_field_type *,
2196                                               String *) const;
2197   double Item_func_hybrid_field_type_val_real(Item_func_hybrid_field_type *)
2198                                               const;
2199   longlong Item_func_hybrid_field_type_val_int(Item_func_hybrid_field_type *)
2200                                                const;
2201   my_decimal *Item_func_hybrid_field_type_val_decimal(
2202                                               Item_func_hybrid_field_type *,
2203                                               my_decimal *) const;
2204   bool Item_func_hybrid_field_type_get_date(Item_func_hybrid_field_type *,
2205                                             MYSQL_TIME *,
2206                                             ulonglong fuzzydate) const;
2207   String *Item_func_min_max_val_str(Item_func_min_max *, String *) const;
2208   double Item_func_min_max_val_real(Item_func_min_max *) const;
2209   longlong Item_func_min_max_val_int(Item_func_min_max *) const;
2210   my_decimal *Item_func_min_max_val_decimal(Item_func_min_max *,
2211                                             my_decimal *) const;
2212   bool Item_func_min_max_get_date(Item_func_min_max*,
2213                                   MYSQL_TIME *, ulonglong fuzzydate) const;
2214   bool Item_func_between_fix_length_and_dec(Item_func_between *func) const;
2215   longlong Item_func_between_val_int(Item_func_between *func) const;
2216   bool Item_func_in_fix_comparator_compatible_types(THD *thd,
2217                                                     Item_func_in *) const;
2218   bool Item_func_round_fix_length_and_dec(Item_func_round *) const;
2219   bool Item_func_int_val_fix_length_and_dec(Item_func_int_val *) const;
2220   bool Item_func_abs_fix_length_and_dec(Item_func_abs *) const;
2221   bool Item_func_neg_fix_length_and_dec(Item_func_neg *) const;
2222   bool Item_func_plus_fix_length_and_dec(Item_func_plus *) const;
2223   bool Item_func_minus_fix_length_and_dec(Item_func_minus *) const;
2224   bool Item_func_mul_fix_length_and_dec(Item_func_mul *) const;
2225   bool Item_func_div_fix_length_and_dec(Item_func_div *) const;
2226   bool Item_func_mod_fix_length_and_dec(Item_func_mod *) const;
2227   bool Vers_history_point_resolve_unit(THD *thd, Vers_history_point *p) const;
2228 };
2229 
2230 
2231 class Type_handler_string_result: public Type_handler
2232 {
2233   uint Item_temporal_precision(Item *item, bool is_time) const;
2234 public:
result_type()2235   Item_result result_type() const { return STRING_RESULT; }
cmp_type()2236   Item_result cmp_type() const { return STRING_RESULT; }
2237   CHARSET_INFO *charset_for_protocol(const Item *item) const;
~Type_handler_string_result()2238   virtual ~Type_handler_string_result() {}
2239   const Type_handler *type_handler_for_comparison() const;
2240   const Type_handler *
2241   type_handler_adjusted_to_max_octet_length(uint max_octet_length,
2242                                             CHARSET_INFO *cs) const;
2243   void make_sort_key(uchar *to, Item *item, const SORT_FIELD_ATTR *sort_field,
2244                      Sort_param *param) const;
2245   void sortlength(THD *thd,
2246                   const Type_std_attributes *item,
2247                   SORT_FIELD_ATTR *attr) const;
2248   bool union_element_finalize(Item_type_holder *item) const;
2249   bool Column_definition_prepare_stage1(THD *thd,
2250                                         MEM_ROOT *mem_root,
2251                                         Column_definition *c,
2252                                         handler *file,
2253                                         ulonglong table_flags) const;
2254   bool Column_definition_redefine_stage1(Column_definition *def,
2255                                          const Column_definition *dup,
2256                                          const handler *file,
2257                                          const Schema_specification_st *schema)
2258                                          const;
2259   uint32 max_display_length(const Item *item) const;
Item_time_precision(Item * item)2260   uint Item_time_precision(Item *item) const
2261   {
2262     return Item_temporal_precision(item, true);
2263   }
Item_datetime_precision(Item * item)2264   uint Item_datetime_precision(Item *item) const
2265   {
2266     return Item_temporal_precision(item, false);
2267   }
2268   uint Item_decimal_precision(const Item *item) const;
2269   bool Item_save_in_value(Item *item, st_value *value) const;
2270   void Item_param_setup_conversion(THD *thd, Item_param *) const;
2271   void Item_param_set_param_func(Item_param *param,
2272                                  uchar **pos, ulong len) const;
2273   bool Item_param_set_from_value(THD *thd,
2274                                  Item_param *param,
2275                                  const Type_all_attributes *attr,
2276                                  const st_value *value) const;
Item_send(Item * item,Protocol * protocol,st_value * buf)2277   bool Item_send(Item *item, Protocol *protocol, st_value *buf) const
2278   {
2279     return Item_send_str(item, protocol, buf);
2280   }
2281   int Item_save_in_field(Item *item, Field *field, bool no_conversions) const;
print_item_value(THD * thd,Item * item,String * str)2282   String *print_item_value(THD *thd, Item *item, String *str) const
2283   {
2284     return print_item_value_csstr(thd, item, str);
2285   }
2286   bool can_change_cond_ref_to_const(Item_bool_func2 *target,
2287                                    Item *target_expr, Item *target_value,
2288                                    Item_bool_func2 *source,
2289                                    Item *source_expr, Item *source_const) const;
2290   bool subquery_type_allows_materialization(const Item *inner,
2291                                             const Item *outer,
2292                                             bool is_in_predicate) const;
2293   Item *make_const_item_for_comparison(THD *, Item *src, const Item *cmp) const;
2294   Item_cache *Item_get_cache(THD *thd, const Item *item) const;
2295   bool set_comparator_func(Arg_comparator *cmp) const;
2296   bool Item_hybrid_func_fix_attributes(THD *thd,
2297                                        const char *name,
2298                                        Type_handler_hybrid_field_type *,
2299                                        Type_all_attributes *atrr,
2300                                        Item **items, uint nitems) const;
2301   bool Item_sum_hybrid_fix_length_and_dec(Item_sum_hybrid *func) const;
2302   bool Item_sum_sum_fix_length_and_dec(Item_sum_sum *) const;
2303   bool Item_sum_avg_fix_length_and_dec(Item_sum_avg *) const;
2304   bool Item_sum_variance_fix_length_and_dec(Item_sum_variance *) const;
2305   bool Item_func_signed_fix_length_and_dec(Item_func_signed *item) const;
2306   bool Item_func_unsigned_fix_length_and_dec(Item_func_unsigned *item) const;
2307   bool Item_val_bool(Item *item) const;
2308   bool Item_get_date(Item *item, MYSQL_TIME *ltime, ulonglong fuzzydate) const;
2309   longlong Item_val_int_signed_typecast(Item *item) const;
2310   longlong Item_val_int_unsigned_typecast(Item *item) const;
2311   String *Item_func_hex_val_str_ascii(Item_func_hex *item, String *str) const;
2312   String *Item_func_hybrid_field_type_val_str(Item_func_hybrid_field_type *,
2313                                               String *) const;
2314   double Item_func_hybrid_field_type_val_real(Item_func_hybrid_field_type *)
2315                                               const;
2316   longlong Item_func_hybrid_field_type_val_int(Item_func_hybrid_field_type *)
2317                                                const;
2318   my_decimal *Item_func_hybrid_field_type_val_decimal(
2319                                               Item_func_hybrid_field_type *,
2320                                               my_decimal *) const;
2321   bool Item_func_hybrid_field_type_get_date(Item_func_hybrid_field_type *,
2322                                             MYSQL_TIME *,
2323                                             ulonglong fuzzydate) const;
2324   String *Item_func_min_max_val_str(Item_func_min_max *, String *) const;
2325   double Item_func_min_max_val_real(Item_func_min_max *) const;
2326   longlong Item_func_min_max_val_int(Item_func_min_max *) const;
2327   my_decimal *Item_func_min_max_val_decimal(Item_func_min_max *,
2328                                             my_decimal *) const;
2329   bool Item_func_min_max_get_date(Item_func_min_max*,
2330                                   MYSQL_TIME *, ulonglong fuzzydate) const;
2331   bool Item_func_between_fix_length_and_dec(Item_func_between *func) const;
2332   longlong Item_func_between_val_int(Item_func_between *func) const;
2333   bool Item_char_typecast_fix_length_and_dec(Item_char_typecast *) const;
2334   cmp_item *make_cmp_item(THD *thd, CHARSET_INFO *cs) const;
2335   in_vector *make_in_vector(THD *, const Item_func_in *, uint nargs) const;
2336   bool Item_func_in_fix_comparator_compatible_types(THD *thd,
2337                                                     Item_func_in *) const;
2338   bool Item_func_round_fix_length_and_dec(Item_func_round *) const;
2339   bool Item_func_int_val_fix_length_and_dec(Item_func_int_val *) const;
2340   bool Item_func_abs_fix_length_and_dec(Item_func_abs *) const;
2341   bool Item_func_neg_fix_length_and_dec(Item_func_neg *) const;
2342   bool Item_func_plus_fix_length_and_dec(Item_func_plus *) const;
2343   bool Item_func_minus_fix_length_and_dec(Item_func_minus *) const;
2344   bool Item_func_mul_fix_length_and_dec(Item_func_mul *) const;
2345   bool Item_func_div_fix_length_and_dec(Item_func_div *) const;
2346   bool Item_func_mod_fix_length_and_dec(Item_func_mod *) const;
2347 };
2348 
2349 
2350 class Type_handler_general_purpose_string: public Type_handler_string_result
2351 {
2352 public:
is_general_purpose_string_type()2353   bool is_general_purpose_string_type() const { return true; }
2354   bool Vers_history_point_resolve_unit(THD *thd, Vers_history_point *p) const;
2355 };
2356 
2357 
2358 /***
2359   Instantiable classes for every MYSQL_TYPE_XXX
2360 
2361   There are no Type_handler_xxx for the following types:
2362   - MYSQL_TYPE_VAR_STRING (old VARCHAR) - mapped to MYSQL_TYPE_VARSTRING
2363   - MYSQL_TYPE_ENUM                     - mapped to MYSQL_TYPE_VARSTRING
2364   - MYSQL_TYPE_SET:                     - mapped to MYSQL_TYPE_VARSTRING
2365 
2366   because the functionality that currently uses Type_handler
2367   (e.g. hybrid type functions) does not need to distinguish between
2368   these types and VARCHAR.
2369   For example:
2370     CREATE TABLE t2 AS SELECT COALESCE(enum_column) FROM t1;
2371   creates a VARCHAR column.
2372 
2373   There most likely be Type_handler_enum and Type_handler_set later,
2374   when the Type_handler infrastructure gets used in more pieces of the code.
2375 */
2376 
2377 
2378 class Type_handler_tiny: public Type_handler_general_purpose_int
2379 {
2380   static const Name m_name_tiny;
2381   static const Type_limits_int m_limits_sint8;
2382   static const Type_limits_int m_limits_uint8;
2383 public:
~Type_handler_tiny()2384   virtual ~Type_handler_tiny() {}
name()2385   const Name name() const { return m_name_tiny; }
field_type()2386   enum_field_types field_type() const { return MYSQL_TYPE_TINY; }
type_limits_int_by_unsigned_flag(bool unsigned_fl)2387   const Type_limits_int *type_limits_int_by_unsigned_flag(bool unsigned_fl) const
2388   {
2389     return unsigned_fl ? &m_limits_uint8 : &m_limits_sint8;
2390   }
calc_pack_length(uint32 length)2391   uint32 calc_pack_length(uint32 length) const { return 1; }
Item_send(Item * item,Protocol * protocol,st_value * buf)2392   bool Item_send(Item *item, Protocol *protocol, st_value *buf) const
2393   {
2394     return Item_send_tiny(item, protocol, buf);
2395   }
2396   Field *make_conversion_table_field(TABLE *TABLE, uint metadata,
2397                                      const Field *target) const;
2398   bool Column_definition_fix_attributes(Column_definition *c) const;
Column_definition_prepare_stage2(Column_definition * c,handler * file,ulonglong table_flags)2399   bool Column_definition_prepare_stage2(Column_definition *c,
2400                                         handler *file,
2401                                         ulonglong table_flags) const
2402   { return Column_definition_prepare_stage2_legacy_num(c, MYSQL_TYPE_TINY); }
2403   Field *make_table_field(const LEX_CSTRING *name,
2404                           const Record_addr &addr,
2405                           const Type_all_attributes &attr,
2406                           TABLE *table) const;
2407   void Item_param_set_param_func(Item_param *param,
2408                                  uchar **pos, ulong len) const;
2409 };
2410 
2411 
2412 class Type_handler_short: public Type_handler_general_purpose_int
2413 {
2414   static const Name m_name_short;
2415   static const Type_limits_int m_limits_sint16;
2416   static const Type_limits_int m_limits_uint16;
2417 public:
~Type_handler_short()2418   virtual ~Type_handler_short() {}
name()2419   const Name name() const { return m_name_short; }
field_type()2420   enum_field_types field_type() const { return MYSQL_TYPE_SHORT; }
Item_send(Item * item,Protocol * protocol,st_value * buf)2421   bool Item_send(Item *item, Protocol *protocol, st_value *buf) const
2422   {
2423     return Item_send_short(item, protocol, buf);
2424   }
type_limits_int_by_unsigned_flag(bool unsigned_fl)2425   const Type_limits_int *type_limits_int_by_unsigned_flag(bool unsigned_fl) const
2426   {
2427     return unsigned_fl ? &m_limits_uint16 : &m_limits_sint16;
2428   }
calc_pack_length(uint32 length)2429   uint32 calc_pack_length(uint32 length) const { return 2; }
2430   Field *make_conversion_table_field(TABLE *TABLE, uint metadata,
2431                                      const Field *target) const;
2432   bool Column_definition_fix_attributes(Column_definition *c) const;
Column_definition_prepare_stage2(Column_definition * c,handler * file,ulonglong table_flags)2433   bool Column_definition_prepare_stage2(Column_definition *c,
2434                                         handler *file,
2435                                         ulonglong table_flags) const
2436   { return Column_definition_prepare_stage2_legacy_num(c, MYSQL_TYPE_SHORT); }
2437   Field *make_table_field(const LEX_CSTRING *name,
2438                           const Record_addr &addr,
2439                           const Type_all_attributes &attr,
2440                           TABLE *table) const;
2441   void Item_param_set_param_func(Item_param *param,
2442                                  uchar **pos, ulong len) const;
2443 };
2444 
2445 
2446 class Type_handler_long: public Type_handler_general_purpose_int
2447 {
2448   static const Name m_name_int;
2449   static const Type_limits_int m_limits_sint32;
2450   static const Type_limits_int m_limits_uint32;
2451 public:
~Type_handler_long()2452   virtual ~Type_handler_long() {}
name()2453   const Name name() const { return m_name_int; }
field_type()2454   enum_field_types field_type() const { return MYSQL_TYPE_LONG; }
type_limits_int_by_unsigned_flag(bool unsigned_fl)2455   const Type_limits_int *type_limits_int_by_unsigned_flag(bool unsigned_fl) const
2456   {
2457     return unsigned_fl ? &m_limits_uint32 : &m_limits_sint32;
2458   }
calc_pack_length(uint32 length)2459   uint32 calc_pack_length(uint32 length) const { return 4; }
Item_send(Item * item,Protocol * protocol,st_value * buf)2460   bool Item_send(Item *item, Protocol *protocol, st_value *buf) const
2461   {
2462     return Item_send_long(item, protocol, buf);
2463   }
2464   Field *make_conversion_table_field(TABLE *TABLE, uint metadata,
2465                                      const Field *target) const;
2466   bool Column_definition_fix_attributes(Column_definition *c) const;
Column_definition_prepare_stage2(Column_definition * c,handler * file,ulonglong table_flags)2467   bool Column_definition_prepare_stage2(Column_definition *c,
2468                                         handler *file,
2469                                         ulonglong table_flags) const
2470   { return Column_definition_prepare_stage2_legacy_num(c, MYSQL_TYPE_LONG); }
2471   Field *make_table_field(const LEX_CSTRING *name,
2472                           const Record_addr &addr,
2473                           const Type_all_attributes &attr,
2474                           TABLE *table) const;
2475   void Item_param_set_param_func(Item_param *param,
2476                                  uchar **pos, ulong len) const;
2477 };
2478 
2479 
2480 class Type_handler_longlong: public Type_handler_general_purpose_int
2481 {
2482   static const Name m_name_longlong;
2483   static const Type_limits_int m_limits_sint64;
2484   static const Type_limits_int m_limits_uint64;
2485 public:
~Type_handler_longlong()2486   virtual ~Type_handler_longlong() {}
name()2487   const Name name() const { return m_name_longlong; }
field_type()2488   enum_field_types field_type() const { return MYSQL_TYPE_LONGLONG; }
type_limits_int_by_unsigned_flag(bool unsigned_fl)2489   const Type_limits_int *type_limits_int_by_unsigned_flag(bool unsigned_fl) const
2490   {
2491     return unsigned_fl ? &m_limits_uint64 : &m_limits_sint64;
2492   }
calc_pack_length(uint32 length)2493   uint32 calc_pack_length(uint32 length) const { return 8; }
2494   Item *create_typecast_item(THD *thd, Item *item,
2495                              const Type_cast_attributes &attr) const;
Item_send(Item * item,Protocol * protocol,st_value * buf)2496   bool Item_send(Item *item, Protocol *protocol, st_value *buf) const
2497   {
2498     return Item_send_longlong(item, protocol, buf);
2499   }
2500   Field *make_conversion_table_field(TABLE *TABLE, uint metadata,
2501                                      const Field *target) const;
2502   bool Column_definition_fix_attributes(Column_definition *c) const;
Column_definition_prepare_stage2(Column_definition * c,handler * file,ulonglong table_flags)2503   bool Column_definition_prepare_stage2(Column_definition *c,
2504                                         handler *file,
2505                                         ulonglong table_flags) const
2506   {
2507     return Column_definition_prepare_stage2_legacy_num(c, MYSQL_TYPE_LONGLONG);
2508   }
2509   Field *make_table_field(const LEX_CSTRING *name,
2510                           const Record_addr &addr,
2511                           const Type_all_attributes &attr,
2512                           TABLE *table) const;
2513   void Item_param_set_param_func(Item_param *param,
2514                                  uchar **pos, ulong len) const;
2515 };
2516 
2517 
2518 class Type_handler_vers_trx_id: public Type_handler_longlong
2519 {
2520 public:
~Type_handler_vers_trx_id()2521   virtual ~Type_handler_vers_trx_id() {}
2522   Field *make_table_field(const LEX_CSTRING *name,
2523                           const Record_addr &addr,
2524                           const Type_all_attributes &attr,
2525                           TABLE *table) const;
2526 };
2527 
2528 
2529 class Type_handler_int24: public Type_handler_general_purpose_int
2530 {
2531   static const Name m_name_mediumint;
2532   static const Type_limits_int m_limits_sint24;
2533   static const Type_limits_int m_limits_uint24;
2534 public:
~Type_handler_int24()2535   virtual ~Type_handler_int24() {}
name()2536   const Name name() const { return m_name_mediumint; }
field_type()2537   enum_field_types field_type() const { return MYSQL_TYPE_INT24; }
Item_send(Item * item,Protocol * protocol,st_value * buf)2538   bool Item_send(Item *item, Protocol *protocol, st_value *buf) const
2539   {
2540     return Item_send_long(item, protocol, buf);
2541   }
type_limits_int_by_unsigned_flag(bool unsigned_fl)2542   const Type_limits_int *type_limits_int_by_unsigned_flag(bool unsigned_fl) const
2543   {
2544     return unsigned_fl ? &m_limits_uint24 : &m_limits_sint24;
2545   }
calc_pack_length(uint32 length)2546   uint32 calc_pack_length(uint32 length) const { return 3; }
2547   Field *make_conversion_table_field(TABLE *, uint metadata,
2548                                      const Field *target) const;
2549   bool Column_definition_fix_attributes(Column_definition *c) const;
Column_definition_prepare_stage2(Column_definition * c,handler * file,ulonglong table_flags)2550   bool Column_definition_prepare_stage2(Column_definition *c,
2551                                         handler *file,
2552                                         ulonglong table_flags) const
2553   { return Column_definition_prepare_stage2_legacy_num(c, MYSQL_TYPE_INT24); }
2554   Field *make_table_field(const LEX_CSTRING *name,
2555                           const Record_addr &addr,
2556                           const Type_all_attributes &attr,
2557                           TABLE *table) const;
2558 };
2559 
2560 
2561 class Type_handler_year: public Type_handler_int_result
2562 {
2563   static const Name m_name_year;
2564 public:
~Type_handler_year()2565   virtual ~Type_handler_year() {}
name()2566   const Name name() const { return m_name_year; }
field_type()2567   enum_field_types field_type() const { return MYSQL_TYPE_YEAR; }
2568   uint32 max_display_length(const Item *item) const;
calc_pack_length(uint32 length)2569   uint32 calc_pack_length(uint32 length) const { return 1; }
Item_send(Item * item,Protocol * protocol,st_value * buf)2570   bool Item_send(Item *item, Protocol *protocol, st_value *buf) const
2571   {
2572     return Item_send_short(item, protocol, buf);
2573   }
2574   Field *make_conversion_table_field(TABLE *, uint metadata,
2575                                      const Field *target) const;
2576   bool Column_definition_fix_attributes(Column_definition *c) const;
Column_definition_prepare_stage2(Column_definition * c,handler * file,ulonglong table_flags)2577   bool Column_definition_prepare_stage2(Column_definition *c,
2578                                         handler *file,
2579                                         ulonglong table_flags) const
2580   { return Column_definition_prepare_stage2_legacy_num(c, MYSQL_TYPE_YEAR); }
2581   Field *make_table_field(const LEX_CSTRING *name,
2582                           const Record_addr &addr,
2583                           const Type_all_attributes &attr,
2584                           TABLE *table) const;
2585   Item_cache *Item_get_cache(THD *thd, const Item *item) const;
2586   bool Item_get_date(Item *item, MYSQL_TIME *ltime, ulonglong fuzzydate) const;
2587 };
2588 
2589 
2590 class Type_handler_bit: public Type_handler_int_result
2591 {
2592   static const Name m_name_bit;
2593 public:
~Type_handler_bit()2594   virtual ~Type_handler_bit() {}
name()2595   const Name name() const { return m_name_bit; }
field_type()2596   enum_field_types field_type() const { return MYSQL_TYPE_BIT; }
2597   uint32 max_display_length(const Item *item) const;
calc_pack_length(uint32 length)2598   uint32 calc_pack_length(uint32 length) const { return length / 8; }
Item_send(Item * item,Protocol * protocol,st_value * buf)2599   bool Item_send(Item *item, Protocol *protocol, st_value *buf) const
2600   {
2601     return Item_send_str(item, protocol, buf);
2602   }
print_item_value(THD * thd,Item * item,String * str)2603   String *print_item_value(THD *thd, Item *item, String *str) const
2604   {
2605     return print_item_value_csstr(thd, item, str);
2606   }
2607   Field *make_conversion_table_field(TABLE *, uint metadata,
2608                                      const Field *target) const;
2609   bool Column_definition_fix_attributes(Column_definition *c) const;
2610   bool Column_definition_prepare_stage1(THD *thd,
2611                                         MEM_ROOT *mem_root,
2612                                         Column_definition *c,
2613                                         handler *file,
2614                                         ulonglong table_flags) const;
2615   bool Column_definition_redefine_stage1(Column_definition *def,
2616                                          const Column_definition *dup,
2617                                          const handler *file,
2618                                          const Schema_specification_st *schema)
2619                                          const;
2620   bool Column_definition_prepare_stage2(Column_definition *c,
2621                                         handler *file,
2622                                         ulonglong table_flags) const;
2623   Field *make_table_field(const LEX_CSTRING *name,
2624                           const Record_addr &addr,
2625                           const Type_all_attributes &attr,
2626                           TABLE *table) const;
2627   bool Vers_history_point_resolve_unit(THD *thd, Vers_history_point *p) const;
2628 };
2629 
2630 
2631 class Type_handler_float: public Type_handler_real_result
2632 {
2633   static const Name m_name_float;
2634 public:
~Type_handler_float()2635   virtual ~Type_handler_float() {}
name()2636   const Name name() const { return m_name_float; }
field_type()2637   enum_field_types field_type() const { return MYSQL_TYPE_FLOAT; }
type_can_have_auto_increment_attribute()2638   bool type_can_have_auto_increment_attribute() const { return true; }
max_display_length(const Item * item)2639   uint32 max_display_length(const Item *item) const { return 25; }
calc_pack_length(uint32 length)2640   uint32 calc_pack_length(uint32 length) const { return sizeof(float); }
2641   Item *create_typecast_item(THD *thd, Item *item,
2642                              const Type_cast_attributes &attr) const;
Item_send(Item * item,Protocol * protocol,st_value * buf)2643   bool Item_send(Item *item, Protocol *protocol, st_value *buf) const
2644   {
2645     return Item_send_float(item, protocol, buf);
2646   }
2647   Field *make_num_distinct_aggregator_field(MEM_ROOT *, const Item *) const;
2648   Field *make_conversion_table_field(TABLE *, uint metadata,
2649                                      const Field *target) const;
2650   bool Column_definition_fix_attributes(Column_definition *c) const;
Column_definition_prepare_stage2(Column_definition * c,handler * file,ulonglong table_flags)2651   bool Column_definition_prepare_stage2(Column_definition *c,
2652                                         handler *file,
2653                                         ulonglong table_flags) const
2654   { return Column_definition_prepare_stage2_legacy_real(c, MYSQL_TYPE_FLOAT); }
2655   Field *make_table_field(const LEX_CSTRING *name,
2656                           const Record_addr &addr,
2657                           const Type_all_attributes &attr,
2658                           TABLE *table) const;
2659   void Item_param_set_param_func(Item_param *param,
2660                                  uchar **pos, ulong len) const;
2661 
2662   Item_cache *Item_get_cache(THD *thd, const Item *item) const;
2663   String *Item_func_hybrid_field_type_val_str(Item_func_hybrid_field_type *,
2664                                               String *) const;
2665   String *Item_func_min_max_val_str(Item_func_min_max *, String *) const;
2666 };
2667 
2668 
2669 class Type_handler_double: public Type_handler_real_result
2670 {
2671   static const Name m_name_double;
2672 public:
~Type_handler_double()2673   virtual ~Type_handler_double() {}
name()2674   const Name name() const { return m_name_double; }
field_type()2675   enum_field_types field_type() const { return MYSQL_TYPE_DOUBLE; }
type_can_have_auto_increment_attribute()2676   bool type_can_have_auto_increment_attribute() const { return true; }
max_display_length(const Item * item)2677   uint32 max_display_length(const Item *item) const { return 53; }
calc_pack_length(uint32 length)2678   uint32 calc_pack_length(uint32 length) const { return sizeof(double); }
2679   Item *create_typecast_item(THD *thd, Item *item,
2680                              const Type_cast_attributes &attr) const;
Item_send(Item * item,Protocol * protocol,st_value * buf)2681   bool Item_send(Item *item, Protocol *protocol, st_value *buf) const
2682   {
2683     return Item_send_double(item, protocol, buf);
2684   }
2685   Field *make_conversion_table_field(TABLE *, uint metadata,
2686                                      const Field *target) const;
2687   bool Column_definition_fix_attributes(Column_definition *c) const;
Column_definition_prepare_stage2(Column_definition * c,handler * file,ulonglong table_flags)2688   bool Column_definition_prepare_stage2(Column_definition *c,
2689                                         handler *file,
2690                                         ulonglong table_flags) const
2691   { return Column_definition_prepare_stage2_legacy_real(c, MYSQL_TYPE_DOUBLE); }
2692   Field *make_table_field(const LEX_CSTRING *name,
2693                           const Record_addr &addr,
2694                           const Type_all_attributes &attr,
2695                           TABLE *table) const;
2696   void Item_param_set_param_func(Item_param *param,
2697                                  uchar **pos, ulong len) const;
2698 
2699   Item_cache *Item_get_cache(THD *thd, const Item *item) const;
2700   String *Item_func_hybrid_field_type_val_str(Item_func_hybrid_field_type *,
2701                                               String *) const;
2702   String *Item_func_min_max_val_str(Item_func_min_max *, String *) const;
2703 };
2704 
2705 
2706 class Type_handler_time_common: public Type_handler_temporal_result
2707 {
2708   static const Name m_name_time;
2709 public:
~Type_handler_time_common()2710   virtual ~Type_handler_time_common() { }
name()2711   const Name name() const { return m_name_time; }
field_type()2712   enum_field_types field_type() const { return MYSQL_TYPE_TIME; }
mysql_timestamp_type()2713   enum_mysql_timestamp_type mysql_timestamp_type() const
2714   {
2715     return MYSQL_TIMESTAMP_TIME;
2716   }
2717   Item *create_typecast_item(THD *thd, Item *item,
2718                              const Type_cast_attributes &attr) const;
Item_decimal_scale(const Item * item)2719   uint Item_decimal_scale(const Item *item) const
2720   {
2721     return Item_decimal_scale_with_seconds(item);
2722   }
2723   uint Item_decimal_precision(const Item *item) const;
Item_divisor_precision_increment(const Item * item)2724   uint Item_divisor_precision_increment(const Item *item) const
2725   {
2726     return Item_divisor_precision_increment_with_seconds(item);
2727   }
2728   const Type_handler *type_handler_for_comparison() const;
2729   bool Column_definition_fix_attributes(Column_definition *c) const;
2730   bool Item_save_in_value(Item *item, st_value *value) const;
Item_send(Item * item,Protocol * protocol,st_value * buf)2731   bool Item_send(Item *item, Protocol *protocol, st_value *buf) const
2732   {
2733     return Item_send_time(item, protocol, buf);
2734   }
2735   int Item_save_in_field(Item *item, Field *field, bool no_conversions) const;
2736   String *print_item_value(THD *thd, Item *item, String *str) const;
2737   Item_cache *Item_get_cache(THD *thd, const Item *item) const;
2738   bool Item_hybrid_func_fix_attributes(THD *thd,
2739                                        const char *name,
2740                                        Type_handler_hybrid_field_type *,
2741                                        Type_all_attributes *atrr,
2742                                        Item **items, uint nitems) const;
2743   String *Item_func_hybrid_field_type_val_str(Item_func_hybrid_field_type *,
2744                                               String *) const;
2745   double Item_func_hybrid_field_type_val_real(Item_func_hybrid_field_type *)
2746                                               const;
2747   longlong Item_func_hybrid_field_type_val_int(Item_func_hybrid_field_type *)
2748                                                const;
2749   my_decimal *Item_func_hybrid_field_type_val_decimal(
2750                                               Item_func_hybrid_field_type *,
2751                                               my_decimal *) const;
2752   bool Item_func_hybrid_field_type_get_date(Item_func_hybrid_field_type *,
2753                                             MYSQL_TIME *,
2754                                             ulonglong fuzzydate) const;
2755   bool Item_func_min_max_get_date(Item_func_min_max*,
2756                                   MYSQL_TIME *, ulonglong fuzzydate) const;
2757   Item *make_const_item_for_comparison(THD *, Item *src, const Item *cmp) const;
2758   bool set_comparator_func(Arg_comparator *cmp) const;
2759   cmp_item *make_cmp_item(THD *thd, CHARSET_INFO *cs) const;
2760   in_vector *make_in_vector(THD *, const Item_func_in *, uint nargs) const;
2761   void Item_param_set_param_func(Item_param *param,
2762                                  uchar **pos, ulong len) const;
2763 };
2764 
2765 
2766 class Type_handler_time: public Type_handler_time_common
2767 {
2768   /* number of bytes to store TIME(N) */
2769   static uint m_hires_bytes[MAX_DATETIME_PRECISION+1];
2770 public:
hires_bytes(uint dec)2771   static uint hires_bytes(uint dec) { return m_hires_bytes[dec]; }
~Type_handler_time()2772   virtual ~Type_handler_time() {}
2773   uint32 calc_pack_length(uint32 length) const;
2774   Field *make_conversion_table_field(TABLE *, uint metadata,
2775                                      const Field *target) const;
Column_definition_prepare_stage2(Column_definition * c,handler * file,ulonglong table_flags)2776   bool Column_definition_prepare_stage2(Column_definition *c,
2777                                         handler *file,
2778                                         ulonglong table_flags) const
2779   { return Column_definition_prepare_stage2_legacy(c, MYSQL_TYPE_TIME); }
2780   Field *make_table_field(const LEX_CSTRING *name,
2781                           const Record_addr &addr,
2782                           const Type_all_attributes &attr,
2783                           TABLE *table) const;
2784 };
2785 
2786 
2787 class Type_handler_time2: public Type_handler_time_common
2788 {
2789 public:
~Type_handler_time2()2790   virtual ~Type_handler_time2() {}
real_field_type()2791   enum_field_types real_field_type() const { return MYSQL_TYPE_TIME2; }
2792   uint32 calc_pack_length(uint32 length) const;
2793   Field *make_conversion_table_field(TABLE *, uint metadata,
2794                                      const Field *target) const;
Column_definition_prepare_stage2(Column_definition * c,handler * file,ulonglong table_flags)2795   bool Column_definition_prepare_stage2(Column_definition *c,
2796                                         handler *file,
2797                                         ulonglong table_flags) const
2798   { return Column_definition_prepare_stage2_legacy(c, MYSQL_TYPE_TIME2); }
2799   Field *make_table_field(const LEX_CSTRING *name,
2800                           const Record_addr &addr,
2801                           const Type_all_attributes &attr,
2802                           TABLE *table) const;
2803 };
2804 
2805 
2806 class Type_handler_temporal_with_date: public Type_handler_temporal_result
2807 {
2808 public:
~Type_handler_temporal_with_date()2809   virtual ~Type_handler_temporal_with_date() {}
2810   bool Item_save_in_value(Item *item, st_value *value) const;
Item_send(Item * item,Protocol * protocol,st_value * buf)2811   bool Item_send(Item *item, Protocol *protocol, st_value *buf) const
2812   {
2813     return Item_send_date(item, protocol, buf);
2814   }
2815   int Item_save_in_field(Item *item, Field *field, bool no_conversions) const;
2816   Item *make_const_item_for_comparison(THD *, Item *src, const Item *cmp) const;
2817   bool set_comparator_func(Arg_comparator *cmp) const;
2818   cmp_item *make_cmp_item(THD *thd, CHARSET_INFO *cs) const;
2819   in_vector *make_in_vector(THD *, const Item_func_in *, uint nargs) const;
2820 };
2821 
2822 
2823 class Type_handler_date_common: public Type_handler_temporal_with_date
2824 {
2825   static const Name m_name_date;
2826 public:
~Type_handler_date_common()2827   virtual ~Type_handler_date_common() {}
name()2828   const Name name() const { return m_name_date; }
2829   const Type_handler *type_handler_for_comparison() const;
field_type()2830   enum_field_types field_type() const { return MYSQL_TYPE_DATE; }
mysql_timestamp_type()2831   enum_mysql_timestamp_type mysql_timestamp_type() const
2832   {
2833     return MYSQL_TIMESTAMP_DATE;
2834   }
2835   Item *create_typecast_item(THD *thd, Item *item,
2836                              const Type_cast_attributes &attr) const;
2837   bool Column_definition_fix_attributes(Column_definition *c) const;
2838   uint Item_decimal_precision(const Item *item) const;
2839   String *print_item_value(THD *thd, Item *item, String *str) const;
2840   Item_cache *Item_get_cache(THD *thd, const Item *item) const;
2841   bool Item_hybrid_func_fix_attributes(THD *thd,
2842                                        const char *name,
2843                                        Type_handler_hybrid_field_type *,
2844                                        Type_all_attributes *atrr,
2845                                        Item **items, uint nitems) const;
2846   void Item_param_set_param_func(Item_param *param,
2847                                  uchar **pos, ulong len) const;
2848 };
2849 
2850 class Type_handler_date: public Type_handler_date_common
2851 {
2852 public:
~Type_handler_date()2853   virtual ~Type_handler_date() {}
calc_pack_length(uint32 length)2854   uint32 calc_pack_length(uint32 length) const { return 4; }
2855   Field *make_conversion_table_field(TABLE *, uint metadata,
2856                                      const Field *target) const;
Column_definition_prepare_stage2(Column_definition * c,handler * file,ulonglong table_flags)2857   bool Column_definition_prepare_stage2(Column_definition *c,
2858                                         handler *file,
2859                                         ulonglong table_flags) const
2860   { return Column_definition_prepare_stage2_legacy(c, MYSQL_TYPE_DATE); }
2861   Field *make_table_field(const LEX_CSTRING *name,
2862                           const Record_addr &addr,
2863                           const Type_all_attributes &attr,
2864                           TABLE *table) const;
2865 };
2866 
2867 
2868 class Type_handler_newdate: public Type_handler_date_common
2869 {
2870 public:
~Type_handler_newdate()2871   virtual ~Type_handler_newdate() {}
real_field_type()2872   enum_field_types real_field_type() const { return MYSQL_TYPE_NEWDATE; }
calc_pack_length(uint32 length)2873   uint32 calc_pack_length(uint32 length) const { return 3; }
2874   Field *make_conversion_table_field(TABLE *, uint metadata,
2875                                      const Field *target) const;
Column_definition_prepare_stage2(Column_definition * c,handler * file,ulonglong table_flags)2876   bool Column_definition_prepare_stage2(Column_definition *c,
2877                                         handler *file,
2878                                         ulonglong table_flags) const
2879   { return Column_definition_prepare_stage2_legacy(c, MYSQL_TYPE_NEWDATE); }
2880   Field *make_table_field(const LEX_CSTRING *name,
2881                           const Record_addr &addr,
2882                           const Type_all_attributes &attr,
2883                           TABLE *table) const;
2884 };
2885 
2886 
2887 class Type_handler_datetime_common: public Type_handler_temporal_with_date
2888 {
2889   static const Name m_name_datetime;
2890 public:
~Type_handler_datetime_common()2891   virtual ~Type_handler_datetime_common() {}
name()2892   const Name name() const { return m_name_datetime; }
2893   const Type_handler *type_handler_for_comparison() const;
field_type()2894   enum_field_types field_type() const { return MYSQL_TYPE_DATETIME; }
mysql_timestamp_type()2895   enum_mysql_timestamp_type mysql_timestamp_type() const
2896   {
2897     return MYSQL_TIMESTAMP_DATETIME;
2898   }
2899   Item *create_typecast_item(THD *thd, Item *item,
2900                              const Type_cast_attributes &attr) const;
2901   bool Column_definition_fix_attributes(Column_definition *c) const;
Item_decimal_scale(const Item * item)2902   uint Item_decimal_scale(const Item *item) const
2903   {
2904     return Item_decimal_scale_with_seconds(item);
2905   }
2906   uint Item_decimal_precision(const Item *item) const;
Item_divisor_precision_increment(const Item * item)2907   uint Item_divisor_precision_increment(const Item *item) const
2908   {
2909     return Item_divisor_precision_increment_with_seconds(item);
2910   }
Item_send(Item * item,Protocol * protocol,st_value * buf)2911   bool Item_send(Item *item, Protocol *protocol, st_value *buf) const
2912   {
2913     return Item_send_datetime(item, protocol, buf);
2914   }
2915   String *print_item_value(THD *thd, Item *item, String *str) const;
2916   Item_cache *Item_get_cache(THD *thd, const Item *item) const;
2917   bool Item_hybrid_func_fix_attributes(THD *thd,
2918                                        const char *name,
2919                                        Type_handler_hybrid_field_type *,
2920                                        Type_all_attributes *atrr,
2921                                        Item **items, uint nitems) const;
2922   void Item_param_set_param_func(Item_param *param,
2923                                  uchar **pos, ulong len) const;
2924 };
2925 
2926 
2927 class Type_handler_datetime: public Type_handler_datetime_common
2928 {
2929   /* number of bytes to store DATETIME(N) */
2930   static uint m_hires_bytes[MAX_DATETIME_PRECISION + 1];
2931 public:
hires_bytes(uint dec)2932   static uint hires_bytes(uint dec) { return m_hires_bytes[dec]; }
~Type_handler_datetime()2933   virtual ~Type_handler_datetime() {}
2934   uint32 calc_pack_length(uint32 length) const;
2935   Field *make_conversion_table_field(TABLE *, uint metadata,
2936                                      const Field *target) const;
Column_definition_prepare_stage2(Column_definition * c,handler * file,ulonglong table_flags)2937   bool Column_definition_prepare_stage2(Column_definition *c,
2938                                         handler *file,
2939                                         ulonglong table_flags) const
2940   { return Column_definition_prepare_stage2_legacy(c, MYSQL_TYPE_DATETIME); }
2941   Field *make_table_field(const LEX_CSTRING *name,
2942                           const Record_addr &addr,
2943                           const Type_all_attributes &attr,
2944                           TABLE *table) const;
2945 };
2946 
2947 
2948 class Type_handler_datetime2: public Type_handler_datetime_common
2949 {
2950 public:
~Type_handler_datetime2()2951   virtual ~Type_handler_datetime2() {}
real_field_type()2952   enum_field_types real_field_type() const { return MYSQL_TYPE_DATETIME2; }
2953   uint32 calc_pack_length(uint32 length) const;
2954   Field *make_conversion_table_field(TABLE *, uint metadata,
2955                                      const Field *target) const;
Column_definition_prepare_stage2(Column_definition * c,handler * file,ulonglong table_flags)2956   bool Column_definition_prepare_stage2(Column_definition *c,
2957                                         handler *file,
2958                                         ulonglong table_flags) const
2959   { return Column_definition_prepare_stage2_legacy(c, MYSQL_TYPE_DATETIME2); }
2960   Field *make_table_field(const LEX_CSTRING *name,
2961                           const Record_addr &addr,
2962                           const Type_all_attributes &attr,
2963                           TABLE *table) const;
2964 };
2965 
2966 
2967 class Type_handler_timestamp_common: public Type_handler_temporal_with_date
2968 {
2969   static const Name m_name_timestamp;
2970 public:
~Type_handler_timestamp_common()2971   virtual ~Type_handler_timestamp_common() {}
name()2972   const Name name() const { return m_name_timestamp; }
2973   const Type_handler *type_handler_for_comparison() const;
field_type()2974   enum_field_types field_type() const { return MYSQL_TYPE_TIMESTAMP; }
mysql_timestamp_type()2975   enum_mysql_timestamp_type mysql_timestamp_type() const
2976   {
2977     return MYSQL_TIMESTAMP_DATETIME;
2978   }
is_timestamp_type()2979   bool is_timestamp_type() const
2980   {
2981     return true;
2982   }
2983   bool Column_definition_fix_attributes(Column_definition *c) const;
Item_decimal_scale(const Item * item)2984   uint Item_decimal_scale(const Item *item) const
2985   {
2986     return Item_decimal_scale_with_seconds(item);
2987   }
2988   uint Item_decimal_precision(const Item *item) const;
Item_divisor_precision_increment(const Item * item)2989   uint Item_divisor_precision_increment(const Item *item) const
2990   {
2991     return Item_divisor_precision_increment_with_seconds(item);
2992   }
Item_send(Item * item,Protocol * protocol,st_value * buf)2993   bool Item_send(Item *item, Protocol *protocol, st_value *buf) const
2994   {
2995     return Item_send_datetime(item, protocol, buf);
2996   }
2997   String *print_item_value(THD *thd, Item *item, String *str) const;
2998   Item_cache *Item_get_cache(THD *thd, const Item *item) const;
2999   bool Item_hybrid_func_fix_attributes(THD *thd,
3000                                        const char *name,
3001                                        Type_handler_hybrid_field_type *,
3002                                        Type_all_attributes *atrr,
3003                                        Item **items, uint nitems) const;
3004   void Item_param_set_param_func(Item_param *param,
3005                                  uchar **pos, ulong len) const;
3006 };
3007 
3008 
3009 class Type_handler_timestamp: public Type_handler_timestamp_common
3010 {
3011   /* number of bytes to store second_part part of the TIMESTAMP(N) */
3012   static uint m_sec_part_bytes[MAX_DATETIME_PRECISION + 1];
3013 public:
sec_part_bytes(uint dec)3014   static uint sec_part_bytes(uint dec) { return m_sec_part_bytes[dec]; }
~Type_handler_timestamp()3015   virtual ~Type_handler_timestamp() {}
3016   uint32 calc_pack_length(uint32 length) const;
3017   Field *make_conversion_table_field(TABLE *, uint metadata,
3018                                      const Field *target) const;
Column_definition_prepare_stage2(Column_definition * c,handler * file,ulonglong table_flags)3019   bool Column_definition_prepare_stage2(Column_definition *c,
3020                                         handler *file,
3021                                         ulonglong table_flags) const
3022   { return Column_definition_prepare_stage2_legacy_num(c, MYSQL_TYPE_TIMESTAMP); }
3023   Field *make_table_field(const LEX_CSTRING *name,
3024                           const Record_addr &addr,
3025                           const Type_all_attributes &attr,
3026                           TABLE *table) const;
3027 };
3028 
3029 
3030 class Type_handler_timestamp2: public Type_handler_timestamp_common
3031 {
3032 public:
~Type_handler_timestamp2()3033   virtual ~Type_handler_timestamp2() {}
real_field_type()3034   enum_field_types real_field_type() const { return MYSQL_TYPE_TIMESTAMP2; }
3035   uint32 calc_pack_length(uint32 length) const;
3036   Field *make_conversion_table_field(TABLE *, uint metadata,
3037                                      const Field *target) const;
Column_definition_prepare_stage2(Column_definition * c,handler * file,ulonglong table_flags)3038   bool Column_definition_prepare_stage2(Column_definition *c,
3039                                         handler *file,
3040                                         ulonglong table_flags) const
3041   {
3042     return Column_definition_prepare_stage2_legacy_num(c, MYSQL_TYPE_TIMESTAMP2);
3043   }
3044   Field *make_table_field(const LEX_CSTRING *name,
3045                           const Record_addr &addr,
3046                           const Type_all_attributes &attr,
3047                           TABLE *table) const;
3048 };
3049 
3050 
3051 class Type_handler_olddecimal: public Type_handler_decimal_result
3052 {
3053   static const Name m_name_decimal;
3054 public:
~Type_handler_olddecimal()3055   virtual ~Type_handler_olddecimal() {}
name()3056   const Name name() const { return m_name_decimal; }
field_type()3057   enum_field_types field_type() const { return MYSQL_TYPE_DECIMAL; }
calc_pack_length(uint32 length)3058   uint32 calc_pack_length(uint32 length) const { return length; }
3059   const Type_handler *type_handler_for_tmp_table(const Item *item) const;
3060   const Type_handler *type_handler_for_union(const Item *item) const;
3061   Field *make_conversion_table_field(TABLE *, uint metadata,
3062                                      const Field *target) const;
3063   bool Column_definition_fix_attributes(Column_definition *c) const;
Column_definition_prepare_stage2(Column_definition * c,handler * file,ulonglong table_flags)3064   bool Column_definition_prepare_stage2(Column_definition *c,
3065                                         handler *file,
3066                                         ulonglong table_flags) const
3067   { return Column_definition_prepare_stage2_legacy_num(c, MYSQL_TYPE_DECIMAL); }
3068   Field *make_table_field(const LEX_CSTRING *name,
3069                           const Record_addr &addr,
3070                           const Type_all_attributes &attr,
3071                           TABLE *table) const;
3072 };
3073 
3074 
3075 class Type_handler_newdecimal: public Type_handler_decimal_result
3076 {
3077   static const Name m_name_decimal;
3078 public:
~Type_handler_newdecimal()3079   virtual ~Type_handler_newdecimal() {}
name()3080   const Name name() const { return m_name_decimal; }
field_type()3081   enum_field_types field_type() const { return MYSQL_TYPE_NEWDECIMAL; }
3082   uint32 calc_pack_length(uint32 length) const;
3083   Field *make_conversion_table_field(TABLE *, uint metadata,
3084                                      const Field *target) const;
3085   bool Column_definition_fix_attributes(Column_definition *c) const;
3086   bool Column_definition_prepare_stage1(THD *thd,
3087                                         MEM_ROOT *mem_root,
3088                                         Column_definition *c,
3089                                         handler *file,
3090                                         ulonglong table_flags) const;
3091   bool Column_definition_redefine_stage1(Column_definition *def,
3092                                          const Column_definition *dup,
3093                                          const handler *file,
3094                                          const Schema_specification_st *schema)
3095                                          const;
3096   bool Column_definition_prepare_stage2(Column_definition *c,
3097                                         handler *file,
3098                                         ulonglong table_flags) const;
3099   Field *make_table_field(const LEX_CSTRING *name,
3100                           const Record_addr &addr,
3101                           const Type_all_attributes &attr,
3102                           TABLE *table) const;
3103 };
3104 
3105 
3106 class Type_handler_null: public Type_handler_general_purpose_string
3107 {
3108   static const Name m_name_null;
3109 public:
~Type_handler_null()3110   virtual ~Type_handler_null() {}
name()3111   const Name name() const { return m_name_null; }
field_type()3112   enum_field_types field_type() const { return MYSQL_TYPE_NULL; }
3113   const Type_handler *type_handler_for_comparison() const;
3114   const Type_handler *type_handler_for_tmp_table(const Item *item) const;
3115   const Type_handler *type_handler_for_union(const Item *) const;
max_display_length(const Item * item)3116   uint32 max_display_length(const Item *item) const { return 0; }
calc_pack_length(uint32 length)3117   uint32 calc_pack_length(uint32 length) const { return 0; }
3118   bool Item_save_in_value(Item *item, st_value *value) const;
3119   bool Item_send(Item *item, Protocol *protocol, st_value *buf) const;
3120   Field *make_conversion_table_field(TABLE *, uint metadata,
3121                                      const Field *target) const;
3122   bool union_element_finalize(Item_type_holder *item) const;
3123   bool Column_definition_fix_attributes(Column_definition *c) const;
3124   bool Column_definition_prepare_stage1(THD *thd,
3125                                         MEM_ROOT *mem_root,
3126                                         Column_definition *c,
3127                                         handler *file,
3128                                         ulonglong table_flags) const;
3129   bool Column_definition_redefine_stage1(Column_definition *def,
3130                                          const Column_definition *dup,
3131                                          const handler *file,
3132                                          const Schema_specification_st *schema)
3133                                          const;
Column_definition_prepare_stage2(Column_definition * c,handler * file,ulonglong table_flags)3134   bool Column_definition_prepare_stage2(Column_definition *c,
3135                                         handler *file,
3136                                         ulonglong table_flags) const
3137   { return Column_definition_prepare_stage2_legacy(c, MYSQL_TYPE_NULL); }
3138   Field *make_table_field(const LEX_CSTRING *name,
3139                           const Record_addr &addr,
3140                           const Type_all_attributes &attr,
3141                           TABLE *table) const;
3142 };
3143 
3144 
3145 class Type_handler_longstr: public Type_handler_general_purpose_string
3146 {
3147 public:
type_can_have_key_part()3148   bool type_can_have_key_part() const
3149   {
3150     return true;
3151   }
3152 };
3153 
3154 
3155 class Type_handler_string: public Type_handler_longstr
3156 {
3157   static const Name m_name_char;
3158 public:
~Type_handler_string()3159   virtual ~Type_handler_string() {}
name()3160   const Name name() const { return m_name_char; }
field_type()3161   enum_field_types field_type() const { return MYSQL_TYPE_STRING; }
is_param_long_data_type()3162   bool is_param_long_data_type() const { return true; }
calc_pack_length(uint32 length)3163   uint32 calc_pack_length(uint32 length) const { return length; }
type_handler_for_tmp_table(const Item * item)3164   const Type_handler *type_handler_for_tmp_table(const Item *item) const
3165   {
3166     return varstring_type_handler(item);
3167   }
3168   Field *make_conversion_table_field(TABLE *, uint metadata,
3169                                      const Field *target) const;
3170   bool Column_definition_fix_attributes(Column_definition *c) const;
3171   bool Column_definition_prepare_stage2(Column_definition *c,
3172                                         handler *file,
3173                                         ulonglong table_flags) const;
3174   Field *make_table_field(const LEX_CSTRING *name,
3175                           const Record_addr &addr,
3176                           const Type_all_attributes &attr,
3177                           TABLE *table) const;
3178 };
3179 
3180 
3181 /* Old varchar */
3182 class Type_handler_var_string: public Type_handler_string
3183 {
3184   static const Name m_name_var_string;
3185 public:
~Type_handler_var_string()3186   virtual ~Type_handler_var_string() {}
name()3187   const Name name() const { return m_name_var_string; }
field_type()3188   enum_field_types field_type() const { return MYSQL_TYPE_VAR_STRING; }
real_field_type()3189   enum_field_types real_field_type() const { return MYSQL_TYPE_STRING; }
type_handler_for_tmp_table(const Item * item)3190   const Type_handler *type_handler_for_tmp_table(const Item *item) const
3191   {
3192     return varstring_type_handler(item);
3193   }
3194   bool Column_definition_fix_attributes(Column_definition *c) const;
Column_definition_prepare_stage2(Column_definition * c,handler * file,ulonglong table_flags)3195   bool Column_definition_prepare_stage2(Column_definition *c,
3196                                         handler *file,
3197                                         ulonglong table_flags) const
3198   { return Column_definition_prepare_stage2_legacy_num(c, MYSQL_TYPE_STRING); }
type_handler_for_union(const Item * item)3199   const Type_handler *type_handler_for_union(const Item *item) const
3200   {
3201     return varstring_type_handler(item);
3202   }
3203 };
3204 
3205 
3206 class Type_handler_varchar: public Type_handler_longstr
3207 {
3208   static const Name m_name_varchar;
3209 public:
~Type_handler_varchar()3210   virtual ~Type_handler_varchar() {}
name()3211   const Name name() const { return m_name_varchar; }
field_type()3212   enum_field_types field_type() const { return MYSQL_TYPE_VARCHAR; }
calc_pack_length(uint32 length)3213   uint32 calc_pack_length(uint32 length) const
3214   {
3215     return (length + (length < 256 ? 1: 2));
3216   }
type_handler_for_tmp_table(const Item * item)3217   const Type_handler *type_handler_for_tmp_table(const Item *item) const
3218   {
3219     return varstring_type_handler(item);
3220   }
type_handler_for_union(const Item * item)3221   const Type_handler *type_handler_for_union(const Item *item) const
3222   {
3223     return varstring_type_handler(item);
3224   }
is_param_long_data_type()3225   bool is_param_long_data_type() const { return true; }
3226   Field *make_conversion_table_field(TABLE *, uint metadata,
3227                                      const Field *target) const;
3228   bool Column_definition_fix_attributes(Column_definition *c) const;
3229   bool Column_definition_prepare_stage2(Column_definition *c,
3230                                         handler *file,
3231                                         ulonglong table_flags) const;
3232   Field *make_table_field(const LEX_CSTRING *name,
3233                           const Record_addr &addr,
3234                           const Type_all_attributes &attr,
3235                           TABLE *table) const;
3236   bool adjust_spparam_type(Spvar_definition *def, Item *from) const;
3237 };
3238 
3239 
3240 class Type_handler_varchar_compressed: public Type_handler_varchar
3241 {
3242 public:
3243   Field *make_conversion_table_field(TABLE *, uint metadata,
3244                                      const Field *target) const;
3245 };
3246 
3247 
3248 class Type_handler_blob_common: public Type_handler_longstr
3249 {
3250 public:
~Type_handler_blob_common()3251   virtual ~Type_handler_blob_common() { }
3252   Field *make_conversion_table_field(TABLE *, uint metadata,
3253                                      const Field *target) const;
type_handler_for_tmp_table(const Item * item)3254   const Type_handler *type_handler_for_tmp_table(const Item *item) const
3255   {
3256     return blob_type_handler(item);
3257   }
type_handler_for_union(const Item * item)3258   const Type_handler *type_handler_for_union(const Item *item) const
3259   {
3260     return blob_type_handler(item);
3261   }
subquery_type_allows_materialization(const Item * inner,const Item * outer,bool is_in_predicate)3262   bool subquery_type_allows_materialization(const Item *inner,
3263                                             const Item *outer,
3264                                             bool is_in_predicate) const
3265   {
3266     return false; // Materialization does not work with BLOB columns
3267   }
is_param_long_data_type()3268   bool is_param_long_data_type() const { return true; }
3269   bool Column_definition_fix_attributes(Column_definition *c) const;
3270   bool Column_definition_prepare_stage2(Column_definition *c,
3271                                         handler *file,
3272                                         ulonglong table_flags) const;
3273   bool Item_hybrid_func_fix_attributes(THD *thd,
3274                                        const char *name,
3275                                        Type_handler_hybrid_field_type *,
3276                                        Type_all_attributes *atrr,
3277                                        Item **items, uint nitems) const;
3278   void Item_param_setup_conversion(THD *thd, Item_param *) const;
3279 
3280 };
3281 
3282 
3283 class Type_handler_tiny_blob: public Type_handler_blob_common
3284 {
3285   static const Name m_name_tinyblob;
3286 public:
~Type_handler_tiny_blob()3287   virtual ~Type_handler_tiny_blob() {}
name()3288   const Name name() const { return m_name_tinyblob; }
field_type()3289   enum_field_types field_type() const { return MYSQL_TYPE_TINY_BLOB; }
3290   uint32 calc_pack_length(uint32 length) const;
3291   Field *make_table_field(const LEX_CSTRING *name,
3292                           const Record_addr &addr,
3293                           const Type_all_attributes &attr,
3294                           TABLE *table) const;
3295 };
3296 
3297 
3298 class Type_handler_medium_blob: public Type_handler_blob_common
3299 {
3300   static const Name m_name_mediumblob;
3301 public:
~Type_handler_medium_blob()3302   virtual ~Type_handler_medium_blob() {}
name()3303   const Name name() const { return m_name_mediumblob; }
field_type()3304   enum_field_types field_type() const { return MYSQL_TYPE_MEDIUM_BLOB; }
3305   uint32 calc_pack_length(uint32 length) const;
3306   Field *make_table_field(const LEX_CSTRING *name,
3307                           const Record_addr &addr,
3308                           const Type_all_attributes &attr,
3309                           TABLE *table) const;
3310 };
3311 
3312 
3313 class Type_handler_long_blob: public Type_handler_blob_common
3314 {
3315   static const Name m_name_longblob;
3316 public:
~Type_handler_long_blob()3317   virtual ~Type_handler_long_blob() {}
name()3318   const Name name() const { return m_name_longblob; }
field_type()3319   enum_field_types field_type() const { return MYSQL_TYPE_LONG_BLOB; }
3320   uint32 calc_pack_length(uint32 length) const;
3321   Item *create_typecast_item(THD *thd, Item *item,
3322                              const Type_cast_attributes &attr) const;
3323   Field *make_table_field(const LEX_CSTRING *name,
3324                           const Record_addr &addr,
3325                           const Type_all_attributes &attr,
3326                           TABLE *table) const;
3327 };
3328 
3329 
3330 class Type_handler_blob: public Type_handler_blob_common
3331 {
3332   static const Name m_name_blob;
3333 public:
~Type_handler_blob()3334   virtual ~Type_handler_blob() {}
name()3335   const Name name() const { return m_name_blob; }
field_type()3336   enum_field_types field_type() const { return MYSQL_TYPE_BLOB; }
3337   uint32 calc_pack_length(uint32 length) const;
3338   Field *make_table_field(const LEX_CSTRING *name,
3339                           const Record_addr &addr,
3340                           const Type_all_attributes &attr,
3341                           TABLE *table) const;
3342 };
3343 
3344 
3345 class Type_handler_blob_compressed: public Type_handler_blob
3346 {
3347 public:
3348   Field *make_conversion_table_field(TABLE *, uint metadata,
3349                                      const Field *target) const;
3350 };
3351 
3352 
3353 #ifdef HAVE_SPATIAL
3354 class Type_handler_geometry: public Type_handler_string_result
3355 {
3356   static const Name m_name_geometry;
3357 public:
~Type_handler_geometry()3358   virtual ~Type_handler_geometry() {}
name()3359   const Name name() const { return m_name_geometry; }
field_type()3360   enum_field_types field_type() const { return MYSQL_TYPE_GEOMETRY; }
is_param_long_data_type()3361   bool is_param_long_data_type() const { return true; }
3362   uint32 calc_pack_length(uint32 length) const;
3363   const Type_handler *type_handler_for_comparison() const;
type_can_have_key_part()3364   bool type_can_have_key_part() const
3365   {
3366     return true;
3367   }
subquery_type_allows_materialization(const Item * inner,const Item * outer,bool is_in_predicate)3368   bool subquery_type_allows_materialization(const Item *inner,
3369                                             const Item *outer,
3370                                             bool is_in_predicate) const
3371   {
3372     return false; // Materialization does not work with GEOMETRY columns
3373   }
3374   void Item_param_set_param_func(Item_param *param,
3375                                  uchar **pos, ulong len) const;
3376   bool Item_param_set_from_value(THD *thd,
3377                                  Item_param *param,
3378                                  const Type_all_attributes *attr,
3379                                  const st_value *value) const;
3380   Field *make_conversion_table_field(TABLE *, uint metadata,
3381                                      const Field *target) const;
3382   bool Column_definition_fix_attributes(Column_definition *c) const;
3383   bool Column_definition_prepare_stage1(THD *thd,
3384                                         MEM_ROOT *mem_root,
3385                                         Column_definition *c,
3386                                         handler *file,
3387                                         ulonglong table_flags) const;
3388   bool Column_definition_prepare_stage2(Column_definition *c,
3389                                         handler *file,
3390                                         ulonglong table_flags) const;
3391   Field *make_table_field(const LEX_CSTRING *name,
3392                           const Record_addr &addr,
3393                           const Type_all_attributes &attr,
3394                           TABLE *table) const;
3395 
can_return_int()3396   bool can_return_int() const { return false; }
can_return_decimal()3397   bool can_return_decimal() const { return false; }
can_return_real()3398   bool can_return_real() const { return false; }
can_return_text()3399   bool can_return_text() const { return false; }
can_return_date()3400   bool can_return_date() const { return false; }
can_return_time()3401   bool can_return_time() const { return false; }
is_traditional_type()3402   bool is_traditional_type() const
3403   {
3404     return false;
3405   }
3406   bool Item_func_round_fix_length_and_dec(Item_func_round *) const;
3407   bool Item_func_int_val_fix_length_and_dec(Item_func_int_val *) const;
3408   bool Item_func_abs_fix_length_and_dec(Item_func_abs *) const;
3409   bool Item_func_neg_fix_length_and_dec(Item_func_neg *) const;
3410   bool Item_hybrid_func_fix_attributes(THD *thd,
3411                                        const char *name,
3412                                        Type_handler_hybrid_field_type *h,
3413                                        Type_all_attributes *attr,
3414                                        Item **items, uint nitems) const;
3415   bool Item_sum_sum_fix_length_and_dec(Item_sum_sum *) const;
3416   bool Item_sum_avg_fix_length_and_dec(Item_sum_avg *) const;
3417   bool Item_sum_variance_fix_length_and_dec(Item_sum_variance *) const;
3418 
3419   bool Item_func_signed_fix_length_and_dec(Item_func_signed *) const;
3420   bool Item_func_unsigned_fix_length_and_dec(Item_func_unsigned *) const;
3421   bool Item_double_typecast_fix_length_and_dec(Item_double_typecast *) const;
3422   bool Item_float_typecast_fix_length_and_dec(Item_float_typecast *) const;
3423   bool Item_decimal_typecast_fix_length_and_dec(Item_decimal_typecast *) const;
3424   bool Item_char_typecast_fix_length_and_dec(Item_char_typecast *) const;
3425   bool Item_time_typecast_fix_length_and_dec(Item_time_typecast *) const;
3426   bool Item_date_typecast_fix_length_and_dec(Item_date_typecast *) const;
3427   bool Item_datetime_typecast_fix_length_and_dec(Item_datetime_typecast *) const;
3428 };
3429 
3430 extern MYSQL_PLUGIN_IMPORT Type_handler_geometry type_handler_geometry;
3431 #endif
3432 
3433 
3434 class Type_handler_typelib: public Type_handler_general_purpose_string
3435 {
3436 public:
~Type_handler_typelib()3437   virtual ~Type_handler_typelib() { }
field_type()3438   enum_field_types field_type() const { return MYSQL_TYPE_STRING; }
3439   const Type_handler *type_handler_for_item_field() const;
3440   const Type_handler *cast_to_int_type_handler() const;
3441   bool Item_hybrid_func_fix_attributes(THD *thd,
3442                                        const char *name,
3443                                        Type_handler_hybrid_field_type *,
3444                                        Type_all_attributes *atrr,
3445                                        Item **items, uint nitems) const;
3446   bool Column_definition_prepare_stage1(THD *thd,
3447                                         MEM_ROOT *mem_root,
3448                                         Column_definition *c,
3449                                         handler *file,
3450                                         ulonglong table_flags) const;
3451   bool Column_definition_redefine_stage1(Column_definition *def,
3452                                          const Column_definition *dup,
3453                                          const handler *file,
3454                                          const Schema_specification_st *schema)
3455                                          const;
3456   void Item_param_set_param_func(Item_param *param,
3457                                  uchar **pos, ulong len) const;
3458   bool Vers_history_point_resolve_unit(THD *thd, Vers_history_point *p) const;
3459 };
3460 
3461 
3462 class Type_handler_enum: public Type_handler_typelib
3463 {
3464   static const Name m_name_enum;
3465 public:
~Type_handler_enum()3466   virtual ~Type_handler_enum() {}
name()3467   const Name name() const { return m_name_enum; }
real_field_type()3468   virtual enum_field_types real_field_type() const { return MYSQL_TYPE_ENUM; }
3469   uint32 calc_pack_length(uint32 length) const;
3470   Field *make_conversion_table_field(TABLE *, uint metadata,
3471                                      const Field *target) const;
3472   bool Column_definition_fix_attributes(Column_definition *c) const;
3473   bool Column_definition_prepare_stage2(Column_definition *c,
3474                                         handler *file,
3475                                         ulonglong table_flags) const;
3476   Field *make_table_field(const LEX_CSTRING *name,
3477                           const Record_addr &addr,
3478                           const Type_all_attributes &attr,
3479                           TABLE *table) const;
3480 };
3481 
3482 
3483 class Type_handler_set: public Type_handler_typelib
3484 {
3485   static const Name m_name_set;
3486 public:
~Type_handler_set()3487   virtual ~Type_handler_set() {}
name()3488   const Name name() const { return m_name_set; }
real_field_type()3489   virtual enum_field_types real_field_type() const { return MYSQL_TYPE_SET; }
3490   uint32 calc_pack_length(uint32 length) const;
3491   Field *make_conversion_table_field(TABLE *, uint metadata,
3492                                      const Field *target) const;
3493   bool Column_definition_fix_attributes(Column_definition *c) const;
3494   bool Column_definition_prepare_stage2(Column_definition *c,
3495                                         handler *file,
3496                                         ulonglong table_flags) const;
3497   Field *make_table_field(const LEX_CSTRING *name,
3498                           const Record_addr &addr,
3499                           const Type_all_attributes &attr,
3500                           TABLE *table) const;
3501 };
3502 
3503 
3504 /**
3505   A handler for hybrid type functions, e.g.
3506   COALESCE(), IF(), IFNULL(), NULLIF(), CASE,
3507   numeric operators,
3508   UNIX_TIMESTAMP(), TIME_TO_SEC().
3509 
3510   Makes sure that field_type(), cmp_type() and result_type()
3511   are always in sync to each other for hybrid functions.
3512 */
3513 class Type_handler_hybrid_field_type
3514 {
3515   const Type_handler *m_type_handler;
3516   bool aggregate_for_min_max(const Type_handler *other);
3517 
3518 public:
3519   Type_handler_hybrid_field_type();
Type_handler_hybrid_field_type(const Type_handler * handler)3520   Type_handler_hybrid_field_type(const Type_handler *handler)
3521    :m_type_handler(handler)
3522   { }
Type_handler_hybrid_field_type(const Type_handler_hybrid_field_type * other)3523   Type_handler_hybrid_field_type(const Type_handler_hybrid_field_type *other)
3524     :m_type_handler(other->m_type_handler)
3525   { }
swap(Type_handler_hybrid_field_type & other)3526   void swap(Type_handler_hybrid_field_type &other)
3527   {
3528     swap_variables(const Type_handler *, m_type_handler, other.m_type_handler);
3529   }
type_handler()3530   const Type_handler *type_handler() const { return m_type_handler; }
real_field_type()3531   enum_field_types real_field_type() const
3532   {
3533     return m_type_handler->real_field_type();
3534   }
cmp_type()3535   Item_result cmp_type() const { return m_type_handler->cmp_type(); }
mysql_timestamp_type()3536   enum_mysql_timestamp_type mysql_timestamp_type() const
3537   {
3538     return m_type_handler->mysql_timestamp_type();
3539   }
is_timestamp_type()3540   bool is_timestamp_type() const
3541   {
3542     return m_type_handler->is_timestamp_type();
3543   }
set_handler(const Type_handler * other)3544   void set_handler(const Type_handler *other)
3545   {
3546     m_type_handler= other;
3547   }
set_handler_by_result_type(Item_result type)3548   const Type_handler *set_handler_by_result_type(Item_result type)
3549   {
3550     return (m_type_handler= Type_handler::get_handler_by_result_type(type));
3551   }
set_handler_by_result_type(Item_result type,uint max_octet_length,CHARSET_INFO * cs)3552   const Type_handler *set_handler_by_result_type(Item_result type,
3553                                                  uint max_octet_length,
3554                                                  CHARSET_INFO *cs)
3555   {
3556     m_type_handler= Type_handler::get_handler_by_result_type(type);
3557     return m_type_handler=
3558       m_type_handler->type_handler_adjusted_to_max_octet_length(max_octet_length,
3559                                                                 cs);
3560   }
set_handler_by_field_type(enum_field_types type)3561   const Type_handler *set_handler_by_field_type(enum_field_types type)
3562   {
3563     return (m_type_handler= Type_handler::get_handler_by_field_type(type));
3564   }
set_handler_by_real_type(enum_field_types type)3565   const Type_handler *set_handler_by_real_type(enum_field_types type)
3566   {
3567     return (m_type_handler= Type_handler::get_handler_by_real_type(type));
3568   }
3569   bool aggregate_for_comparison(const Type_handler *other);
3570   bool aggregate_for_comparison(const char *funcname,
3571                                 Item **items, uint nitems,
3572                                 bool treat_int_to_uint_as_decimal);
3573   bool aggregate_for_result(const Type_handler *other);
3574   bool aggregate_for_result(const char *funcname,
3575                             Item **item, uint nitems, bool treat_bit_as_number);
3576   bool aggregate_for_min_max(const char *funcname, Item **item, uint nitems);
3577 
3578   bool aggregate_for_num_op(const class Type_aggregator *aggregator,
3579                             const Type_handler *h0, const Type_handler *h1);
3580 };
3581 
3582 
3583 extern MYSQL_PLUGIN_IMPORT Type_handler_row         type_handler_row;
3584 extern MYSQL_PLUGIN_IMPORT Type_handler_null        type_handler_null;
3585 
3586 extern MYSQL_PLUGIN_IMPORT Type_handler_float       type_handler_float;
3587 extern MYSQL_PLUGIN_IMPORT Type_handler_double      type_handler_double;
3588 
3589 extern MYSQL_PLUGIN_IMPORT Type_handler_bit         type_handler_bit;
3590 
3591 extern MYSQL_PLUGIN_IMPORT Type_handler_enum        type_handler_enum;
3592 extern MYSQL_PLUGIN_IMPORT Type_handler_set         type_handler_set;
3593 
3594 extern MYSQL_PLUGIN_IMPORT Type_handler_string      type_handler_string;
3595 extern MYSQL_PLUGIN_IMPORT Type_handler_var_string  type_handler_var_string;
3596 extern MYSQL_PLUGIN_IMPORT Type_handler_varchar     type_handler_varchar;
3597 
3598 extern MYSQL_PLUGIN_IMPORT Type_handler_tiny_blob   type_handler_tiny_blob;
3599 extern MYSQL_PLUGIN_IMPORT Type_handler_medium_blob type_handler_medium_blob;
3600 extern MYSQL_PLUGIN_IMPORT Type_handler_long_blob   type_handler_long_blob;
3601 extern MYSQL_PLUGIN_IMPORT Type_handler_blob        type_handler_blob;
3602 
3603 extern MYSQL_PLUGIN_IMPORT Type_handler_tiny        type_handler_tiny;
3604 extern MYSQL_PLUGIN_IMPORT Type_handler_short       type_handler_short;
3605 extern MYSQL_PLUGIN_IMPORT Type_handler_int24       type_handler_int24;
3606 extern MYSQL_PLUGIN_IMPORT Type_handler_long        type_handler_long;
3607 extern MYSQL_PLUGIN_IMPORT Type_handler_longlong    type_handler_longlong;
3608 extern MYSQL_PLUGIN_IMPORT Type_handler_longlong    type_handler_ulonglong;
3609 extern MYSQL_PLUGIN_IMPORT Type_handler_vers_trx_id type_handler_vers_trx_id;
3610 
3611 extern MYSQL_PLUGIN_IMPORT Type_handler_newdecimal  type_handler_newdecimal;
3612 extern MYSQL_PLUGIN_IMPORT Type_handler_olddecimal  type_handler_olddecimal;
3613 
3614 extern MYSQL_PLUGIN_IMPORT Type_handler_year        type_handler_year;
3615 extern MYSQL_PLUGIN_IMPORT Type_handler_newdate     type_handler_newdate;
3616 extern MYSQL_PLUGIN_IMPORT Type_handler_date        type_handler_date;
3617 extern MYSQL_PLUGIN_IMPORT Type_handler_time        type_handler_time;
3618 extern MYSQL_PLUGIN_IMPORT Type_handler_time2       type_handler_time2;
3619 extern MYSQL_PLUGIN_IMPORT Type_handler_datetime    type_handler_datetime;
3620 extern MYSQL_PLUGIN_IMPORT Type_handler_datetime2   type_handler_datetime2;
3621 extern MYSQL_PLUGIN_IMPORT Type_handler_timestamp   type_handler_timestamp;
3622 extern MYSQL_PLUGIN_IMPORT Type_handler_timestamp2  type_handler_timestamp2;
3623 
3624 extern MYSQL_PLUGIN_IMPORT Type_handler_tiny_blob   type_handler_tiny_blob;
3625 extern MYSQL_PLUGIN_IMPORT Type_handler_blob        type_handler_blob;
3626 extern MYSQL_PLUGIN_IMPORT Type_handler_medium_blob type_handler_medium_blob;
3627 extern MYSQL_PLUGIN_IMPORT Type_handler_long_blob   type_handler_long_blob;
3628 
3629 class Type_aggregator
3630 {
3631   bool m_is_commutative;
3632   class Pair
3633   {
3634   public:
3635     const Type_handler *m_handler1;
3636     const Type_handler *m_handler2;
3637     const Type_handler *m_result;
Pair()3638     Pair() { }
Pair(const Type_handler * handler1,const Type_handler * handler2,const Type_handler * result)3639     Pair(const Type_handler *handler1,
3640          const Type_handler *handler2,
3641          const Type_handler *result)
3642      :m_handler1(handler1), m_handler2(handler2), m_result(result)
3643     { }
eq(const Type_handler * handler1,const Type_handler * handler2)3644     bool eq(const Type_handler *handler1, const Type_handler *handler2) const
3645     {
3646       return m_handler1 == handler1 && m_handler2 == handler2;
3647     }
3648   };
3649   Dynamic_array<Pair> m_array;
3650   const Pair* find_pair(const Type_handler *handler1,
3651                         const Type_handler *handler2) const;
3652 public:
3653   Type_aggregator(bool is_commutative= false)
m_is_commutative(is_commutative)3654    :m_is_commutative(is_commutative)
3655   { }
add(const Type_handler * handler1,const Type_handler * handler2,const Type_handler * result)3656   bool add(const Type_handler *handler1,
3657            const Type_handler *handler2,
3658            const Type_handler *result)
3659   {
3660     return m_array.append(Pair(handler1, handler2, result));
3661   }
find_handler(const Type_handler * handler1,const Type_handler * handler2)3662   const Type_handler *find_handler(const Type_handler *handler1,
3663                                    const Type_handler *handler2) const
3664   {
3665     const Pair* el= find_pair(handler1, handler2);
3666     return el ? el->m_result : NULL;
3667   }
is_commutative()3668   bool is_commutative() const { return m_is_commutative; }
3669 };
3670 
3671 
3672 class Type_aggregator_commutative: public Type_aggregator
3673 {
3674 public:
Type_aggregator_commutative()3675   Type_aggregator_commutative()
3676    :Type_aggregator(true)
3677   { }
3678 };
3679 
3680 
3681 class Type_handler_data
3682 {
3683 public:
3684   Type_aggregator_commutative m_type_aggregator_for_result;
3685   Type_aggregator_commutative m_type_aggregator_for_comparison;
3686 
3687   Type_aggregator_commutative m_type_aggregator_for_plus;
3688   Type_aggregator_commutative m_type_aggregator_for_mul;
3689 
3690   Type_aggregator m_type_aggregator_for_minus;
3691   Type_aggregator m_type_aggregator_for_div;
3692   Type_aggregator m_type_aggregator_for_mod;
3693 #ifndef DBUG_OFF
3694   // This is used for mtr purposes in debug builds
3695   Type_aggregator m_type_aggregator_non_commutative_test;
3696 #endif
3697   bool init();
3698 };
3699 
3700 
3701 extern Type_handler_data *type_handler_data;
3702 
3703 #endif /* SQL_TYPE_H_INCLUDED */
3704