1 /* Copyright (c) 2000, 2016, Oracle and/or its affiliates.
2 Copyright (c) 2010, 2018, 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 static void 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_timestamp*) 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 ((Field_timestamp*) 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->cset->scan(cs,
469 (char*) copy->from_ptr + copy->to_length,
470 (char*) copy->from_ptr + copy->from_length,
471 MY_SEQ_SPACES) < copy->from_length - copy->to_length)
472 {
473 copy->to_field->set_warning(Sql_condition::WARN_LEVEL_WARN,
474 WARN_DATA_TRUNCATED, 1);
475 }
476 }
477
478
479 /**
480 string copy for multi byte characters set when to string is shorter than
481 from string.
482 */
483
do_cut_string_complex(Copy_field * copy)484 static void do_cut_string_complex(Copy_field *copy)
485 { // Shorter string field
486 CHARSET_INFO *cs= copy->from_field->charset();
487 const uchar *from_end= copy->from_ptr + copy->from_length;
488 Well_formed_prefix prefix(cs,
489 (char*) copy->from_ptr,
490 (char*) from_end,
491 copy->to_length / cs->mbmaxlen);
492 size_t copy_length= prefix.length();
493 if (copy->to_length < copy_length)
494 copy_length= copy->to_length;
495 memcpy(copy->to_ptr, copy->from_ptr, copy_length);
496
497 /* Check if we lost any important characters */
498 if (unlikely(prefix.well_formed_error_pos() ||
499 cs->cset->scan(cs, (char*) copy->from_ptr + copy_length,
500 (char*) from_end,
501 MY_SEQ_SPACES) <
502 (copy->from_length - copy_length)))
503 {
504 copy->to_field->set_warning(Sql_condition::WARN_LEVEL_WARN,
505 WARN_DATA_TRUNCATED, 1);
506 }
507
508 if (copy_length < copy->to_length)
509 cs->cset->fill(cs, (char*) copy->to_ptr + copy_length,
510 copy->to_length - copy_length, ' ');
511 }
512
513
514
515
do_expand_binary(Copy_field * copy)516 static void do_expand_binary(Copy_field *copy)
517 {
518 CHARSET_INFO *cs= copy->from_field->charset();
519 memcpy(copy->to_ptr,copy->from_ptr,copy->from_length);
520 cs->cset->fill(cs, (char*) copy->to_ptr+copy->from_length,
521 copy->to_length-copy->from_length, '\0');
522 }
523
524
525
do_expand_string(Copy_field * copy)526 static void do_expand_string(Copy_field *copy)
527 {
528 CHARSET_INFO *cs= copy->from_field->charset();
529 memcpy(copy->to_ptr,copy->from_ptr,copy->from_length);
530 cs->cset->fill(cs, (char*) copy->to_ptr+copy->from_length,
531 copy->to_length-copy->from_length, ' ');
532 }
533
534
do_varstring1(Copy_field * copy)535 static void do_varstring1(Copy_field *copy)
536 {
537 uint length= (uint) *(uchar*) copy->from_ptr;
538 if (length > copy->to_length- 1)
539 {
540 length=copy->to_length - 1;
541 if (copy->from_field->table->in_use->count_cuted_fields >
542 CHECK_FIELD_EXPRESSION &&
543 copy->to_field)
544 copy->to_field->set_warning(Sql_condition::WARN_LEVEL_WARN,
545 WARN_DATA_TRUNCATED, 1);
546 }
547 *(uchar*) copy->to_ptr= (uchar) length;
548 memcpy(copy->to_ptr+1, copy->from_ptr + 1, length);
549 }
550
551
do_varstring1_mb(Copy_field * copy)552 static void do_varstring1_mb(Copy_field *copy)
553 {
554 CHARSET_INFO *cs= copy->from_field->charset();
555 uint from_length= (uint) *(uchar*) copy->from_ptr;
556 const uchar *from_ptr= copy->from_ptr + 1;
557 uint to_char_length= (copy->to_length - 1) / cs->mbmaxlen;
558 Well_formed_prefix prefix(cs, (char*) from_ptr, from_length, to_char_length);
559 if (prefix.length() < from_length)
560 {
561 if (current_thd->count_cuted_fields > CHECK_FIELD_EXPRESSION)
562 copy->to_field->set_warning(Sql_condition::WARN_LEVEL_WARN,
563 WARN_DATA_TRUNCATED, 1);
564 }
565 *copy->to_ptr= (uchar) prefix.length();
566 memcpy(copy->to_ptr + 1, from_ptr, prefix.length());
567 }
568
569
do_varstring2(Copy_field * copy)570 static void do_varstring2(Copy_field *copy)
571 {
572 uint length=uint2korr(copy->from_ptr);
573 if (length > copy->to_length- HA_KEY_BLOB_LENGTH)
574 {
575 length=copy->to_length-HA_KEY_BLOB_LENGTH;
576 if (copy->from_field->table->in_use->count_cuted_fields >
577 CHECK_FIELD_EXPRESSION &&
578 copy->to_field)
579 copy->to_field->set_warning(Sql_condition::WARN_LEVEL_WARN,
580 WARN_DATA_TRUNCATED, 1);
581 }
582 int2store(copy->to_ptr,length);
583 memcpy(copy->to_ptr+HA_KEY_BLOB_LENGTH, copy->from_ptr + HA_KEY_BLOB_LENGTH,
584 length);
585 }
586
587
do_varstring2_mb(Copy_field * copy)588 static void do_varstring2_mb(Copy_field *copy)
589 {
590 CHARSET_INFO *cs= copy->from_field->charset();
591 uint char_length= (copy->to_length - HA_KEY_BLOB_LENGTH) / cs->mbmaxlen;
592 uint from_length= uint2korr(copy->from_ptr);
593 const uchar *from_beg= copy->from_ptr + HA_KEY_BLOB_LENGTH;
594 Well_formed_prefix prefix(cs, (char*) from_beg, from_length, char_length);
595 if (prefix.length() < from_length)
596 {
597 if (current_thd->count_cuted_fields > CHECK_FIELD_EXPRESSION)
598 copy->to_field->set_warning(Sql_condition::WARN_LEVEL_WARN,
599 WARN_DATA_TRUNCATED, 1);
600 }
601 int2store(copy->to_ptr, prefix.length());
602 memcpy(copy->to_ptr+HA_KEY_BLOB_LENGTH, from_beg, prefix.length());
603 }
604
605
606 /***************************************************************************
607 ** The different functions that fills in a Copy_field class
608 ***************************************************************************/
609
610 /**
611 copy of field to maybe null string.
612 If field is null then the all bytes are set to 0.
613 if field is not null then the first byte is set to 1 and the rest of the
614 string is the field value.
615 The 'to' buffer should have a size of field->pack_length()+1
616 */
617
set(uchar * to,Field * from)618 void Copy_field::set(uchar *to,Field *from)
619 {
620 from_ptr=from->ptr;
621 to_ptr=to;
622 from_length=from->pack_length_in_rec();
623 if (from->maybe_null())
624 {
625 from_null_ptr=from->null_ptr;
626 from_bit= from->null_bit;
627 to_ptr[0]= 1; // Null as default value
628 to_null_ptr= (uchar*) to_ptr++;
629 to_bit= 1;
630 if (from->table->maybe_null)
631 {
632 null_row= &from->table->null_row;
633 do_copy= do_outer_field_to_null_str;
634 }
635 else
636 do_copy= do_field_to_null_str;
637 }
638 else
639 {
640 to_null_ptr= 0; // For easy debugging
641 do_copy= do_field_eq;
642 }
643 }
644
645
646 /*
647 To do:
648
649 If 'save' is set to true and the 'from' is a blob field, do_copy is set to
650 do_save_blob rather than do_conv_blob. The only differences between them
651 appears to be:
652
653 - do_save_blob allocates and uses an intermediate buffer before calling
654 Field_blob::store. Is this in order to trigger the call to
655 well_formed_copy_nchars, by changing the pointer copy->tmp.ptr()?
656 That call will take place anyway in all known cases.
657 */
set(Field * to,Field * from,bool save)658 void Copy_field::set(Field *to,Field *from,bool save)
659 {
660 if (to->type() == MYSQL_TYPE_NULL)
661 {
662 to_null_ptr=0; // For easy debugging
663 to_ptr=0;
664 do_copy=do_skip;
665 return;
666 }
667 from_field=from;
668 to_field=to;
669 from_ptr=from->ptr;
670 from_length=from->pack_length_in_rec();
671 to_ptr= to->ptr;
672 to_length=to_field->pack_length_in_rec();
673
674 // set up null handling
675 from_null_ptr=to_null_ptr=0;
676 if (from->maybe_null())
677 {
678 from_null_ptr= from->null_ptr;
679 from_bit= from->null_bit;
680 if (to_field->real_maybe_null())
681 {
682 to_null_ptr= to->null_ptr;
683 to_bit= to->null_bit;
684 if (from_null_ptr)
685 do_copy= do_copy_null;
686 else
687 {
688 null_row= &from->table->null_row;
689 do_copy= do_outer_field_null;
690 }
691 }
692 else
693 {
694 if (to_field->type() == MYSQL_TYPE_TIMESTAMP)
695 do_copy= do_copy_timestamp; // Automatic timestamp
696 else if (to_field == to_field->table->next_number_field)
697 do_copy= do_copy_next_number;
698 else
699 {
700 if (!from_null_ptr)
701 {
702 null_row= &from->table->null_row;
703 do_copy= do_copy_nullable_row_to_notnull;
704 }
705 else
706 do_copy= do_copy_not_null;
707 }
708 }
709 }
710 else if (to_field->real_maybe_null())
711 {
712 to_null_ptr= to->null_ptr;
713 to_bit= to->null_bit;
714 do_copy= do_copy_maybe_null;
715 }
716 else
717 do_copy=0;
718
719 if ((to->flags & BLOB_FLAG) && save)
720 do_copy2= do_save_blob;
721 else
722 do_copy2= to->get_copy_func(from);
723 if (!do_copy) // Not null
724 do_copy=do_copy2;
725 }
726
727
get_copy_func(const Field * from) const728 Field::Copy_func *Field_timestamp::get_copy_func(const Field *from) const
729 {
730 Field::Copy_func *copy= Field_temporal::get_copy_func(from);
731 if (copy == do_field_datetime && from->type() == MYSQL_TYPE_TIMESTAMP)
732 return do_field_timestamp;
733 else
734 return copy;
735 }
736
737
get_copy_func(const Field * from) const738 Field::Copy_func *Field_date_common::get_copy_func(const Field *from) const
739 {
740 Field::Copy_func *copy= Field_temporal::get_copy_func(from);
741 return copy == do_field_datetime ? do_field_date : copy;
742 }
743
744
get_copy_func(const Field * from) const745 Field::Copy_func *Field_temporal::get_copy_func(const Field *from) const
746 {
747 /* If types are not 100 % identical then convert trough get_date() */
748 if (from->cmp_type() == REAL_RESULT)
749 return do_field_string; // TODO: MDEV-9344
750 if (from->type() == MYSQL_TYPE_YEAR)
751 return do_field_string; // TODO: MDEV-9343
752 if (from->type() == MYSQL_TYPE_BIT)
753 return do_field_int;
754 if (!eq_def(from) ||
755 (table->in_use->variables.sql_mode &
756 (MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE)))
757 return do_field_datetime;
758 return get_identical_copy_func();
759 }
760
761
get_copy_func(const Field * from) const762 Field::Copy_func *Field_varstring::get_copy_func(const Field *from) const
763 {
764 if (from->type() == MYSQL_TYPE_BIT)
765 return do_field_int;
766 /*
767 Detect copy from pre 5.0 varbinary to varbinary as of 5.0 and
768 use special copy function that removes trailing spaces and thus
769 repairs data.
770 */
771 if (from->type() == MYSQL_TYPE_VAR_STRING && !from->has_charset() &&
772 !Field_varstring::has_charset())
773 return do_field_varbinary_pre50;
774 if (Field_varstring::real_type() != from->real_type() ||
775 Field_varstring::charset() != from->charset() ||
776 length_bytes != ((const Field_varstring*) from)->length_bytes ||
777 !compression_method() != !from->compression_method())
778 return do_field_string;
779 return length_bytes == 1 ?
780 (from->charset()->mbmaxlen == 1 ? do_varstring1 : do_varstring1_mb) :
781 (from->charset()->mbmaxlen == 1 ? do_varstring2 : do_varstring2_mb);
782 }
783
784
get_copy_func(const Field * from) const785 Field::Copy_func *Field_string::get_copy_func(const Field *from) const
786 {
787 if (from->type() == MYSQL_TYPE_BIT)
788 return do_field_int;
789 if (Field_string::real_type() != from->real_type() ||
790 Field_string::charset() != from->charset())
791 return do_field_string;
792 if (Field_string::pack_length() < from->pack_length())
793 return (Field_string::charset()->mbmaxlen == 1 ?
794 do_cut_string : do_cut_string_complex);
795 if (Field_string::pack_length() > from->pack_length())
796 return Field_string::charset() == &my_charset_bin ? do_expand_binary :
797 do_expand_string;
798 return get_identical_copy_func();
799 }
800
801
get_identical_copy_func() const802 Field::Copy_func *Field::get_identical_copy_func() const
803 {
804 /* Identical field types */
805 switch (pack_length()) {
806 case 1: return do_field_1;
807 case 2: return do_field_2;
808 case 3: return do_field_3;
809 case 4: return do_field_4;
810 case 6: return do_field_6;
811 case 8: return do_field_8;
812 }
813 return do_field_eq;
814 }
815
816
memcpy_field_possible(const Field * from) const817 bool Field_temporal::memcpy_field_possible(const Field *from) const
818 {
819 return real_type() == from->real_type() &&
820 decimals() == from->decimals() &&
821 !sql_mode_for_dates(table->in_use);
822 }
823
824
field_conv_memcpy(Field * to,Field * from)825 static int field_conv_memcpy(Field *to, Field *from)
826 {
827 /*
828 This may happen if one does 'UPDATE ... SET x=x'
829 The test is here mostly for valgrind, but can also be relevant
830 if memcpy() is implemented with prefetch-write
831 */
832 if (to->ptr != from->ptr)
833 memcpy(to->ptr,from->ptr, to->pack_length());
834 return 0;
835 }
836
837
838 /**
839 Copy value of the field with conversion.
840
841 @note Impossibility of simple copy should be checked before this call.
842
843 @param to The field to copy to
844
845 @retval TRUE ERROR
846 @retval FALSE OK
847
848 */
field_conv_incompatible(Field * to,Field * from)849 static int field_conv_incompatible(Field *to, Field *from)
850 {
851 return to->store_field(from);
852 }
853
854
855 /**
856 Simple quick field converter that is called on insert, e.g.:
857 INSERT INTO t1 (field1) SELECT field2 FROM t2;
858 */
859
field_conv(Field * to,Field * from)860 int field_conv(Field *to,Field *from)
861 {
862 return to->memcpy_field_possible(from) ?
863 field_conv_memcpy(to, from) :
864 field_conv_incompatible(to, from);
865 }
866
867
get_fast_field_copier(const Field * from)868 fast_field_copier Field::get_fast_field_copier(const Field *from)
869 {
870 DBUG_ENTER("Field::get_fast_field_copier");
871 DBUG_RETURN(memcpy_field_possible(from) ?
872 &field_conv_memcpy :
873 &field_conv_incompatible);
874 }
875