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