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(&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->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