1 /* Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved.
2 
3    This program is free software; you can redistribute it and/or modify
4    it under the terms of the GNU General Public License, version 2.0,
5    as published by the Free Software Foundation.
6 
7    This program is also distributed with certain software (including
8    but not limited to OpenSSL) that is licensed under separate terms,
9    as designated in a particular file or component or in included license
10    documentation.  The authors of MySQL hereby grant you an additional
11    permission to link the program and your derivative works with the
12    separately licensed software that they have included with MySQL.
13 
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License, version 2.0, for more details.
18 
19    You should have received a copy of the GNU General Public License
20    along with this program; if not, write to the Free Software
21    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA */
22 
23 #include "sql/create_field.h"
24 
25 #include "sql/derror.h"
26 #include "sql/field.h"
27 #include "sql/item.h"
28 #include "sql/my_decimal.h"
29 #include "sql/sql_class.h"
30 #include "sql_string.h"
31 #include "template_utils.h"
32 
33 #include <cmath>
34 
35 // Definition of static constexpr data members in Create_field.
36 constexpr size_t Create_field::TINYBLOB_MAX_SIZE_IN_BYTES;
37 constexpr size_t Create_field::BLOB_MAX_SIZE_IN_BYTES;
38 constexpr size_t Create_field::MEDIUMBLOB_MAX_SIZE_IN_BYTES;
39 constexpr size_t Create_field::LONGBLOB_MAX_SIZE_IN_BYTES;
40 
41 /**
42     Constructs a column definition from an object representing an actual
43     column. This is a reverse-engineering procedure that creates a column
44     definition object as produced by the parser (Create_field) from a resolved
45     column object (Field).
46 
47     @param old_field  The column object from which the column definition is
48                       constructed.
49     @param orig_field Used for copying default values. This parameter may be
50                       NULL, but if present it is used for copying default
51                       values.
52 
53     Default values are copied into an Item_string unless:
54     - The default value is a function.
55     - There is no default value.
56     - old_field is a BLOB column.
57     - old_field has its data pointer improperly initialized.
58 */
Create_field(Field * old_field,Field * orig_field)59 Create_field::Create_field(Field *old_field, Field *orig_field)
60     : hidden(old_field->hidden()),
61       field_name(old_field->field_name),
62       change(nullptr),
63       comment(old_field->comment),
64       sql_type(old_field->real_type()),
65       decimals(old_field->decimals()),
66       flags(old_field->all_flags()),
67       auto_flags(old_field->auto_flags),
68       charset(old_field->charset()),  // May be NULL ptr
69       is_explicit_collation(false),
70       geom_type(Field::GEOM_GEOMETRY),
71       field(old_field),
72       is_nullable(old_field->is_nullable()),
73       is_zerofill(false),  // Init to avoid UBSAN warnings
74       is_unsigned(false),  // Init to avoid UBSAN warnings
75       treat_bit_as_char(
76           false),  // Init to avoid valgrind warnings in opt. build
77       pack_length_override(0),
78       gcol_info(old_field->gcol_info),
79       stored_in_db(old_field->stored_in_db),
80       m_default_val_expr(old_field->m_default_val_expr),
81       is_array(old_field->is_array()),
82       m_engine_attribute(old_field->m_engine_attribute),
83       m_secondary_engine_attribute(old_field->m_secondary_engine_attribute),
84       m_max_display_width_in_codepoints(old_field->char_length()) {
85   switch (sql_type) {
86     case MYSQL_TYPE_TINY_BLOB:
87     case MYSQL_TYPE_MEDIUM_BLOB:
88     case MYSQL_TYPE_LONG_BLOB:
89     case MYSQL_TYPE_BLOB:
90       sql_type = blob_type_from_pack_length(old_field->pack_length() -
91                                             portable_sizeof_char_ptr);
92       break;
93     case MYSQL_TYPE_STRING:
94       /* Change CHAR -> VARCHAR if dynamic record length */
95       if (old_field->type() == MYSQL_TYPE_VAR_STRING)
96         sql_type = MYSQL_TYPE_VARCHAR;
97       break;
98     case MYSQL_TYPE_GEOMETRY: {
99       const Field_geom *field_geom = down_cast<const Field_geom *>(old_field);
100       geom_type = field_geom->geom_type;
101       m_srid = field_geom->get_srid();
102       break;
103     }
104     case MYSQL_TYPE_YEAR:
105       m_max_display_width_in_codepoints = 4;  // set default value
106       break;
107     default:
108       break;
109   }
110 
111   if (flags & (ENUM_FLAG | SET_FLAG))
112     interval = down_cast<Field_enum *>(old_field)->typelib;
113   else
114     interval = nullptr;
115   constant_default = nullptr;
116 
117   /*
118     Copy the default (constant/function) from the column object orig_field, if
119     supplied. We do this if all these conditions are met:
120 
121     - The column allows a default.
122 
123     - The column type is not a BLOB type.
124 
125     - The original column (old_field) was properly initialized with a record
126       buffer pointer.
127   */
128   if (!(flags & (NO_DEFAULT_VALUE_FLAG | BLOB_FLAG)) &&
129       old_field->field_ptr() != nullptr && orig_field != nullptr) {
130     bool default_now = false;
131     if (real_type_with_now_as_default(sql_type)) {
132       // The SQL type of the new field allows a function default:
133       default_now = orig_field->has_insert_default_datetime_value_expression();
134       auto_flags = default_now ? Field::DEFAULT_NOW : Field::NONE;
135       if (orig_field->has_update_default_datetime_value_expression())
136         auto_flags |= Field::ON_UPDATE_NOW;
137       if (orig_field->has_insert_default_general_value_expression())
138         auto_flags |= Field::GENERATED_FROM_EXPRESSION;
139     }
140     if (!default_now)  // Give a constant default
141     {
142       /* Get the value from default_values */
143       ptrdiff_t diff = orig_field->table->default_values_offset();
144       orig_field->move_field_offset(diff);  // Points now at default_values
145       if (!orig_field->is_real_null()) {
146         StringBuffer<MAX_FIELD_WIDTH> tmp(charset);
147         String *res = orig_field->val_str(&tmp);
148         char *pos = sql_strmake(res->ptr(), res->length());
149         constant_default = new Item_string(pos, res->length(), charset);
150       }
151       orig_field->move_field_offset(-diff);  // Back to record[0]
152     }
153   }
154 }
155 
156 /**
157   Initialize a column definition object. Column definition objects can be used
158   to construct Field objects.
159 
160   @param thd                   Session/Thread handle.
161   @param fld_name              Column name.
162   @param fld_type              Column type.
163   @param display_width_in_codepoints The column display width, counted in
164                                      number of code points.
165   @param fld_decimals          Number of digits to the right of the decimal
166                                point (if any.)
167   @param fld_type_modifier     Additional type information.
168   @param fld_default_value     Column default constant or datetime expression
169                                (if any.)
170   @param fld_on_update_value   The expression in the ON UPDATE clause.
171   @param fld_comment           Column comment.
172   @param fld_change            Column change.
173   @param fld_interval_list     Interval list (if any.)
174   @param fld_charset           Column charset.
175   @param has_explicit_collation Column has an explicit COLLATE attribute.
176   @param fld_geom_type         Column geometry type (if any.)
177   @param fld_gcol_info         Generated column data
178   @param fld_default_val_expr  The expression for generating default values
179   @param srid                  The SRID specification. This might be null
180                                (has_value() may return false).
181   @param hidden                Whether this column should be hidden or not.
182   @param is_array_arg          Whether the field is a typed array
183 
184   @retval
185     false on success.
186   @retval
187     true  on error.
188 */
189 
init(THD * thd,const char * fld_name,enum_field_types fld_type,const char * display_width_in_codepoints,const char * fld_decimals,uint fld_type_modifier,Item * fld_default_value,Item * fld_on_update_value,const LEX_CSTRING * fld_comment,const char * fld_change,List<String> * fld_interval_list,const CHARSET_INFO * fld_charset,bool has_explicit_collation,uint fld_geom_type,Value_generator * fld_gcol_info,Value_generator * fld_default_val_expr,Nullable<gis::srid_t> srid,dd::Column::enum_hidden_type hidden,bool is_array_arg)190 bool Create_field::init(
191     THD *thd, const char *fld_name, enum_field_types fld_type,
192     const char *display_width_in_codepoints, const char *fld_decimals,
193     uint fld_type_modifier, Item *fld_default_value, Item *fld_on_update_value,
194     const LEX_CSTRING *fld_comment, const char *fld_change,
195     List<String> *fld_interval_list, const CHARSET_INFO *fld_charset,
196     bool has_explicit_collation, uint fld_geom_type,
197     Value_generator *fld_gcol_info, Value_generator *fld_default_val_expr,
198     Nullable<gis::srid_t> srid, dd::Column::enum_hidden_type hidden,
199     bool is_array_arg) {
200   uint sign_len, allowed_type_modifier = 0;
201   ulong max_field_charlength = MAX_FIELD_CHARLENGTH;
202 
203   DBUG_TRACE;
204 
205   DBUG_ASSERT(!(has_explicit_collation && fld_charset == nullptr));
206 
207   field = nullptr;
208   field_name = fld_name;
209   flags = fld_type_modifier;
210   is_explicit_collation = (fld_charset != nullptr);
211 
212   if (!has_explicit_collation && fld_charset == &my_charset_utf8mb4_0900_ai_ci)
213     charset = thd->variables.default_collation_for_utf8mb4;
214   else
215     charset = fld_charset;
216 
217   auto_flags = Field::NONE;
218   is_nullable = !(fld_type_modifier & NOT_NULL_FLAG);
219   this->hidden = hidden;
220   is_array = is_array_arg;
221 
222   if (fld_default_value != nullptr &&
223       fld_default_value->type() == Item::FUNC_ITEM) {
224     // We have a function default for insertions.
225     constant_default = nullptr;
226     auto_flags |= Field::DEFAULT_NOW;
227   } else {
228     // No function default for insertions. Either NULL or a constant.
229     constant_default = fld_default_value;
230   }
231 
232   // ON UPDATE CURRENT_TIMESTAMP
233   if (fld_on_update_value != nullptr &&
234       fld_on_update_value->type() == Item::FUNC_ITEM)
235     auto_flags |= Field::ON_UPDATE_NOW;
236 
237   // Automatic increment.
238   if (fld_type_modifier & AUTO_INCREMENT_FLAG) auto_flags |= Field::NEXT_NUMBER;
239 
240   decimals = fld_decimals ? (uint)atoi(fld_decimals) : 0;
241   if (is_temporal_real_type(fld_type)) {
242     flags |= BINARY_FLAG;
243     charset = &my_charset_numeric;
244     if (decimals > DATETIME_MAX_DECIMALS) {
245       my_error(ER_TOO_BIG_PRECISION, MYF(0), decimals, fld_name,
246                DATETIME_MAX_DECIMALS);
247       return true;
248     }
249   } else if (decimals >= DECIMAL_NOT_SPECIFIED) {
250     my_error(ER_TOO_BIG_SCALE, MYF(0), decimals, fld_name,
251              static_cast<ulong>(DECIMAL_NOT_SPECIFIED - 1));
252     return true;
253   }
254 
255   sql_type = fld_type;
256   change = fld_change;
257   interval = nullptr;
258   geom_type = static_cast<Field::geometry_type>(fld_geom_type);
259   interval_list.empty();
260 
261   comment = *fld_comment;
262   gcol_info = fld_gcol_info;
263   stored_in_db = true;
264   m_srid = srid;
265 
266   if (fld_default_val_expr) {
267     constant_default = nullptr;
268     auto_flags |= Field::GENERATED_FROM_EXPRESSION;
269     m_default_val_expr = fld_default_val_expr;
270   }
271 
272   // Initialize data for a virtual field or default value expression
273   if (gcol_info || m_default_val_expr) {
274     if (gcol_info) {
275       DBUG_ASSERT(gcol_info->expr_item);
276       stored_in_db = gcol_info->get_field_stored();
277 
278       /*
279         Make a field created for the real type.
280         Note that "real" and generated fields differ from each other
281         only by Field::gcol_info, which is always 0 for normal columns.
282         gcol_info is updated for fields later in procedure open_binary_frm.
283       */
284       sql_type = fld_type = gcol_info->get_real_type();
285       if (pre_validate_value_generator_expr(gcol_info->expr_item, field_name,
286                                             VGS_GENERATED_COLUMN))
287         return true;
288     } else {
289       if (pre_validate_value_generator_expr(m_default_val_expr->expr_item,
290                                             field_name, VGS_DEFAULT_EXPRESSION))
291         return true;
292     }
293   }
294 
295   /*
296     Set NO_DEFAULT_VALUE_FLAG if this field doesn't have a default value
297     or an expression to generate the default value and
298     it is NOT NULL and not an AUTO_INCREMENT field.
299   */
300   if (!fld_default_value && !fld_default_val_expr &&
301       (fld_type_modifier & NOT_NULL_FLAG) &&
302       !(fld_type_modifier & AUTO_INCREMENT_FLAG)) {
303     /*
304       TIMESTAMP columns get implicit DEFAULT value when
305       explicit_defaults_for_timestamp is not set.
306     */
307     if (thd->variables.explicit_defaults_for_timestamp ||
308         !is_timestamp_type(fld_type)) {
309       flags |= NO_DEFAULT_VALUE_FLAG;
310     }
311   }
312 
313   if (display_width_in_codepoints != nullptr) {
314     errno = 0;
315     const ulonglong ull_length =
316         my_strtoull(display_width_in_codepoints, nullptr, 10);
317     if ((errno != 0) || (ull_length > MAX_FIELD_BLOBLENGTH)) {
318       my_error(ER_TOO_BIG_DISPLAYWIDTH, MYF(0), fld_name, MAX_FIELD_BLOBLENGTH);
319       return true;
320     }
321     m_max_display_width_in_codepoints = static_cast<size_t>(ull_length);
322     m_explicit_display_width = true;
323 
324     if (m_max_display_width_in_codepoints == 0)
325       display_width_in_codepoints = nullptr; /* purecov: inspected */
326   }
327 
328   sign_len = fld_type_modifier & UNSIGNED_FLAG ? 0 : 1;
329 
330   switch (fld_type) {
331     case MYSQL_TYPE_TINY:
332       if (!display_width_in_codepoints)
333         m_max_display_width_in_codepoints = MAX_TINYINT_WIDTH + sign_len;
334       allowed_type_modifier = AUTO_INCREMENT_FLAG;
335       break;
336     case MYSQL_TYPE_SHORT:
337       if (!display_width_in_codepoints)
338         m_max_display_width_in_codepoints = MAX_SMALLINT_WIDTH + sign_len;
339       allowed_type_modifier = AUTO_INCREMENT_FLAG;
340       break;
341     case MYSQL_TYPE_INT24:
342       if (!display_width_in_codepoints)
343         m_max_display_width_in_codepoints = MAX_MEDIUMINT_WIDTH + sign_len;
344       allowed_type_modifier = AUTO_INCREMENT_FLAG;
345       break;
346     case MYSQL_TYPE_LONG:
347       if (!display_width_in_codepoints)
348         m_max_display_width_in_codepoints = MAX_INT_WIDTH + sign_len;
349       allowed_type_modifier = AUTO_INCREMENT_FLAG;
350       break;
351     case MYSQL_TYPE_LONGLONG:
352       if (!display_width_in_codepoints)
353         m_max_display_width_in_codepoints = MAX_BIGINT_WIDTH;
354       allowed_type_modifier = AUTO_INCREMENT_FLAG;
355       break;
356     case MYSQL_TYPE_NULL:
357       break;
358     case MYSQL_TYPE_NEWDECIMAL: {
359       ulong precision = static_cast<ulong>(m_max_display_width_in_codepoints);
360       my_decimal_trim(&precision, &decimals);
361       m_max_display_width_in_codepoints = precision;
362     }
363       if (m_max_display_width_in_codepoints > DECIMAL_MAX_PRECISION) {
364         my_error(ER_TOO_BIG_PRECISION, MYF(0),
365                  static_cast<int>(m_max_display_width_in_codepoints), fld_name,
366                  static_cast<ulong>(DECIMAL_MAX_PRECISION));
367         return true;
368       }
369       if (m_max_display_width_in_codepoints < decimals) {
370         my_error(ER_M_BIGGER_THAN_D, MYF(0), fld_name);
371         return true;
372       }
373       m_max_display_width_in_codepoints = my_decimal_precision_to_length(
374           m_max_display_width_in_codepoints, decimals,
375           fld_type_modifier & UNSIGNED_FLAG);
376       break;
377     case MYSQL_TYPE_VARCHAR:
378       // Note that VARCHAR fields with a long length may be converted to blob
379       // types in prepare_blob_field()
380       max_field_charlength = MAX_FIELD_VARCHARLENGTH;
381       break;
382     case MYSQL_TYPE_STRING:
383       break;
384     case MYSQL_TYPE_BLOB:
385     case MYSQL_TYPE_TINY_BLOB:
386     case MYSQL_TYPE_LONG_BLOB:
387     case MYSQL_TYPE_MEDIUM_BLOB:
388     case MYSQL_TYPE_JSON:
389       if (fld_default_value) {
390         /* Allow empty as default value. */
391         String str, *res;
392         res = fld_default_value->val_str(&str);
393         /*
394           A default other than '' is always an error, and any non-NULL
395           specified default is an error in strict mode.
396         */
397         if (res->length() || thd->is_strict_mode()) {
398           my_error(ER_BLOB_CANT_HAVE_DEFAULT, MYF(0),
399                    fld_name); /* purecov: inspected */
400           return true;
401         } else {
402           /*
403             Otherwise a default of '' is just a warning.
404           */
405           push_warning_printf(thd, Sql_condition::SL_WARNING,
406                               ER_BLOB_CANT_HAVE_DEFAULT,
407                               ER_THD(thd, ER_BLOB_CANT_HAVE_DEFAULT), fld_name);
408         }
409         constant_default = nullptr;
410       }
411 
412       flags |= BLOB_FLAG;
413       break;
414     case MYSQL_TYPE_GEOMETRY:
415       if (fld_default_value) {
416         my_error(ER_BLOB_CANT_HAVE_DEFAULT, MYF(0), fld_name);
417         return true;
418       }
419       flags |= BLOB_FLAG;
420       break;
421     case MYSQL_TYPE_YEAR:
422       if (!display_width_in_codepoints ||
423           m_max_display_width_in_codepoints != 4)
424         m_max_display_width_in_codepoints = 4; /* Default length */
425       flags |= ZEROFILL_FLAG | UNSIGNED_FLAG;
426       break;
427     case MYSQL_TYPE_FLOAT:
428       /* change FLOAT(precision) to FLOAT or DOUBLE */
429       allowed_type_modifier = AUTO_INCREMENT_FLAG;
430       if (display_width_in_codepoints && !fld_decimals) {
431         size_t tmp_length = m_max_display_width_in_codepoints;
432         if (tmp_length > PRECISION_FOR_DOUBLE) {
433           my_error(ER_WRONG_FIELD_SPEC, MYF(0), fld_name);
434           return true;
435         } else if (tmp_length > PRECISION_FOR_FLOAT) {
436           sql_type = MYSQL_TYPE_DOUBLE;
437           m_max_display_width_in_codepoints = MAX_DOUBLE_STR_LENGTH;
438         } else
439           m_max_display_width_in_codepoints = MAX_FLOAT_STR_LENGTH;
440         decimals = DECIMAL_NOT_SPECIFIED;
441         break;
442       }
443       if (!display_width_in_codepoints && !fld_decimals) {
444         m_max_display_width_in_codepoints = MAX_FLOAT_STR_LENGTH;
445         decimals = DECIMAL_NOT_SPECIFIED;
446       }
447       if (m_max_display_width_in_codepoints < decimals &&
448           decimals != DECIMAL_NOT_SPECIFIED) {
449         my_error(ER_M_BIGGER_THAN_D, MYF(0), fld_name);
450         return true;
451       }
452       break;
453     case MYSQL_TYPE_DOUBLE:
454       allowed_type_modifier = AUTO_INCREMENT_FLAG;
455       if (!display_width_in_codepoints && !fld_decimals) {
456         m_max_display_width_in_codepoints = DBL_DIG + 7;
457         decimals = DECIMAL_NOT_SPECIFIED;
458       }
459       if (m_max_display_width_in_codepoints < decimals &&
460           decimals != DECIMAL_NOT_SPECIFIED) {
461         my_error(ER_M_BIGGER_THAN_D, MYF(0), fld_name);
462         return true;
463       }
464       break;
465     case MYSQL_TYPE_TIMESTAMP:
466       /* Add flags for TIMESTAMP for 4.0 MYD and 4.0 InnoDB compatibility */
467       flags |= ZEROFILL_FLAG | UNSIGNED_FLAG;
468       /* Fall through */
469     case MYSQL_TYPE_TIMESTAMP2:
470       if (display_width_in_codepoints == nullptr) {
471         m_max_display_width_in_codepoints =
472             MAX_DATETIME_WIDTH + (decimals ? (1 + decimals) : 0);
473       } else if (m_max_display_width_in_codepoints != MAX_DATETIME_WIDTH) {
474         /*
475           We support only even TIMESTAMP lengths less or equal than 14
476           and 19 as length of 4.1 compatible representation.  Silently
477           shrink it to MAX_DATETIME_COMPRESSED_WIDTH.
478         */
479         DBUG_ASSERT(MAX_DATETIME_COMPRESSED_WIDTH < UINT_MAX);
480         if (m_max_display_width_in_codepoints !=
481             UINT_MAX) /* avoid overflow; is safe because of min() */
482           m_max_display_width_in_codepoints =
483               ((m_max_display_width_in_codepoints + 1) / 2) * 2;
484         m_max_display_width_in_codepoints = std::min<size_t>(
485             m_max_display_width_in_codepoints, MAX_DATETIME_COMPRESSED_WIDTH);
486       }
487 
488       /*
489         Since we silently rewrite down to MAX_DATETIME_COMPRESSED_WIDTH bytes,
490         the parser should not raise errors unless bizzarely large.
491        */
492       max_field_charlength = UINT_MAX;
493 
494       break;
495     case MYSQL_TYPE_DATE:
496       /* Old date type. */
497       sql_type = MYSQL_TYPE_NEWDATE;
498       /* fall through */
499     case MYSQL_TYPE_NEWDATE:
500       m_max_display_width_in_codepoints = MAX_DATE_WIDTH;
501       break;
502     case MYSQL_TYPE_TIME:
503     case MYSQL_TYPE_TIME2:
504       m_max_display_width_in_codepoints =
505           MAX_TIME_WIDTH + (decimals ? (1 + decimals) : 0);
506       break;
507     case MYSQL_TYPE_DATETIME:
508     case MYSQL_TYPE_DATETIME2:
509       m_max_display_width_in_codepoints =
510           MAX_DATETIME_WIDTH + (decimals ? (1 + decimals) : 0);
511       break;
512     case MYSQL_TYPE_SET:
513     case MYSQL_TYPE_ENUM: {
514       for (String &it : *fld_interval_list) {
515         interval_list.push_back(&it);
516       }
517       break;
518     }
519     case MYSQL_TYPE_VAR_STRING:
520       DBUG_ASSERT(0); /* Impossible. */
521       break;
522     case MYSQL_TYPE_BIT: {
523       if (!display_width_in_codepoints) {
524         my_error(ER_INVALID_FIELD_SIZE, MYF(0), fld_name);
525         return true;
526       }
527       if (m_max_display_width_in_codepoints > MAX_BIT_FIELD_LENGTH) {
528         my_error(ER_TOO_BIG_DISPLAYWIDTH, MYF(0), fld_name,
529                  static_cast<ulong>(MAX_BIT_FIELD_LENGTH));
530         return true;
531       }
532       break;
533     }
534     case MYSQL_TYPE_DECIMAL:
535     default:
536       DBUG_ASSERT(0); /* Was obsolete */
537   }
538 
539   if (!(flags & BLOB_FLAG) &&
540       ((m_max_display_width_in_codepoints > max_field_charlength &&
541         fld_type != MYSQL_TYPE_SET && fld_type != MYSQL_TYPE_ENUM &&
542         (fld_type != MYSQL_TYPE_VARCHAR || fld_default_value)) ||
543        ((m_max_display_width_in_codepoints == 0 && m_explicit_display_width) &&
544         fld_type != MYSQL_TYPE_STRING && fld_type != MYSQL_TYPE_VARCHAR &&
545         fld_type != MYSQL_TYPE_GEOMETRY))) {
546     my_error((fld_type == MYSQL_TYPE_VAR_STRING ||
547               fld_type == MYSQL_TYPE_VARCHAR || fld_type == MYSQL_TYPE_STRING)
548                  ? ER_TOO_BIG_FIELDLENGTH
549                  : ER_TOO_BIG_DISPLAYWIDTH,
550              MYF(0), fld_name, max_field_charlength); /* purecov: inspected */
551     return true;
552   }
553   fld_type_modifier &= AUTO_INCREMENT_FLAG;
554   if ((~allowed_type_modifier) & fld_type_modifier) {
555     my_error(ER_WRONG_FIELD_SPEC, MYF(0), fld_name);
556     return true;
557   }
558 
559   /*
560     After all checks were carried out we should be able guarantee that column
561     can't have AUTO_INCREMENT and DEFAULT/ON UPDATE CURRENT_TIMESTAMP at the
562     same time.
563   */
564   DBUG_ASSERT(!((auto_flags & (Field::DEFAULT_NOW | Field::ON_UPDATE_NOW |
565                                Field::GENERATED_FROM_EXPRESSION)) != 0 &&
566                 (auto_flags & Field::NEXT_NUMBER) != 0));
567 
568   return false; /* success */
569 }
570 
571 /**
572   Init for a tmp table field. To be extended if need be.
573 */
init_for_tmp_table(enum_field_types sql_type_arg,uint32 length_arg,uint32 decimals_arg,bool is_nullable_arg,bool is_unsigned_arg,uint pack_length_override_arg,const char * fld_name)574 void Create_field::init_for_tmp_table(enum_field_types sql_type_arg,
575                                       uint32 length_arg, uint32 decimals_arg,
576                                       bool is_nullable_arg,
577                                       bool is_unsigned_arg,
578                                       uint pack_length_override_arg,
579                                       const char *fld_name) {
580   DBUG_TRACE;
581 
582   field_name = fld_name;
583   sql_type = sql_type_arg;
584   m_max_display_width_in_codepoints = length_arg;
585   auto_flags = Field::NONE;
586   interval = nullptr;
587   charset = &my_charset_bin;
588   geom_type = Field::GEOM_GEOMETRY;
589 
590   DBUG_PRINT("enter", ("sql_type: %d, length: %u", sql_type_arg, length_arg));
591 
592   /* Init members needed for correct execution of make_field(). */
593 #ifndef DBUG_OFF
594   const uint32 FIELDFLAG_MAX_DEC = 31;
595 #endif
596 
597   switch (sql_type_arg) {
598     case MYSQL_TYPE_BIT:
599       treat_bit_as_char = true;
600       break;
601     case MYSQL_TYPE_DATE:
602       // Old type
603       sql_type = MYSQL_TYPE_NEWDATE;
604       break;
605 
606     case MYSQL_TYPE_NEWDECIMAL:
607       DBUG_ASSERT(decimals_arg <= DECIMAL_MAX_SCALE);
608     case MYSQL_TYPE_DECIMAL:
609     case MYSQL_TYPE_FLOAT:
610     case MYSQL_TYPE_DOUBLE:
611       DBUG_ASSERT(decimals_arg <= FIELDFLAG_MAX_DEC);
612       decimals = decimals_arg;
613       break;
614 
615     default:
616       break;
617   }
618 
619   is_nullable = is_nullable_arg;
620 
621   is_zerofill = false;
622   is_unsigned = is_unsigned_arg;
623 
624   pack_length_override = pack_length_override_arg;
625 
626   gcol_info = nullptr;
627   stored_in_db = true;
628   m_default_val_expr = nullptr;
629 }
630 
max_display_width_in_codepoints() const631 size_t Create_field::max_display_width_in_codepoints() const {
632   if (sql_type == MYSQL_TYPE_ENUM || sql_type == MYSQL_TYPE_SET) {
633     DBUG_ASSERT(interval != nullptr);
634     DBUG_ASSERT(charset != nullptr);
635 
636     size_t max_display_width_in_codepoints = 0;
637     for (size_t i = 0; i < interval->count; i++) {
638       const char *start = interval->type_names[i];
639       const char *end = interval->type_names[i] + interval->type_lengths[i];
640       const size_t num_characters =
641           charset->cset->numchars(charset, start, end);
642 
643       if (sql_type == MYSQL_TYPE_ENUM) {
644         // ENUM uses the longest value.
645         max_display_width_in_codepoints =
646             std::max(max_display_width_in_codepoints, num_characters);
647       } else if (sql_type == MYSQL_TYPE_SET) {
648         // SET uses the total length of all values, plus a comma between each
649         // value.
650         max_display_width_in_codepoints += num_characters;
651         if (i > 0) {
652           max_display_width_in_codepoints++;
653         }
654       }
655     }
656 
657     return std::min(max_display_width_in_codepoints,
658                     static_cast<size_t>(MAX_FIELD_WIDTH - 1));
659   } else if (sql_type == MYSQL_TYPE_TINY_BLOB) {
660     return TINYBLOB_MAX_SIZE_IN_BYTES / charset->mbmaxlen;
661   } else if (sql_type == MYSQL_TYPE_BLOB && !explicit_display_width()) {
662     // For BLOB and TEXT, the user can give a display width explicitly in CREATE
663     // TABLE (BLOB(25), TEXT(25)) where the expected behavior is that the server
664     // will find the smallest possible BLOB/TEXT type that will fit the given
665     // display width. If the user has given an explicit display width, return
666     // that instead of the max BLOB size.
667     return BLOB_MAX_SIZE_IN_BYTES / charset->mbmaxlen;
668   } else if (sql_type == MYSQL_TYPE_MEDIUM_BLOB) {
669     return MEDIUMBLOB_MAX_SIZE_IN_BYTES / charset->mbmaxlen;
670   } else if (sql_type == MYSQL_TYPE_LONG_BLOB || sql_type == MYSQL_TYPE_JSON ||
671              sql_type == MYSQL_TYPE_GEOMETRY) {
672     return LONGBLOB_MAX_SIZE_IN_BYTES / charset->mbmaxlen;
673   } else {
674     return m_max_display_width_in_codepoints;
675   }
676 }
677 
max_display_width_in_bytes() const678 size_t Create_field::max_display_width_in_bytes() const {
679   // It might seem unnecessary to have special case for the various BLOB types
680   // instead of just using the "else" clause for these types as well. However,
681   // that might give us rounding errors for multi-byte character sets. One
682   // example is JSON which has the character set utf8mb4_bin.
683   // max_display_width_in_codepoints() will return 1073741823 (truncated from
684   // 1073741823.75), and multiplying that by four again will give 4294967292
685   // which is the wrong result.
686   DBUG_ASSERT(charset != nullptr);
687   if (is_numeric_type(sql_type) || is_temporal_real_type(sql_type) ||
688       sql_type == MYSQL_TYPE_YEAR || sql_type == MYSQL_TYPE_BIT) {
689     // Numeric types, temporal types, YEAR or BIT are never multi-byte.
690     return max_display_width_in_codepoints();
691   } else if (sql_type == MYSQL_TYPE_TINY_BLOB) {
692     return TINYBLOB_MAX_SIZE_IN_BYTES;
693   } else if (sql_type == MYSQL_TYPE_BLOB && !explicit_display_width()) {
694     // For BLOB and TEXT, the user can give a display width (BLOB(25), TEXT(25))
695     // where the expected behavior is that the server will find the smallest
696     // possible BLOB/TEXT type that will fit the given display width. If the
697     // user has given an explicit display width, return that instead of the
698     // max BLOB size.
699     return BLOB_MAX_SIZE_IN_BYTES;
700   } else if (sql_type == MYSQL_TYPE_MEDIUM_BLOB) {
701     return MEDIUMBLOB_MAX_SIZE_IN_BYTES;
702   } else if (sql_type == MYSQL_TYPE_LONG_BLOB || sql_type == MYSQL_TYPE_JSON ||
703              sql_type == MYSQL_TYPE_GEOMETRY) {
704     return LONGBLOB_MAX_SIZE_IN_BYTES;
705   } else {
706     // If the user has given a display width to the TEXT type where the display
707     // width is 2^32-1, the below computation will exceed
708     // LONGBLOB_MAX_SIZE_IN_BYTES if the character set is multi-byte. So we must
709     // ensure that we never return a value greater than
710     // LONGBLOB_MAX_SIZE_IN_BYTES.
711     std::int64_t display_width = max_display_width_in_codepoints() *
712                                  static_cast<std::int64_t>(charset->mbmaxlen);
713     return static_cast<size_t>(std::min(
714         display_width, static_cast<std::int64_t>(LONGBLOB_MAX_SIZE_IN_BYTES)));
715   }
716 }
717 
pack_length(bool dont_override) const718 size_t Create_field::pack_length(bool dont_override) const {
719   if (!dont_override && pack_length_override != 0) return pack_length_override;
720 
721   switch (sql_type) {
722     case MYSQL_TYPE_SET: {
723       return get_set_pack_length(interval == nullptr ? interval_list.elements
724                                                      : interval->count);
725     }
726     case MYSQL_TYPE_ENUM: {
727       return get_enum_pack_length(interval == nullptr ? interval_list.elements
728                                                       : interval->count);
729     }
730     case MYSQL_TYPE_NEWDECIMAL: {
731       DBUG_ASSERT(decimals <= DECIMAL_MAX_SCALE);
732       uint precision = my_decimal_length_to_precision(
733           max_display_width_in_bytes(), decimals, (flags & UNSIGNED_FLAG));
734       precision = std::min(precision, static_cast<uint>(DECIMAL_MAX_PRECISION));
735       return my_decimal_get_binary_size(precision, decimals);
736     }
737     case MYSQL_TYPE_BIT: {
738       if (treat_bit_as_char) {
739         return (max_display_width_in_bytes() + 7) / 8;
740       } else {
741         return max_display_width_in_bytes() / 8;
742       }
743     }
744     default: {
745       return calc_pack_length(sql_type, max_display_width_in_bytes());
746     }
747   }
748 }
749 
key_length() const750 size_t Create_field::key_length() const {
751   switch (sql_type) {
752     case MYSQL_TYPE_TINY_BLOB:
753     case MYSQL_TYPE_MEDIUM_BLOB:
754     case MYSQL_TYPE_LONG_BLOB:
755     case MYSQL_TYPE_BLOB:
756     case MYSQL_TYPE_GEOMETRY:
757     case MYSQL_TYPE_JSON:
758     case MYSQL_TYPE_VAR_STRING:
759     case MYSQL_TYPE_STRING:
760     case MYSQL_TYPE_VARCHAR: {
761       return std::min(max_display_width_in_bytes(),
762                       static_cast<size_t>(MAX_FIELD_BLOBLENGTH));
763     }
764     case MYSQL_TYPE_ENUM:
765     case MYSQL_TYPE_SET: {
766       return pack_length();
767     }
768     case MYSQL_TYPE_BIT: {
769       if (treat_bit_as_char) {
770         return pack_length();
771       }
772       return pack_length() + (max_display_width_in_bytes() & 7 ? 1 : 0);
773     }
774     default: {
775       return pack_length(is_array);
776     }
777   }
778 }
779 
is_field_for_functional_index(const Create_field * create_field)780 bool is_field_for_functional_index(const Create_field *create_field) {
781   return create_field->hidden == dd::Column::enum_hidden_type::HT_HIDDEN_SQL;
782 }
783