1 /* Copyright (c) 2000, 2016, Oracle and/or its affiliates.
2 Copyright (c) 2010, 2020, MariaDB Corporation
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; version 2 of the License.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12
13 You should have received a copy of the GNU General Public License
14 along with this program; if not, write to the Free Software
15 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA */
16
17
18 /**
19 @file
20
21 @brief
22 Functions to copy data to or from fields
23
24 This could be done with a single short function but opencoding this
25 gives much more speed.
26 */
27
28 #include "mariadb.h"
29 #include "sql_priv.h"
30 #include "sql_class.h" // THD
31 #include <m_ctype.h>
32
do_field_eq(Copy_field * copy)33 void Field::do_field_eq(Copy_field *copy)
34 {
35 memcpy(copy->to_ptr,copy->from_ptr,copy->from_length);
36 }
37
do_field_1(Copy_field * copy)38 static void do_field_1(Copy_field *copy)
39 {
40 copy->to_ptr[0]=copy->from_ptr[0];
41 }
42
do_field_2(Copy_field * copy)43 static void do_field_2(Copy_field *copy)
44 {
45 copy->to_ptr[0]=copy->from_ptr[0];
46 copy->to_ptr[1]=copy->from_ptr[1];
47 }
48
do_field_3(Copy_field * copy)49 static void do_field_3(Copy_field *copy)
50 {
51 copy->to_ptr[0]=copy->from_ptr[0];
52 copy->to_ptr[1]=copy->from_ptr[1];
53 copy->to_ptr[2]=copy->from_ptr[2];
54 }
55
do_field_4(Copy_field * copy)56 static void do_field_4(Copy_field *copy)
57 {
58 copy->to_ptr[0]=copy->from_ptr[0];
59 copy->to_ptr[1]=copy->from_ptr[1];
60 copy->to_ptr[2]=copy->from_ptr[2];
61 copy->to_ptr[3]=copy->from_ptr[3];
62 }
63
do_field_6(Copy_field * copy)64 static void do_field_6(Copy_field *copy)
65 { // For blob field
66 copy->to_ptr[0]=copy->from_ptr[0];
67 copy->to_ptr[1]=copy->from_ptr[1];
68 copy->to_ptr[2]=copy->from_ptr[2];
69 copy->to_ptr[3]=copy->from_ptr[3];
70 copy->to_ptr[4]=copy->from_ptr[4];
71 copy->to_ptr[5]=copy->from_ptr[5];
72 }
73
do_field_8(Copy_field * copy)74 static void do_field_8(Copy_field *copy)
75 {
76 copy->to_ptr[0]=copy->from_ptr[0];
77 copy->to_ptr[1]=copy->from_ptr[1];
78 copy->to_ptr[2]=copy->from_ptr[2];
79 copy->to_ptr[3]=copy->from_ptr[3];
80 copy->to_ptr[4]=copy->from_ptr[4];
81 copy->to_ptr[5]=copy->from_ptr[5];
82 copy->to_ptr[6]=copy->from_ptr[6];
83 copy->to_ptr[7]=copy->from_ptr[7];
84 }
85
86
do_field_to_null_str(Copy_field * copy)87 static void do_field_to_null_str(Copy_field *copy)
88 {
89 if (*copy->from_null_ptr & copy->from_bit)
90 {
91 bzero(copy->to_ptr,copy->from_length);
92 copy->to_null_ptr[0]=1; // Always bit 1
93 }
94 else
95 {
96 copy->to_null_ptr[0]=0;
97 memcpy(copy->to_ptr,copy->from_ptr,copy->from_length);
98 }
99 }
100
101
do_outer_field_to_null_str(Copy_field * copy)102 static void do_outer_field_to_null_str(Copy_field *copy)
103 {
104 if (*copy->null_row ||
105 (copy->from_null_ptr && (*copy->from_null_ptr & copy->from_bit)))
106 {
107 bzero(copy->to_ptr,copy->from_length);
108 copy->to_null_ptr[0]=1; // Always bit 1
109 }
110 else
111 {
112 copy->to_null_ptr[0]=0;
113 memcpy(copy->to_ptr,copy->from_ptr,copy->from_length);
114 }
115 }
116
117
set_bad_null_error(Field * field,int err)118 static int set_bad_null_error(Field *field, int err)
119 {
120 switch (field->table->in_use->count_cuted_fields) {
121 case CHECK_FIELD_WARN:
122 field->set_warning(Sql_condition::WARN_LEVEL_WARN, err, 1);
123 /* fall through */
124 case CHECK_FIELD_IGNORE:
125 case CHECK_FIELD_EXPRESSION:
126 return 0;
127 case CHECK_FIELD_ERROR_FOR_NULL:
128 if (!field->table->in_use->no_errors)
129 my_error(ER_BAD_NULL_ERROR, MYF(0), field->field_name.str);
130 return -1;
131 }
132 DBUG_ASSERT(0); // impossible
133 return -1;
134 }
135
136
set_field_to_null(Field * field)137 int set_field_to_null(Field *field)
138 {
139 if (field->table->null_catch_flags & CHECK_ROW_FOR_NULLS_TO_REJECT)
140 {
141 field->table->null_catch_flags|= REJECT_ROW_DUE_TO_NULL_FIELDS;
142 return -1;
143 }
144 if (field->real_maybe_null())
145 {
146 field->set_null();
147 field->reset();
148 return 0;
149 }
150 field->reset();
151 return set_bad_null_error(field, WARN_DATA_TRUNCATED);
152 }
153
154
155 /**
156 Set TIMESTAMP to NOW(), AUTO_INCREMENT to the next number, or report an error
157
158 @param field Field to update
159
160 @retval
161 0 Field could take 0 or an automatic conversion was used
162 @retval
163 -1 Field could not take NULL and no conversion was used.
164 If no_conversion was not set, an error message is printed
165 */
166
convert_null_to_field_value_or_error(Field * field)167 int convert_null_to_field_value_or_error(Field *field)
168 {
169 if (field->type() == MYSQL_TYPE_TIMESTAMP)
170 {
171 field->set_time();
172 return 0;
173 }
174
175 field->reset(); // Note: we ignore any potential failure of reset() here.
176
177 if (field == field->table->next_number_field)
178 {
179 field->table->auto_increment_field_not_null= FALSE;
180 return 0; // field is set in fill_record()
181 }
182 return set_bad_null_error(field, ER_BAD_NULL_ERROR);
183 }
184
185 /**
186 Set field to NULL or TIMESTAMP or to next auto_increment number.
187
188 @param field Field to update
189 @param no_conversions Set to 1 if we should return 1 if field can't
190 take null values.
191 If set to 0 we will do store the 'default value'
192 if the field is a special field. If not we will
193 give an error.
194
195 @retval
196 0 Field could take 0 or an automatic conversion was used
197 @retval
198 -1 Field could not take NULL and no conversion was used.
199 If no_conversion was not set, an error message is printed
200 */
201
202 int
set_field_to_null_with_conversions(Field * field,bool no_conversions)203 set_field_to_null_with_conversions(Field *field, bool no_conversions)
204 {
205 if (field->table->null_catch_flags & CHECK_ROW_FOR_NULLS_TO_REJECT)
206 {
207 field->table->null_catch_flags|= REJECT_ROW_DUE_TO_NULL_FIELDS;
208 return -1;
209 }
210 if (field->real_maybe_null())
211 {
212 field->set_null();
213 field->reset();
214 return 0;
215 }
216 if (no_conversions)
217 return -1;
218
219 return convert_null_to_field_value_or_error(field);
220 }
221
222
do_skip(Copy_field * copy)223 static void do_skip(Copy_field *copy __attribute__((unused)))
224 {
225 }
226
227
228 /*
229 Copy: (NULLable field) -> (NULLable field)
230
231 note: if the record we're copying from is NULL-complemetned (i.e.
232 from_field->table->null_row==1), it will also have all NULLable columns to be
233 set to NULLs, so we don't need to check table->null_row here.
234 */
235
do_copy_null(Copy_field * copy)236 static void do_copy_null(Copy_field *copy)
237 {
238 if (*copy->from_null_ptr & copy->from_bit)
239 {
240 *copy->to_null_ptr|=copy->to_bit;
241 copy->to_field->reset();
242 }
243 else
244 {
245 *copy->to_null_ptr&= ~copy->to_bit;
246 (copy->do_copy2)(copy);
247 }
248 }
249
250 /*
251 Copy: (not-NULL field in table that can be NULL-complemented) -> (NULLable
252 field)
253 */
254
do_outer_field_null(Copy_field * copy)255 static void do_outer_field_null(Copy_field *copy)
256 {
257 if (*copy->null_row ||
258 (copy->from_null_ptr && (*copy->from_null_ptr & copy->from_bit)))
259 {
260 *copy->to_null_ptr|=copy->to_bit;
261 copy->to_field->reset();
262 }
263 else
264 {
265 *copy->to_null_ptr&= ~copy->to_bit;
266 (copy->do_copy2)(copy);
267 }
268 }
269
270 /*
271 Copy: (not-NULL field in table that can be NULL-complemented) -> (not-NULL
272 field)
273 */
do_copy_nullable_row_to_notnull(Copy_field * copy)274 static void do_copy_nullable_row_to_notnull(Copy_field *copy)
275 {
276 if (*copy->null_row ||
277 (copy->from_null_ptr && (*copy->from_null_ptr & copy->from_bit)))
278 {
279 copy->to_field->set_warning(Sql_condition::WARN_LEVEL_WARN,
280 WARN_DATA_TRUNCATED, 1);
281 copy->to_field->reset();
282 }
283 else
284 {
285 (copy->do_copy2)(copy);
286 }
287
288 }
289
290 /* Copy: (NULL-able field) -> (not NULL-able field) */
do_copy_not_null(Copy_field * copy)291 static void do_copy_not_null(Copy_field *copy)
292 {
293 if (*copy->from_null_ptr & copy->from_bit)
294 {
295 copy->to_field->set_warning(Sql_condition::WARN_LEVEL_WARN,
296 WARN_DATA_TRUNCATED, 1);
297 copy->to_field->reset();
298 }
299 else
300 (copy->do_copy2)(copy);
301 }
302
303
304 /* Copy: (non-NULLable field) -> (NULLable field) */
do_copy_maybe_null(Copy_field * copy)305 static void do_copy_maybe_null(Copy_field *copy)
306 {
307 *copy->to_null_ptr&= ~copy->to_bit;
308 (copy->do_copy2)(copy);
309 }
310
311 /* timestamp and next_number has special handling in case of NULL values */
312
do_copy_timestamp(Copy_field * copy)313 static void do_copy_timestamp(Copy_field *copy)
314 {
315 if (*copy->from_null_ptr & copy->from_bit)
316 {
317 /* Same as in set_field_to_null_with_conversions() */
318 copy->to_field->set_time();
319 }
320 else
321 (copy->do_copy2)(copy);
322 }
323
324
do_copy_next_number(Copy_field * copy)325 static void do_copy_next_number(Copy_field *copy)
326 {
327 if (*copy->from_null_ptr & copy->from_bit)
328 {
329 /* Same as in set_field_to_null_with_conversions() */
330 copy->to_field->table->auto_increment_field_not_null= FALSE;
331 copy->to_field->reset();
332 }
333 else
334 (copy->do_copy2)(copy);
335 }
336
337
do_copy_blob(Copy_field * copy)338 void Field_blob::do_copy_blob(Copy_field *copy)
339 {
340 ((Field_blob*) copy->to_field)->copy_value(((Field_blob*) copy->from_field));
341 }
342
do_conv_blob(Copy_field * copy)343 void Field_blob::do_conv_blob(Copy_field *copy)
344 {
345 copy->from_field->val_str(©->tmp);
346 ((Field_blob *) copy->to_field)->store(copy->tmp.ptr(),
347 copy->tmp.length(),
348 copy->tmp.charset());
349 }
350
351 /** Save blob in copy->tmp for GROUP BY. */
352
do_save_blob(Copy_field * copy)353 static void do_save_blob(Copy_field *copy)
354 {
355 char buff[MAX_FIELD_WIDTH];
356 String res(buff,sizeof(buff),copy->tmp.charset());
357 copy->from_field->val_str(&res);
358 copy->tmp.copy(res);
359 ((Field_blob *) copy->to_field)->store(copy->tmp.ptr(),
360 copy->tmp.length(),
361 copy->tmp.charset());
362 }
363
364
do_field_string(Copy_field * copy)365 void Field::do_field_string(Copy_field *copy)
366 {
367 char buff[MAX_FIELD_WIDTH];
368 String res(buff, sizeof(buff), copy->from_field->charset());
369 res.length(0U);
370
371 copy->from_field->val_str(&res);
372 copy->to_field->store(res.c_ptr_quick(), res.length(), res.charset());
373 }
374
375
do_field_enum(Copy_field * copy)376 void Field_enum::do_field_enum(Copy_field *copy)
377 {
378 if (copy->from_field->val_int() == 0)
379 ((Field_enum *) copy->to_field)->store_type((ulonglong) 0);
380 else
381 do_field_string(copy);
382 }
383
384
do_field_varbinary_pre50(Copy_field * copy)385 static void do_field_varbinary_pre50(Copy_field *copy)
386 {
387 char buff[MAX_FIELD_WIDTH];
388 copy->tmp.set_quick(buff,sizeof(buff),copy->tmp.charset());
389 copy->from_field->val_str(©->tmp);
390
391 /* Use the same function as in 4.1 to trim trailing spaces */
392 size_t length= my_lengthsp_8bit(&my_charset_bin, copy->tmp.c_ptr_quick(),
393 copy->from_field->field_length);
394
395 copy->to_field->store(copy->tmp.c_ptr_quick(), length,
396 copy->tmp.charset());
397 }
398
399
do_field_int(Copy_field * copy)400 void Field::do_field_int(Copy_field *copy)
401 {
402 longlong value= copy->from_field->val_int();
403 copy->to_field->store(value,
404 MY_TEST(copy->from_field->flags & UNSIGNED_FLAG));
405 }
406
do_field_real(Copy_field * copy)407 void Field::do_field_real(Copy_field *copy)
408 {
409 double value=copy->from_field->val_real();
410 copy->to_field->store(value);
411 }
412
413
do_field_decimal(Copy_field * copy)414 void Field::do_field_decimal(Copy_field *copy)
415 {
416 my_decimal value(copy->from_field);
417 copy->to_field->store_decimal(&value);
418 }
419
420
do_field_timestamp(Copy_field * copy)421 void Field::do_field_timestamp(Copy_field *copy)
422 {
423 // XXX why couldn't we do it everywhere?
424 copy->from_field->save_in_field(copy->to_field);
425 }
426
427
do_field_temporal(Copy_field * copy,date_mode_t fuzzydate)428 void Field::do_field_temporal(Copy_field *copy, date_mode_t fuzzydate)
429 {
430 MYSQL_TIME ltime;
431 // TODO: we now need to check result
432 if (copy->from_field->get_date(<ime, fuzzydate))
433 copy->to_field->reset();
434 else
435 copy->to_field->store_time_dec(<ime, copy->from_field->decimals());
436 }
437
438
do_field_datetime(Copy_field * copy)439 void Field::do_field_datetime(Copy_field *copy)
440 {
441 return do_field_temporal(copy, Datetime::Options(TIME_CONV_NONE, current_thd));
442 }
443
444
do_field_date(Copy_field * copy)445 void Field::do_field_date(Copy_field *copy)
446 {
447 return do_field_temporal(copy, Date::Options(TIME_CONV_NONE));
448 }
449
450
do_field_time(Copy_field * copy)451 void Field_time::do_field_time(Copy_field *copy)
452 {
453 return do_field_temporal(copy, Time::Options(current_thd));
454 }
455
456
457 /**
458 string copy for single byte characters set when to string is shorter than
459 from string.
460 */
461
do_cut_string(Copy_field * copy)462 static void do_cut_string(Copy_field *copy)
463 {
464 CHARSET_INFO *cs= copy->from_field->charset();
465 memcpy(copy->to_ptr,copy->from_ptr,copy->to_length);
466
467 /* Check if we loosed any important characters */
468 if (cs->scan((char*) copy->from_ptr + copy->to_length,
469 (char*) copy->from_ptr + copy->from_length,
470 MY_SEQ_SPACES) < copy->from_length - copy->to_length)
471 {
472 copy->to_field->set_warning(Sql_condition::WARN_LEVEL_WARN,
473 WARN_DATA_TRUNCATED, 1);
474 }
475 }
476
477
478 /**
479 string copy for multi byte characters set when to string is shorter than
480 from string.
481 */
482
do_cut_string_complex(Copy_field * copy)483 static void do_cut_string_complex(Copy_field *copy)
484 { // Shorter string field
485 CHARSET_INFO *cs= copy->from_field->charset();
486 const uchar *from_end= copy->from_ptr + copy->from_length;
487 Well_formed_prefix prefix(cs,
488 (char*) copy->from_ptr,
489 (char*) from_end,
490 copy->to_length / cs->mbmaxlen);
491 size_t copy_length= prefix.length();
492 if (copy->to_length < copy_length)
493 copy_length= copy->to_length;
494 memcpy(copy->to_ptr, copy->from_ptr, copy_length);
495
496 /* Check if we lost any important characters */
497 if (unlikely(prefix.well_formed_error_pos() ||
498 cs->scan((char*) copy->from_ptr + copy_length,
499 (char*) from_end,
500 MY_SEQ_SPACES) <
501 (copy->from_length - copy_length)))
502 {
503 copy->to_field->set_warning(Sql_condition::WARN_LEVEL_WARN,
504 WARN_DATA_TRUNCATED, 1);
505 }
506
507 if (copy_length < copy->to_length)
508 cs->fill((char*) copy->to_ptr + copy_length,
509 copy->to_length - copy_length, ' ');
510 }
511
512
513
514
do_expand_binary(Copy_field * copy)515 static void do_expand_binary(Copy_field *copy)
516 {
517 CHARSET_INFO *cs= copy->from_field->charset();
518 memcpy(copy->to_ptr,copy->from_ptr,copy->from_length);
519 cs->fill((char*) copy->to_ptr+copy->from_length,
520 copy->to_length-copy->from_length, '\0');
521 }
522
523
524
do_expand_string(Copy_field * copy)525 static void do_expand_string(Copy_field *copy)
526 {
527 CHARSET_INFO *cs= copy->from_field->charset();
528 memcpy(copy->to_ptr,copy->from_ptr,copy->from_length);
529 cs->fill((char*) copy->to_ptr+copy->from_length,
530 copy->to_length-copy->from_length, ' ');
531 }
532
533
do_varstring1(Copy_field * copy)534 static void do_varstring1(Copy_field *copy)
535 {
536 uint length= (uint) *(uchar*) copy->from_ptr;
537 if (length > copy->to_length- 1)
538 {
539 length=copy->to_length - 1;
540 if (copy->from_field->table->in_use->count_cuted_fields >
541 CHECK_FIELD_EXPRESSION &&
542 copy->to_field)
543 copy->to_field->set_warning(Sql_condition::WARN_LEVEL_WARN,
544 WARN_DATA_TRUNCATED, 1);
545 }
546 *(uchar*) copy->to_ptr= (uchar) length;
547 memcpy(copy->to_ptr+1, copy->from_ptr + 1, length);
548 }
549
550
do_varstring1_mb(Copy_field * copy)551 static void do_varstring1_mb(Copy_field *copy)
552 {
553 CHARSET_INFO *cs= copy->from_field->charset();
554 uint from_length= (uint) *(uchar*) copy->from_ptr;
555 const uchar *from_ptr= copy->from_ptr + 1;
556 uint to_char_length= (copy->to_length - 1) / cs->mbmaxlen;
557 Well_formed_prefix prefix(cs, (char*) from_ptr, from_length, to_char_length);
558 if (prefix.length() < from_length)
559 {
560 if (current_thd->count_cuted_fields > CHECK_FIELD_EXPRESSION)
561 copy->to_field->set_warning(Sql_condition::WARN_LEVEL_WARN,
562 WARN_DATA_TRUNCATED, 1);
563 }
564 *copy->to_ptr= (uchar) prefix.length();
565 memcpy(copy->to_ptr + 1, from_ptr, prefix.length());
566 }
567
568
do_varstring2(Copy_field * copy)569 static void do_varstring2(Copy_field *copy)
570 {
571 uint length=uint2korr(copy->from_ptr);
572 if (length > copy->to_length- HA_KEY_BLOB_LENGTH)
573 {
574 length=copy->to_length-HA_KEY_BLOB_LENGTH;
575 if (copy->from_field->table->in_use->count_cuted_fields >
576 CHECK_FIELD_EXPRESSION &&
577 copy->to_field)
578 copy->to_field->set_warning(Sql_condition::WARN_LEVEL_WARN,
579 WARN_DATA_TRUNCATED, 1);
580 }
581 int2store(copy->to_ptr,length);
582 memcpy(copy->to_ptr+HA_KEY_BLOB_LENGTH, copy->from_ptr + HA_KEY_BLOB_LENGTH,
583 length);
584 }
585
586
do_varstring2_mb(Copy_field * copy)587 static void do_varstring2_mb(Copy_field *copy)
588 {
589 CHARSET_INFO *cs= copy->from_field->charset();
590 uint char_length= (copy->to_length - HA_KEY_BLOB_LENGTH) / cs->mbmaxlen;
591 uint from_length= uint2korr(copy->from_ptr);
592 const uchar *from_beg= copy->from_ptr + HA_KEY_BLOB_LENGTH;
593 Well_formed_prefix prefix(cs, (char*) from_beg, from_length, char_length);
594 if (prefix.length() < from_length)
595 {
596 if (current_thd->count_cuted_fields > CHECK_FIELD_EXPRESSION)
597 copy->to_field->set_warning(Sql_condition::WARN_LEVEL_WARN,
598 WARN_DATA_TRUNCATED, 1);
599 }
600 int2store(copy->to_ptr, prefix.length());
601 memcpy(copy->to_ptr+HA_KEY_BLOB_LENGTH, from_beg, prefix.length());
602 }
603
604
605 /***************************************************************************
606 ** The different functions that fills in a Copy_field class
607 ***************************************************************************/
608
609 /**
610 copy of field to maybe null string.
611 If field is null then the all bytes are set to 0.
612 if field is not null then the first byte is set to 1 and the rest of the
613 string is the field value.
614 The 'to' buffer should have a size of field->pack_length()+1
615 */
616
set(uchar * to,Field * from)617 void Copy_field::set(uchar *to,Field *from)
618 {
619 from_ptr=from->ptr;
620 to_ptr=to;
621 from_length=from->pack_length_in_rec();
622 if (from->maybe_null())
623 {
624 from_null_ptr=from->null_ptr;
625 from_bit= from->null_bit;
626 to_ptr[0]= 1; // Null as default value
627 to_null_ptr= (uchar*) to_ptr++;
628 to_bit= 1;
629 if (from->table->maybe_null)
630 {
631 null_row= &from->table->null_row;
632 do_copy= do_outer_field_to_null_str;
633 }
634 else
635 do_copy= do_field_to_null_str;
636 }
637 else
638 {
639 to_null_ptr= 0; // For easy debugging
640 do_copy= Field::do_field_eq;
641 }
642 }
643
644
645 /*
646 To do:
647
648 If 'save' is set to true and the 'from' is a blob field, do_copy is set to
649 do_save_blob rather than do_conv_blob. The only differences between them
650 appears to be:
651
652 - do_save_blob allocates and uses an intermediate buffer before calling
653 Field_blob::store. Is this in order to trigger the call to
654 well_formed_copy_nchars, by changing the pointer copy->tmp.ptr()?
655 That call will take place anyway in all known cases.
656 */
set(Field * to,Field * from,bool save)657 void Copy_field::set(Field *to,Field *from,bool save)
658 {
659 if (to->type() == MYSQL_TYPE_NULL)
660 {
661 to_null_ptr=0; // For easy debugging
662 to_ptr=0;
663 do_copy=do_skip;
664 return;
665 }
666 from_field=from;
667 to_field=to;
668 from_ptr=from->ptr;
669 from_length=from->pack_length_in_rec();
670 to_ptr= to->ptr;
671 to_length=to_field->pack_length_in_rec();
672
673 // set up null handling
674 from_null_ptr=to_null_ptr=0;
675 if (from->maybe_null())
676 {
677 from_null_ptr= from->null_ptr;
678 from_bit= from->null_bit;
679 if (to_field->real_maybe_null())
680 {
681 to_null_ptr= to->null_ptr;
682 to_bit= to->null_bit;
683 if (from_null_ptr)
684 do_copy= do_copy_null;
685 else
686 {
687 null_row= &from->table->null_row;
688 do_copy= do_outer_field_null;
689 }
690 }
691 else
692 {
693 if (to_field->type() == MYSQL_TYPE_TIMESTAMP)
694 do_copy= do_copy_timestamp; // Automatic timestamp
695 else if (to_field == to_field->table->next_number_field)
696 do_copy= do_copy_next_number;
697 else
698 {
699 if (!from_null_ptr)
700 {
701 null_row= &from->table->null_row;
702 do_copy= do_copy_nullable_row_to_notnull;
703 }
704 else
705 do_copy= do_copy_not_null;
706 }
707 }
708 }
709 else if (to_field->real_maybe_null())
710 {
711 to_null_ptr= to->null_ptr;
712 to_bit= to->null_bit;
713 do_copy= do_copy_maybe_null;
714 }
715 else
716 do_copy=0;
717
718 if ((to->flags & BLOB_FLAG) && save)
719 do_copy2= do_save_blob;
720 else
721 do_copy2= from->get_copy_func_to(to);
722 if (!do_copy) // Not null
723 do_copy=do_copy2;
724 }
725
726
get_copy_func(const Field * from) const727 Field::Copy_func *Field_timestamp::get_copy_func(const Field *from) const
728 {
729 Field::Copy_func *copy= Field_temporal::get_copy_func(from);
730 if (copy == do_field_datetime && from->type() == MYSQL_TYPE_TIMESTAMP)
731 return do_field_timestamp;
732 else
733 return copy;
734 }
735
736
get_copy_func(const Field * from) const737 Field::Copy_func *Field_date_common::get_copy_func(const Field *from) const
738 {
739 Field::Copy_func *copy= Field_temporal::get_copy_func(from);
740 return copy == do_field_datetime ? do_field_date : copy;
741 }
742
743
get_copy_func(const Field * from) const744 Field::Copy_func *Field_temporal::get_copy_func(const Field *from) const
745 {
746 /* If types are not 100 % identical then convert trough get_date() */
747 if (from->cmp_type() == REAL_RESULT)
748 return do_field_string; // TODO: MDEV-9344
749 if (from->type() == MYSQL_TYPE_YEAR)
750 return do_field_string; // TODO: MDEV-9343
751 if (from->type() == MYSQL_TYPE_BIT)
752 return do_field_int;
753 if (!eq_def(from) ||
754 (table->in_use->variables.sql_mode &
755 (MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE)))
756 return do_field_datetime;
757 return get_identical_copy_func();
758 }
759
760
get_copy_func(const Field * from) const761 Field::Copy_func *Field_varstring::get_copy_func(const Field *from) const
762 {
763 if (from->type() == MYSQL_TYPE_BIT)
764 return do_field_int;
765 /*
766 Detect copy from pre 5.0 varbinary to varbinary as of 5.0 and
767 use special copy function that removes trailing spaces and thus
768 repairs data.
769 */
770 if (from->type() == MYSQL_TYPE_VAR_STRING && !from->has_charset() &&
771 !Field_varstring::has_charset())
772 return do_field_varbinary_pre50;
773 if (Field_varstring::real_type() != from->real_type() ||
774 Field_varstring::charset() != from->charset() ||
775 length_bytes != ((const Field_varstring*) from)->length_bytes ||
776 !compression_method() != !from->compression_method())
777 return do_field_string;
778 return length_bytes == 1 ?
779 (from->charset()->mbmaxlen == 1 ? do_varstring1 : do_varstring1_mb) :
780 (from->charset()->mbmaxlen == 1 ? do_varstring2 : do_varstring2_mb);
781 }
782
783
get_copy_func(const Field * from) const784 Field::Copy_func *Field_string::get_copy_func(const Field *from) const
785 {
786 if (from->type() == MYSQL_TYPE_BIT)
787 return do_field_int;
788 if (Field_string::type_handler() != from->type_handler() ||
789 Field_string::charset() != from->charset())
790 return do_field_string;
791 if (Field_string::pack_length() < from->pack_length())
792 return (Field_string::charset()->mbmaxlen == 1 ?
793 do_cut_string : do_cut_string_complex);
794 if (Field_string::pack_length() > from->pack_length())
795 return Field_string::charset() == &my_charset_bin ? do_expand_binary :
796 do_expand_string;
797 return get_identical_copy_func();
798 }
799
800
get_identical_copy_func() const801 Field::Copy_func *Field::get_identical_copy_func() const
802 {
803 /* Identical field types */
804 switch (pack_length()) {
805 case 1: return do_field_1;
806 case 2: return do_field_2;
807 case 3: return do_field_3;
808 case 4: return do_field_4;
809 case 6: return do_field_6;
810 case 8: return do_field_8;
811 }
812 return do_field_eq;
813 }
814
815
memcpy_field_possible(const Field * from) const816 bool Field_temporal::memcpy_field_possible(const Field *from) const
817 {
818 return real_type() == from->real_type() &&
819 decimals() == from->decimals() &&
820 !sql_mode_for_dates(table->in_use);
821 }
822
823
field_conv_memcpy(Field * to,Field * from)824 static int field_conv_memcpy(Field *to, Field *from)
825 {
826 /*
827 This may happen if one does 'UPDATE ... SET x=x'
828 The test is here mostly for valgrind, but can also be relevant
829 if memcpy() is implemented with prefetch-write
830 */
831 if (to->ptr != from->ptr)
832 memcpy(to->ptr,from->ptr, to->pack_length());
833 return 0;
834 }
835
836
837 /**
838 Copy value of the field with conversion.
839
840 @note Impossibility of simple copy should be checked before this call.
841
842 @param to The field to copy to
843
844 @retval TRUE ERROR
845 @retval FALSE OK
846
847 */
field_conv_incompatible(Field * to,Field * from)848 static int field_conv_incompatible(Field *to, Field *from)
849 {
850 return to->store_field(from);
851 }
852
853
854 /**
855 Simple quick field converter that is called on insert, e.g.:
856 INSERT INTO t1 (field1) SELECT field2 FROM t2;
857 */
858
field_conv(Field * to,Field * from)859 int field_conv(Field *to,Field *from)
860 {
861 return to->memcpy_field_possible(from) ?
862 field_conv_memcpy(to, from) :
863 field_conv_incompatible(to, from);
864 }
865
866
get_fast_field_copier(const Field * from)867 fast_field_copier Field::get_fast_field_copier(const Field *from)
868 {
869 DBUG_ENTER("Field::get_fast_field_copier");
870 DBUG_RETURN(memcpy_field_possible(from) ?
871 &field_conv_memcpy :
872 &field_conv_incompatible);
873 }
874