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(&copy->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(&copy->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(&ltime, fuzzydate))
433     copy->to_field->reset();
434   else
435     copy->to_field->store_time_dec(&ltime, 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