1 /* Copyright (c) 2000, 2021, Oracle and/or its affiliates.
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
24 /**
25 @file
26
27 @brief
28 Functions to copy data to or from fields
29
30 This could be done with a single short function but opencoding this
31 gives much more speed.
32 */
33
34 #include "sql_class.h" // THD
35 #include "sql_time.h"
36 #include <m_ctype.h>
37 #include "item_timefunc.h" // Item_func_now_local
38 #include "template_utils.h" // down_cast
39
40
41 /**
42 Check if geometry type sub is a subtype of super.
43
44 @param sub The type to check
45 @param super The supertype
46
47 @return True if sub is a subtype of super
48 */
is_subtype_of(Field::geometry_type sub,Field::geometry_type super)49 inline static bool is_subtype_of(Field::geometry_type sub,
50 Field::geometry_type super)
51 {
52 return (super == Field::GEOM_GEOMETRY ||
53 (super == Field::GEOM_GEOMETRYCOLLECTION &&
54 (sub == Field::GEOM_MULTIPOINT ||
55 sub == Field::GEOM_MULTILINESTRING ||
56 sub == Field::GEOM_MULTIPOLYGON)));
57 }
58
59
do_field_eq(Copy_field * copy)60 static void do_field_eq(Copy_field *copy)
61 {
62 memcpy(copy->to_ptr, copy->from_ptr, copy->from_length());
63 }
64
do_field_1(Copy_field * copy)65 static void do_field_1(Copy_field *copy)
66 {
67 copy->to_ptr[0]=copy->from_ptr[0];
68 }
69
do_field_2(Copy_field * copy)70 static void do_field_2(Copy_field *copy)
71 {
72 copy->to_ptr[0]=copy->from_ptr[0];
73 copy->to_ptr[1]=copy->from_ptr[1];
74 }
75
do_field_3(Copy_field * copy)76 static void do_field_3(Copy_field *copy)
77 {
78 copy->to_ptr[0]=copy->from_ptr[0];
79 copy->to_ptr[1]=copy->from_ptr[1];
80 copy->to_ptr[2]=copy->from_ptr[2];
81 }
82
do_field_4(Copy_field * copy)83 static void do_field_4(Copy_field *copy)
84 {
85 copy->to_ptr[0]=copy->from_ptr[0];
86 copy->to_ptr[1]=copy->from_ptr[1];
87 copy->to_ptr[2]=copy->from_ptr[2];
88 copy->to_ptr[3]=copy->from_ptr[3];
89 }
90
do_field_6(Copy_field * copy)91 static void do_field_6(Copy_field *copy)
92 { // For blob field
93 copy->to_ptr[0]=copy->from_ptr[0];
94 copy->to_ptr[1]=copy->from_ptr[1];
95 copy->to_ptr[2]=copy->from_ptr[2];
96 copy->to_ptr[3]=copy->from_ptr[3];
97 copy->to_ptr[4]=copy->from_ptr[4];
98 copy->to_ptr[5]=copy->from_ptr[5];
99 }
100
do_field_8(Copy_field * copy)101 static void do_field_8(Copy_field *copy)
102 {
103 copy->to_ptr[0]=copy->from_ptr[0];
104 copy->to_ptr[1]=copy->from_ptr[1];
105 copy->to_ptr[2]=copy->from_ptr[2];
106 copy->to_ptr[3]=copy->from_ptr[3];
107 copy->to_ptr[4]=copy->from_ptr[4];
108 copy->to_ptr[5]=copy->from_ptr[5];
109 copy->to_ptr[6]=copy->from_ptr[6];
110 copy->to_ptr[7]=copy->from_ptr[7];
111 }
112
do_field_to_null_str(Copy_field * copy)113 static void do_field_to_null_str(Copy_field *copy)
114 {
115 if (*copy->null_row ||
116 (copy->from_null_ptr && (*copy->from_null_ptr & copy->from_bit)))
117 {
118 memset(copy->to_ptr, 0, copy->from_length());
119 copy->to_null_ptr[0]=1; // Always bit 1
120 }
121 else
122 {
123 copy->to_null_ptr[0]=0;
124 memcpy(copy->to_ptr, copy->from_ptr, copy->from_length());
125 }
126 }
127
128
set_field_to_null(Field * field)129 type_conversion_status set_field_to_null(Field *field)
130 {
131 if (field->real_maybe_null() || field->is_tmp_nullable())
132 {
133 field->set_null();
134 field->reset();
135 return TYPE_OK;
136 }
137
138 /**
139 The following piece of code is run for the case when a BLOB column
140 that has value NULL is queried with GROUP BY NULL and the result
141 is inserted into a some table's column declared having primitive type
142 (e.g. INT) and NOT NULL.
143
144 For example, the following test case will hit this piece of code:
145 CREATE TABLE t1 (a BLOB);
146 CREATE TABLE t2 (a INT NOT NULL);
147
148 INSERT t1 VALUES (NULL);
149 INSERT INTO t2(a) SELECT a FROM t1 GROUP BY NULL; <<== Hit here
150
151 In general, when set_field_to_null() is called a Field has to be either
152 declared as NULL-able or be marked as temporary NULL-able.
153 But in case of INSERT SELECT from a BLOB field and when GROUP BY NULL
154 is specified the Field object for a destination column doesn't set
155 neither NULL-able nor temporary NULL-able (see setup_copy_fields()).
156 */
157 field->reset();
158 switch (field->table->in_use->count_cuted_fields) {
159 case CHECK_FIELD_WARN:
160 field->set_warning(Sql_condition::SL_WARNING, WARN_DATA_TRUNCATED, 1);
161 /* fall through */
162 case CHECK_FIELD_IGNORE:
163 return TYPE_OK;
164 case CHECK_FIELD_ERROR_FOR_NULL:
165 if (!field->table->in_use->no_errors)
166 my_error(ER_BAD_NULL_ERROR, MYF(0), field->field_name);
167 return TYPE_ERR_NULL_CONSTRAINT_VIOLATION;
168 }
169 assert(false); // impossible
170
171 return TYPE_ERR_NULL_CONSTRAINT_VIOLATION; // to avoid compiler's warning
172 }
173
174
175 /**
176 Set field to NULL or TIMESTAMP or to next auto_increment number.
177
178 @param field Field to update
179 @param no_conversions Set to 1 if we should return 1 if field can't
180 take null values.
181 If set to 0 we will do store the 'default value'
182 if the field is a special field. If not we will
183 give an error.
184
185 @retval
186 0 Field could take 0 or an automatic conversion was used
187 @retval
188 -1 Field could not take NULL and no conversion was used.
189 If no_conversion was not set, an error message is printed
190 */
191
192 type_conversion_status
set_field_to_null_with_conversions(Field * field,bool no_conversions)193 set_field_to_null_with_conversions(Field *field, bool no_conversions)
194 {
195 if (field->real_maybe_null())
196 {
197 field->set_null();
198 field->reset();
199 return TYPE_OK;
200 }
201
202 if (no_conversions)
203 return TYPE_ERR_NULL_CONSTRAINT_VIOLATION;
204
205 /*
206 Check if this is a special type, which will get a special walue
207 when set to NULL (TIMESTAMP fields which allow setting to NULL
208 are handled by first check).
209
210 From the manual:
211
212 TIMESTAMP columns [...] assigning NULL assigns the current timestamp.
213
214 But if explicit_defaults_for_timestamp, use standard-compliant behaviour:
215 no special value.
216 */
217 if (field->type() == MYSQL_TYPE_TIMESTAMP &&
218 !field->table->in_use->variables.explicit_defaults_for_timestamp)
219 {
220 /*
221 With explicit_defaults_for_timestamp disabled, if a NULL value is inserted
222 into a timestamp column with NOT NULL attribute, would attempt to convert
223 the column value to CURRENT_TIMESTAMP. However, this is inconsistent with
224 the source of the generated value, so the insertion is rejected.
225 */
226 if (field->is_gcol())
227 {
228 my_error(ER_BAD_NULL_ERROR, MYF(0), field->field_name);
229 return TYPE_ERR_NULL_CONSTRAINT_VIOLATION;
230 }
231 else
232 {
233 Item_func_now_local::store_in(field);
234 return TYPE_OK; // Ok to set time to NULL
235 }
236 }
237
238 // Note: we ignore any potential failure of reset() here.
239 field->reset();
240
241 if (field == field->table->next_number_field)
242 {
243 field->table->auto_increment_field_not_null= FALSE;
244 return TYPE_OK; // field is set in fill_record()
245 }
246
247 if (field->is_tmp_nullable())
248 {
249 field->set_null();
250 field->reset();
251 return TYPE_OK;
252 }
253
254 switch (field->table->in_use->count_cuted_fields) {
255 case CHECK_FIELD_WARN:
256 // There's no valid conversion for geometry values.
257 if (field->type() == MYSQL_TYPE_GEOMETRY)
258 {
259 my_error(ER_BAD_NULL_ERROR, MYF(0), field->field_name);
260 return TYPE_ERR_NULL_CONSTRAINT_VIOLATION;
261 }
262
263 field->set_warning(Sql_condition::SL_WARNING, ER_BAD_NULL_ERROR, 1);
264 /* fall through */
265 case CHECK_FIELD_IGNORE:
266 return TYPE_OK;
267 case CHECK_FIELD_ERROR_FOR_NULL:
268 if (!field->table->in_use->no_errors)
269 my_error(ER_BAD_NULL_ERROR, MYF(0), field->field_name);
270 return TYPE_ERR_NULL_CONSTRAINT_VIOLATION;
271 }
272 assert(false); // impossible
273 return TYPE_ERR_NULL_CONSTRAINT_VIOLATION;
274 }
275
276
do_skip(Copy_field * copy MY_ATTRIBUTE ((unused)))277 static void do_skip(Copy_field *copy MY_ATTRIBUTE((unused)))
278 {
279 }
280
281
do_copy_null(Copy_field * copy)282 static void do_copy_null(Copy_field *copy)
283 {
284 if (*copy->null_row ||
285 (copy->from_null_ptr && (*copy->from_null_ptr & copy->from_bit)))
286 {
287 *copy->to_null_ptr|=copy->to_bit;
288 copy->to_field()->reset();
289 }
290 else
291 {
292 *copy->to_null_ptr&= ~copy->to_bit;
293 copy->invoke_do_copy2(copy);
294 }
295 }
296
297
do_copy_not_null(Copy_field * copy)298 static void do_copy_not_null(Copy_field *copy)
299 {
300 if (*copy->null_row ||
301 (copy->from_null_ptr && (*copy->from_null_ptr & copy->from_bit)))
302 {
303 if (copy->to_field()->reset() == TYPE_ERR_NULL_CONSTRAINT_VIOLATION)
304 my_error(ER_INVALID_USE_OF_NULL, MYF(0));
305 else
306 copy->to_field()->set_warning(Sql_condition::SL_WARNING,
307 WARN_DATA_TRUNCATED, 1);
308 }
309 else
310 copy->invoke_do_copy2(copy);
311 }
312
313
do_copy_maybe_null(Copy_field * copy)314 static void do_copy_maybe_null(Copy_field *copy)
315 {
316 *copy->to_null_ptr&= ~copy->to_bit;
317 copy->invoke_do_copy2(copy);
318 }
319
320 /* timestamp and next_number has special handling in case of NULL values */
321
do_copy_timestamp(Copy_field * copy)322 static void do_copy_timestamp(Copy_field *copy)
323 {
324 if (*copy->null_row || (*copy->from_null_ptr & copy->from_bit))
325 {
326 /* Same as in set_field_to_null_with_conversions() */
327 Item_func_now_local::store_in(copy->to_field());
328 }
329 else
330 copy->invoke_do_copy2(copy);
331 }
332
333
do_copy_next_number(Copy_field * copy)334 static void do_copy_next_number(Copy_field *copy)
335 {
336 if (*copy->null_row || (*copy->from_null_ptr & copy->from_bit))
337 {
338 /* Same as in set_field_to_null_with_conversions() */
339 copy->to_field()->table->auto_increment_field_not_null= false;
340 copy->to_field()->reset();
341 }
342 else
343 copy->invoke_do_copy2(copy);
344 }
345
346
do_copy_blob(Copy_field * copy)347 static void do_copy_blob(Copy_field *copy)
348 {
349 ulong from_length=((Field_blob*) copy->from_field())->get_length();
350 ((Field_blob*) copy->to_field())->store_length(from_length);
351 memcpy(copy->to_ptr, copy->from_ptr, sizeof(char*));
352 ulong to_length=((Field_blob*) copy->to_field())->get_length();
353 if (to_length < from_length)
354 {
355 if (copy->to_field()->table->in_use->is_strict_mode())
356 {
357 copy->to_field()->set_warning(Sql_condition::SL_WARNING,
358 ER_DATA_TOO_LONG, 1);
359 }
360 else
361 {
362 copy->to_field()->set_warning(Sql_condition::SL_WARNING,
363 WARN_DATA_TRUNCATED, 1);
364 }
365 }
366 }
367
do_conv_blob(Copy_field * copy)368 static void do_conv_blob(Copy_field *copy)
369 {
370 copy->from_field()->val_str(©->tmp);
371 ((Field_blob *) copy->to_field())->store(copy->tmp.ptr(),
372 copy->tmp.length(),
373 copy->tmp.charset());
374 }
375
376 /** Save blob in copy->tmp for GROUP BY. */
377
do_save_blob(Copy_field * copy)378 static void do_save_blob(Copy_field *copy)
379 {
380 char buff[MAX_FIELD_WIDTH];
381 String res(buff,sizeof(buff),copy->tmp.charset());
382 copy->from_field()->val_str(&res);
383 copy->tmp.copy(res);
384 ((Field_blob *) copy->to_field())->store(copy->tmp.ptr(),
385 copy->tmp.length(),
386 copy->tmp.charset());
387 }
388
389
390 /**
391 Copy the contents of one Field_json into another Field_json.
392 */
do_save_json(Copy_field * copy)393 static void do_save_json(Copy_field *copy)
394 {
395 Field_json *from= down_cast<Field_json *>(copy->from_field());
396 Field_json *to= down_cast<Field_json *>(copy->to_field());
397 to->store(from);
398 }
399
400
do_field_string(Copy_field * copy)401 static void do_field_string(Copy_field *copy)
402 {
403 char buff[MAX_FIELD_WIDTH];
404 String res(buff, sizeof(buff), copy->from_field()->charset());
405 res.length(0U);
406
407 copy->from_field()->val_str(&res);
408 copy->to_field()->store(res.c_ptr_quick(), res.length(), res.charset());
409 }
410
411
do_field_enum(Copy_field * copy)412 static void do_field_enum(Copy_field *copy)
413 {
414 if (copy->from_field()->val_int() == 0)
415 ((Field_enum *) copy->to_field())->store_type((ulonglong) 0);
416 else
417 do_field_string(copy);
418 }
419
420
do_field_varbinary_pre50(Copy_field * copy)421 static void do_field_varbinary_pre50(Copy_field *copy)
422 {
423 char buff[MAX_FIELD_WIDTH];
424 copy->tmp.set_quick(buff,sizeof(buff),copy->tmp.charset());
425 copy->from_field()->val_str(©->tmp);
426
427 /* Use the same function as in 4.1 to trim trailing spaces */
428 size_t length= my_lengthsp_8bit(&my_charset_bin, copy->tmp.c_ptr_quick(),
429 copy->from_field()->field_length);
430
431 copy->to_field()->store(copy->tmp.c_ptr_quick(), length,
432 copy->tmp.charset());
433 }
434
435
do_field_int(Copy_field * copy)436 static void do_field_int(Copy_field *copy)
437 {
438 longlong value= copy->from_field()->val_int();
439 copy->to_field()->store(value,
440 MY_TEST(copy->from_field()->flags & UNSIGNED_FLAG));
441 }
442
do_field_real(Copy_field * copy)443 static void do_field_real(Copy_field *copy)
444 {
445 double value=copy->from_field()->val_real();
446 copy->to_field()->store(value);
447 }
448
449
do_field_decimal(Copy_field * copy)450 static void do_field_decimal(Copy_field *copy)
451 {
452 my_decimal value;
453 copy->to_field()->store_decimal(copy->from_field()->val_decimal(&value));
454 }
455
456
copy_time_to_time(Field * from,Field * to)457 inline type_conversion_status copy_time_to_time(Field *from, Field *to)
458 {
459 MYSQL_TIME ltime;
460 from->get_time(<ime);
461 return to->store_time(<ime);
462 }
463
464 /**
465 Convert between fields using time representation.
466 */
do_field_time(Copy_field * copy)467 static void do_field_time(Copy_field *copy)
468 {
469 (void) copy_time_to_time(copy->from_field(), copy->to_field());
470 }
471
472
473 /**
474 string copy for single byte characters set when to string is shorter than
475 from string.
476 */
477
do_cut_string(Copy_field * copy)478 static void do_cut_string(Copy_field *copy)
479 {
480 const CHARSET_INFO *cs= copy->from_field()->charset();
481 memcpy(copy->to_ptr, copy->from_ptr, copy->to_length());
482
483 /* Check if we loosed any important characters */
484 if (cs->cset->scan(cs,
485 (char*) copy->from_ptr + copy->to_length(),
486 (char*) copy->from_ptr + copy->from_length(),
487 MY_SEQ_SPACES) < copy->from_length() - copy->to_length())
488 {
489 copy->to_field()->set_warning(Sql_condition::SL_WARNING,
490 WARN_DATA_TRUNCATED, 1);
491 }
492 }
493
494
495 /**
496 string copy for multi byte characters set when to string is shorter than
497 from string.
498 */
499
do_cut_string_complex(Copy_field * copy)500 static void do_cut_string_complex(Copy_field *copy)
501 { // Shorter string field
502 int well_formed_error;
503 const CHARSET_INFO *cs= copy->from_field()->charset();
504 const uchar *from_end= copy->from_ptr + copy->from_length();
505 size_t copy_length=
506 cs->cset->well_formed_len(cs,
507 (char*) copy->from_ptr,
508 (char*) from_end,
509 copy->to_length() / cs->mbmaxlen,
510 &well_formed_error);
511 if (copy->to_length() < copy_length)
512 copy_length= copy->to_length();
513 memcpy(copy->to_ptr, copy->from_ptr, copy_length);
514
515 /* Check if we lost any important characters */
516 if (well_formed_error ||
517 cs->cset->scan(cs, (char*) copy->from_ptr + copy_length,
518 (char*) from_end,
519 MY_SEQ_SPACES) < (copy->from_length() - copy_length))
520 {
521 copy->to_field()->set_warning(Sql_condition::SL_WARNING,
522 WARN_DATA_TRUNCATED, 1);
523 }
524
525 if (copy_length < copy->to_length())
526 cs->cset->fill(cs, (char*) copy->to_ptr + copy_length,
527 copy->to_length() - copy_length, ' ');
528 }
529
530
531
532
do_expand_binary(Copy_field * copy)533 static void do_expand_binary(Copy_field *copy)
534 {
535 const CHARSET_INFO *cs= copy->from_field()->charset();
536 memcpy(copy->to_ptr, copy->from_ptr, copy->from_length());
537 cs->cset->fill(cs, (char*) copy->to_ptr + copy->from_length(),
538 copy->to_length() - copy->from_length(), '\0');
539 }
540
541
542
do_expand_string(Copy_field * copy)543 static void do_expand_string(Copy_field *copy)
544 {
545 const CHARSET_INFO *cs= copy->from_field()->charset();
546 memcpy(copy->to_ptr, copy->from_ptr, copy->from_length());
547 cs->cset->fill(cs, (char*) copy->to_ptr + copy->from_length(),
548 copy->to_length() - copy->from_length(), ' ');
549 }
550
551 /**
552 Find how many bytes should be copied between Field_varstring fields
553 so that only the bytes in use in the 'from' field are copied.
554 Handles single and multi-byte charsets. Adds warning if not all
555 bytes in 'from' will fit into 'to'.
556
557 @param to Variable length field we're copying to
558 @param from Variable length field we're copying from
559
560 @return Number of bytes that should be copied from 'from' to 'to'.
561 */
get_varstring_copy_length(Field_varstring * to,const Field_varstring * from)562 static size_t get_varstring_copy_length(Field_varstring *to,
563 const Field_varstring *from)
564 {
565 const CHARSET_INFO * const cs= from->charset();
566 const bool is_multibyte_charset= (cs->mbmaxlen != 1);
567 const uint to_byte_length= to->row_pack_length();
568
569 size_t bytes_to_copy;
570 if (from->length_bytes == 1)
571 bytes_to_copy= *from->ptr;
572 else
573 bytes_to_copy= uint2korr(from->ptr);
574
575 if (is_multibyte_charset)
576 {
577 int well_formed_error;
578 const char *from_beg= reinterpret_cast<char*>(from->ptr + from->length_bytes);
579 const uint to_char_length= (to_byte_length) / cs->mbmaxlen;
580 const size_t from_byte_length= bytes_to_copy;
581 bytes_to_copy=
582 cs->cset->well_formed_len(cs, from_beg,
583 from_beg + from_byte_length,
584 to_char_length,
585 &well_formed_error);
586 if (bytes_to_copy < from_byte_length)
587 {
588 if (from->table->in_use->count_cuted_fields)
589 to->set_warning(Sql_condition::SL_WARNING,
590 WARN_DATA_TRUNCATED, 1);
591 }
592 }
593 else
594 {
595 if (bytes_to_copy > (to_byte_length))
596 {
597 bytes_to_copy= to_byte_length;
598 if (from->table->in_use->count_cuted_fields)
599 to->set_warning(Sql_condition::SL_WARNING,
600 WARN_DATA_TRUNCATED, 1);
601 }
602 }
603 return bytes_to_copy;
604 }
605
606 /**
607 A variable length string field consists of:
608 (a) 1 or 2 length bytes, depending on the VARCHAR column definition
609 (b) as many relevant character bytes, as defined in the length byte(s)
610 (c) unused padding up to the full length of the column
611
612 This function only copies (a) and (b)
613
614 Condition for using this function: to and from must use the same
615 number of bytes for length, i.e: to->length_bytes==from->length_bytes
616
617 @param to Variable length field we're copying to
618 @param from Variable length field we're copying from
619 */
copy_field_varstring(Field_varstring * const to,const Field_varstring * const from)620 static void copy_field_varstring(Field_varstring * const to,
621 const Field_varstring * const from)
622 {
623 const uint length_bytes= from->length_bytes;
624 assert(length_bytes == to->length_bytes);
625 assert(length_bytes == 1 || length_bytes == 2);
626
627 const size_t bytes_to_copy= get_varstring_copy_length(to, from);
628 if (length_bytes == 1)
629 *to->ptr= static_cast<uchar>(bytes_to_copy);
630 else
631 int2store(to->ptr, bytes_to_copy);
632
633 // memcpy should not be used for overlaping memory blocks
634 assert(to->ptr != from->ptr);
635 memcpy(to->ptr + length_bytes, from->ptr + length_bytes, bytes_to_copy);
636 }
637
do_varstring(Copy_field * copy)638 static void do_varstring(Copy_field *copy)
639 {
640 copy_field_varstring(static_cast<Field_varstring*>(copy->to_field()),
641 static_cast<Field_varstring*>(copy->from_field()));
642 }
643
644
645 /***************************************************************************
646 ** The different functions that fills in a Copy_field class
647 ***************************************************************************/
648
invoke_do_copy(Copy_field * f)649 void Copy_field::invoke_do_copy(Copy_field *f)
650 {
651 (*(this->m_do_copy))(f);
652
653 f->check_and_set_temporary_null();
654 }
655
invoke_do_copy2(Copy_field * f)656 void Copy_field::invoke_do_copy2(Copy_field *f)
657 {
658 (*(this->m_do_copy2))(f);
659
660 f->check_and_set_temporary_null();
661 }
662
663 /**
664 copy of field to maybe null string.
665 If field is null then the all bytes are set to 0.
666 if field is not null then the first byte is set to 1 and the rest of the
667 string is the field value.
668 The 'to' buffer should have a size of field->pack_length()+1
669 */
670
set(uchar * to,Field * from)671 void Copy_field::set(uchar *to,Field *from)
672 {
673 from_ptr=from->ptr;
674 to_ptr=to;
675 m_from_length= from->pack_length();
676 null_row= &from->table->null_row;
677 if (from->maybe_null())
678 {
679 from_null_ptr=from->get_null_ptr();
680 from_bit= from->null_bit;
681 to_ptr[0]= 1; // Null as default value
682 to_null_ptr= to_ptr++;
683 to_bit= 1;
684 m_do_copy= do_field_to_null_str;
685 }
686 else
687 {
688 to_null_ptr= 0; // For easy debugging
689 m_do_copy= do_field_eq;
690 }
691 }
692
693
694 /*
695 To do:
696
697 If 'save' is set to true and the 'from' is a blob field, m_do_copy is set to
698 do_save_blob rather than do_conv_blob. The only differences between them
699 appears to be:
700
701 - do_save_blob allocates and uses an intermediate buffer before calling
702 Field_blob::store. Is this in order to trigger the call to
703 well_formed_copy_nchars, by changing the pointer copy->tmp.ptr()?
704 That call will take place anyway in all known cases.
705 */
set(Field * to,Field * from,bool save)706 void Copy_field::set(Field *to,Field *from,bool save)
707 {
708 if (to->type() == MYSQL_TYPE_NULL)
709 {
710 to_null_ptr=0; // For easy debugging
711 to_ptr=0;
712 m_do_copy= do_skip;
713 return;
714 }
715 m_from_field= from;
716 m_to_field= to;
717 from_ptr= from->ptr;
718 m_from_length= from->pack_length();
719 to_ptr= to->ptr;
720 m_to_length= m_to_field->pack_length();
721
722 // set up null handling
723 from_null_ptr=to_null_ptr=0;
724 null_row= &from->table->null_row;
725 if (from->maybe_null())
726 {
727 from_null_ptr= from->get_null_ptr();
728 from_bit= from->null_bit;
729 if (m_to_field->real_maybe_null())
730 {
731 to_null_ptr= to->get_null_ptr();
732 to_bit= to->null_bit;
733 m_do_copy= do_copy_null;
734 }
735 else
736 {
737 if (m_to_field->type() == MYSQL_TYPE_TIMESTAMP)
738 m_do_copy= do_copy_timestamp; // Automatic timestamp
739 else if (m_to_field == m_to_field->table->next_number_field)
740 m_do_copy= do_copy_next_number;
741 else
742 m_do_copy= do_copy_not_null;
743 }
744 }
745 else if (m_to_field->real_maybe_null())
746 {
747 to_null_ptr= to->get_null_ptr();
748 to_bit= to->null_bit;
749 m_do_copy= do_copy_maybe_null;
750 }
751 else
752 m_do_copy= NULL;
753
754 if ((to->flags & BLOB_FLAG) && save)
755 {
756 if (to->real_type() == MYSQL_TYPE_JSON &&
757 from->real_type() == MYSQL_TYPE_JSON)
758 m_do_copy2= do_save_json;
759 else
760 m_do_copy2= do_save_blob;
761 }
762 else
763 m_do_copy2= get_copy_func(to,from);
764
765 if (!m_do_copy) // Not null
766 m_do_copy= m_do_copy2;
767 }
768
769
770 Copy_field::Copy_func *
get_copy_func(Field * to,Field * from)771 Copy_field::get_copy_func(Field *to,Field *from)
772 {
773 bool compatible_db_low_byte_first= (to->table->s->db_low_byte_first ==
774 from->table->s->db_low_byte_first);
775 if (to->type() == MYSQL_TYPE_GEOMETRY)
776 {
777 if (from->type() != MYSQL_TYPE_GEOMETRY ||
778 to->maybe_null() != from->maybe_null())
779 return do_conv_blob;
780
781 Field_geom *to_geom= down_cast<Field_geom*>(to);
782 Field_geom *from_geom= down_cast<Field_geom*>(from);
783
784 // to is same as or a wider type than from
785 if (to_geom->get_geometry_type() == from_geom->get_geometry_type() ||
786 is_subtype_of(from_geom->get_geometry_type(),
787 to_geom->get_geometry_type()))
788 return do_field_eq;
789
790 return do_conv_blob;
791 }
792 else if (to->flags & BLOB_FLAG)
793 {
794 /*
795 We need to do conversion if we are copying from BLOB to
796 non-BLOB, or if we are copying between BLOBs with different
797 character sets, or if we are copying between JSON and non-JSON.
798 */
799 if (!(from->flags & BLOB_FLAG) || from->charset() != to->charset() ||
800 ((to->type() == MYSQL_TYPE_JSON) != (from->type() == MYSQL_TYPE_JSON)))
801 return do_conv_blob;
802 if (m_from_length != m_to_length || !compatible_db_low_byte_first)
803 {
804 // Correct pointer to point at char pointer
805 to_ptr+= m_to_length - portable_sizeof_char_ptr;
806 from_ptr+= m_from_length - portable_sizeof_char_ptr;
807 return do_copy_blob;
808 }
809 }
810 else
811 {
812 if (to->real_type() == MYSQL_TYPE_BIT ||
813 from->real_type() == MYSQL_TYPE_BIT)
814 return do_field_int;
815 if (to->result_type() == DECIMAL_RESULT)
816 return do_field_decimal;
817 // Check if identical fields
818 if (from->result_type() == STRING_RESULT)
819 {
820 if (from->is_temporal())
821 {
822 if (to->is_temporal())
823 {
824 return do_field_time;
825 }
826 else
827 {
828 if (to->result_type() == INT_RESULT)
829 return do_field_int;
830 if (to->result_type() == REAL_RESULT)
831 return do_field_real;
832 /* Note: conversion from any to DECIMAL_RESULT is handled earlier */
833 }
834 }
835 /*
836 Detect copy from pre 5.0 varbinary to varbinary as of 5.0 and
837 use special copy function that removes trailing spaces and thus
838 repairs data.
839 */
840 if (from->type() == MYSQL_TYPE_VAR_STRING && !from->has_charset() &&
841 to->type() == MYSQL_TYPE_VARCHAR && !to->has_charset())
842 return do_field_varbinary_pre50;
843
844 /*
845 If we are copying date or datetime's we have to check the dates
846 if we don't allow 'all' dates.
847 */
848 if (to->real_type() != from->real_type() ||
849 to->decimals() != from->decimals() /* e.g. TIME vs TIME(6) */ ||
850 !compatible_db_low_byte_first ||
851 (((to->table->in_use->variables.sql_mode &
852 (MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE | MODE_INVALID_DATES)) &&
853 to->type() == MYSQL_TYPE_DATE) ||
854 to->type() == MYSQL_TYPE_DATETIME))
855 {
856 if (from->real_type() == MYSQL_TYPE_ENUM ||
857 from->real_type() == MYSQL_TYPE_SET)
858 if (to->result_type() != STRING_RESULT)
859 return do_field_int; // Convert SET to number
860 return do_field_string;
861 }
862 if (to->real_type() == MYSQL_TYPE_ENUM ||
863 to->real_type() == MYSQL_TYPE_SET)
864 {
865 if (!to->eq_def(from))
866 {
867 if (from->real_type() == MYSQL_TYPE_ENUM &&
868 to->real_type() == MYSQL_TYPE_ENUM)
869 return do_field_enum;
870 else
871 return do_field_string;
872 }
873 }
874 else if (to->charset() != from->charset())
875 return do_field_string;
876 else if (to->real_type() == MYSQL_TYPE_VARCHAR)
877 {
878 if (((Field_varstring*) to)->length_bytes !=
879 ((Field_varstring*) from)->length_bytes)
880 return do_field_string;
881 else
882 return do_varstring;
883 }
884 else if (m_to_length < m_from_length)
885 return (from->charset()->mbmaxlen == 1 ?
886 do_cut_string : do_cut_string_complex);
887 else if (m_to_length > m_from_length)
888 {
889 if (to->charset() == &my_charset_bin)
890 return do_expand_binary;
891 else
892 return do_expand_string;
893 }
894
895 }
896 else if (to->real_type() != from->real_type() ||
897 m_to_length != m_from_length ||
898 !compatible_db_low_byte_first)
899 {
900 if (to->real_type() == MYSQL_TYPE_DECIMAL ||
901 to->result_type() == STRING_RESULT)
902 return do_field_string;
903 if (to->result_type() == INT_RESULT)
904 return do_field_int;
905 return do_field_real;
906 }
907 else
908 {
909 if (!to->eq_def(from) || !compatible_db_low_byte_first)
910 {
911 if (to->real_type() == MYSQL_TYPE_DECIMAL)
912 return do_field_string;
913 if (to->result_type() == INT_RESULT)
914 return do_field_int;
915 else
916 return do_field_real;
917 }
918 }
919 }
920 /* Eq fields */
921 switch (m_to_length) {
922 case 1: return do_field_1;
923 case 2: return do_field_2;
924 case 3: return do_field_3;
925 case 4: return do_field_4;
926 case 6: return do_field_6;
927 case 8: return do_field_8;
928 }
929 return do_field_eq;
930 }
931
is_blob_type(Field * to)932 static inline bool is_blob_type(Field *to)
933 {
934 return (to->type() == MYSQL_TYPE_BLOB || to->type() == MYSQL_TYPE_GEOMETRY);
935 }
936
937 /** Simple quick field convert that is called on insert. */
938
field_conv(Field * to,Field * from)939 type_conversion_status field_conv(Field *to,Field *from)
940 {
941 const int from_type= from->type();
942 const int to_type= to->type();
943
944 if ((to_type == MYSQL_TYPE_JSON) && (from_type == MYSQL_TYPE_JSON))
945 {
946 Field_json *to_json= down_cast<Field_json*>(to);
947 Field_json *from_json= down_cast<Field_json*>(from);
948 return to_json->store(from_json);
949 }
950
951 if (to->real_type() == from->real_type() &&
952 !((is_blob_type(to)) &&
953 to->table->copy_blobs) && to->charset() == from->charset())
954 {
955 if (to->real_type() == MYSQL_TYPE_VARCHAR &&
956 from->real_type() == MYSQL_TYPE_VARCHAR)
957 {
958 Field_varstring *to_vc= static_cast<Field_varstring*>(to);
959 const Field_varstring *from_vc= static_cast<Field_varstring*>(from);
960 if (to_vc->length_bytes == from_vc->length_bytes)
961 {
962 copy_field_varstring(to_vc, from_vc);
963 return TYPE_OK;
964 }
965 }
966 if (to->pack_length() == from->pack_length() &&
967 !(to->flags & UNSIGNED_FLAG && !(from->flags & UNSIGNED_FLAG)) &&
968 to->real_type() != MYSQL_TYPE_ENUM &&
969 to->real_type() != MYSQL_TYPE_SET &&
970 to->real_type() != MYSQL_TYPE_BIT &&
971 (!to->is_temporal_with_time() ||
972 to->decimals() == from->decimals()) &&
973 (to->real_type() != MYSQL_TYPE_NEWDECIMAL ||
974 (to->field_length == from->field_length &&
975 (((Field_num*)to)->dec == ((Field_num*)from)->dec))) &&
976 to->table->s->db_low_byte_first == from->table->s->db_low_byte_first &&
977 (!(to->table->in_use->variables.sql_mode &
978 (MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE | MODE_INVALID_DATES)) ||
979 (to->type() != MYSQL_TYPE_DATE &&
980 to->type() != MYSQL_TYPE_DATETIME &&
981 (!to->table->in_use->variables.explicit_defaults_for_timestamp ||
982 to->type() != MYSQL_TYPE_TIMESTAMP))) &&
983 (from->real_type() != MYSQL_TYPE_VARCHAR))
984 { // Identical fields
985 // to->ptr==from->ptr may happen if one does 'UPDATE ... SET x=x'
986 memmove(to->ptr, from->ptr, to->pack_length());
987 return TYPE_OK;
988 }
989 }
990 if (to->type() == MYSQL_TYPE_BLOB)
991 { // Be sure the value is stored
992 Field_blob *blob=(Field_blob*) to;
993 from->val_str(&blob->value);
994
995 /*
996 Copy value if copy_blobs is set, or source is part of the table's
997 writeset.
998 */
999 if (to->table->copy_blobs ||
1000 (!blob->value.is_alloced() && from->is_updatable()))
1001 blob->value.copy();
1002
1003 return blob->store(blob->value.ptr(),blob->value.length(),from->charset());
1004 }
1005 if (from->real_type() == MYSQL_TYPE_ENUM &&
1006 to->real_type() == MYSQL_TYPE_ENUM &&
1007 from->val_int() == 0)
1008 {
1009 ((Field_enum *)(to))->store_type(0);
1010 return TYPE_OK;
1011 }
1012 else if (from->is_temporal() && to->result_type() == INT_RESULT)
1013 {
1014 MYSQL_TIME ltime;
1015 longlong nr;
1016 if (from->type() == MYSQL_TYPE_TIME)
1017 {
1018 from->get_time(<ime);
1019 nr= TIME_to_ulonglong_time_round(<ime);
1020 }
1021 else
1022 {
1023 from->get_date(<ime, TIME_FUZZY_DATE);
1024 nr= TIME_to_ulonglong_datetime_round(<ime);
1025 }
1026 return to->store(ltime.neg ? -nr : nr, 0);
1027 }
1028 else if (from->is_temporal() &&
1029 (to->result_type() == REAL_RESULT ||
1030 to->result_type() == DECIMAL_RESULT ||
1031 to->result_type() == INT_RESULT))
1032 {
1033 my_decimal tmp;
1034 /*
1035 We prefer DECIMAL as the safest precise type:
1036 double supports only 15 digits, which is not enough for DATETIME(6).
1037 */
1038 return to->store_decimal(from->val_decimal(&tmp));
1039 }
1040 else if (from->is_temporal() && to->is_temporal())
1041 {
1042 return copy_time_to_time(from, to);
1043 }
1044 else if (from_type == MYSQL_TYPE_JSON &&
1045 (to_type == MYSQL_TYPE_TINY ||
1046 to_type == MYSQL_TYPE_SHORT ||
1047 to_type == MYSQL_TYPE_INT24 ||
1048 to_type == MYSQL_TYPE_LONG ||
1049 to_type == MYSQL_TYPE_LONGLONG))
1050 {
1051 return to->store(from->val_int(), from->flags & UNSIGNED_FLAG);
1052 }
1053 else if (from_type == MYSQL_TYPE_JSON &&
1054 to_type == MYSQL_TYPE_NEWDECIMAL)
1055 {
1056 my_decimal buff;
1057 return to->store_decimal(from->val_decimal(&buff));
1058 }
1059 else if (from_type == MYSQL_TYPE_JSON &&
1060 (to_type == MYSQL_TYPE_FLOAT ||
1061 to_type == MYSQL_TYPE_DOUBLE))
1062 {
1063 return to->store(from->val_real());
1064 }
1065 else if (from_type == MYSQL_TYPE_JSON &&
1066 to->is_temporal())
1067 {
1068 MYSQL_TIME ltime;
1069 if (from->get_time(<ime))
1070 return TYPE_ERR_BAD_VALUE;
1071 return to->store_time(<ime);
1072 }
1073 else if ((from->result_type() == STRING_RESULT &&
1074 (to->result_type() == STRING_RESULT ||
1075 (from->real_type() != MYSQL_TYPE_ENUM &&
1076 from->real_type() != MYSQL_TYPE_SET))) ||
1077 to->type() == MYSQL_TYPE_DECIMAL)
1078 {
1079 char buff[MAX_FIELD_WIDTH];
1080 String result(buff,sizeof(buff),from->charset());
1081 from->val_str(&result);
1082 /*
1083 We use c_ptr_quick() here to make it easier if to is a float/double
1084 as the conversion routines will do a copy of the result doesn't
1085 end with \0. Can be replaced with .ptr() when we have our own
1086 string->double conversion.
1087 */
1088 return to->store(result.c_ptr_quick(),result.length(),from->charset());
1089 }
1090 else if (from->result_type() == REAL_RESULT)
1091 return to->store(from->val_real());
1092 else if (from->result_type() == DECIMAL_RESULT)
1093 {
1094 my_decimal buff;
1095 return to->store_decimal(from->val_decimal(&buff));
1096 }
1097 else
1098 return to->store(from->val_int(), MY_TEST(from->flags & UNSIGNED_FLAG));
1099 }
1100