2 Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
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.
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.
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-1301 USA
23 Functions to copy data to or from fields
25 This could be done with a single short function but opencoding this
26 gives much more speed.
29 #include "mysql_priv.h"
32 static void do_field_eq(Copy_field
*copy
)
34 memcpy(copy
->to_ptr
,copy
->from_ptr
,copy
->from_length
);
37 static void do_field_1(Copy_field
*copy
)
39 copy
->to_ptr
[0]=copy
->from_ptr
[0];
42 static void do_field_2(Copy_field
*copy
)
44 copy
->to_ptr
[0]=copy
->from_ptr
[0];
45 copy
->to_ptr
[1]=copy
->from_ptr
[1];
48 static void do_field_3(Copy_field
*copy
)
50 copy
->to_ptr
[0]=copy
->from_ptr
[0];
51 copy
->to_ptr
[1]=copy
->from_ptr
[1];
52 copy
->to_ptr
[2]=copy
->from_ptr
[2];
55 static void do_field_4(Copy_field
*copy
)
57 copy
->to_ptr
[0]=copy
->from_ptr
[0];
58 copy
->to_ptr
[1]=copy
->from_ptr
[1];
59 copy
->to_ptr
[2]=copy
->from_ptr
[2];
60 copy
->to_ptr
[3]=copy
->from_ptr
[3];
63 static void do_field_6(Copy_field
*copy
)
65 copy
->to_ptr
[0]=copy
->from_ptr
[0];
66 copy
->to_ptr
[1]=copy
->from_ptr
[1];
67 copy
->to_ptr
[2]=copy
->from_ptr
[2];
68 copy
->to_ptr
[3]=copy
->from_ptr
[3];
69 copy
->to_ptr
[4]=copy
->from_ptr
[4];
70 copy
->to_ptr
[5]=copy
->from_ptr
[5];
73 static void do_field_8(Copy_field
*copy
)
75 copy
->to_ptr
[0]=copy
->from_ptr
[0];
76 copy
->to_ptr
[1]=copy
->from_ptr
[1];
77 copy
->to_ptr
[2]=copy
->from_ptr
[2];
78 copy
->to_ptr
[3]=copy
->from_ptr
[3];
79 copy
->to_ptr
[4]=copy
->from_ptr
[4];
80 copy
->to_ptr
[5]=copy
->from_ptr
[5];
81 copy
->to_ptr
[6]=copy
->from_ptr
[6];
82 copy
->to_ptr
[7]=copy
->from_ptr
[7];
86 static void do_field_to_null_str(Copy_field
*copy
)
88 if (*copy
->from_null_ptr
& copy
->from_bit
)
90 bzero(copy
->to_ptr
,copy
->from_length
);
91 copy
->to_null_ptr
[0]=1; // Always bit 1
95 copy
->to_null_ptr
[0]=0;
96 memcpy(copy
->to_ptr
,copy
->from_ptr
,copy
->from_length
);
101 static void do_outer_field_to_null_str(Copy_field
*copy
)
103 if (*copy
->null_row
||
104 (copy
->from_null_ptr
&& (*copy
->from_null_ptr
& copy
->from_bit
)))
106 bzero(copy
->to_ptr
,copy
->from_length
);
107 copy
->to_null_ptr
[0]=1; // Always bit 1
111 copy
->to_null_ptr
[0]=0;
112 memcpy(copy
->to_ptr
,copy
->from_ptr
,copy
->from_length
);
118 set_field_to_null(Field
*field
)
120 if (field
->real_maybe_null())
127 switch (field
->table
->in_use
->count_cuted_fields
) {
128 case CHECK_FIELD_WARN
:
129 field
->set_warning(MYSQL_ERROR::WARN_LEVEL_WARN
, WARN_DATA_TRUNCATED
, 1);
131 case CHECK_FIELD_IGNORE
:
133 case CHECK_FIELD_ERROR_FOR_NULL
:
134 if (!field
->table
->in_use
->no_errors
)
135 my_error(ER_BAD_NULL_ERROR
, MYF(0), field
->field_name
);
138 DBUG_ASSERT(0); // impossible
144 Set field to NULL or TIMESTAMP or to next auto_increment number.
146 @param field Field to update
147 @param no_conversions Set to 1 if we should return 1 if field can't
149 If set to 0 we will do store the 'default value'
150 if the field is a special field. If not we will
154 0 Field could take 0 or an automatic conversion was used
156 -1 Field could not take NULL and no conversion was used.
157 If no_conversion was not set, an error message is printed
161 set_field_to_null_with_conversions(Field
*field
, bool no_conversions
)
163 if (field
->real_maybe_null())
173 Check if this is a special type, which will get a special walue
174 when set to NULL (TIMESTAMP fields which allow setting to NULL
175 are handled by first check).
177 if (field
->type() == MYSQL_TYPE_TIMESTAMP
)
179 ((Field_timestamp
*) field
)->set_time();
180 return 0; // Ok to set time to NULL
183 // Note: we ignore any potential failure of reset() here.
186 if (field
== field
->table
->next_number_field
)
188 field
->table
->auto_increment_field_not_null
= FALSE
;
189 return 0; // field is set in fill_record()
191 switch (field
->table
->in_use
->count_cuted_fields
) {
192 case CHECK_FIELD_WARN
:
193 field
->set_warning(MYSQL_ERROR::WARN_LEVEL_WARN
, ER_BAD_NULL_ERROR
, 1);
195 case CHECK_FIELD_IGNORE
:
197 case CHECK_FIELD_ERROR_FOR_NULL
:
198 if (!field
->table
->in_use
->no_errors
)
199 my_error(ER_BAD_NULL_ERROR
, MYF(0), field
->field_name
);
202 DBUG_ASSERT(0); // impossible
207 static void do_skip(Copy_field
*copy
__attribute__((unused
)))
212 static void do_copy_null(Copy_field
*copy
)
214 if (*copy
->from_null_ptr
& copy
->from_bit
)
216 *copy
->to_null_ptr
|=copy
->to_bit
;
217 copy
->to_field
->reset();
221 *copy
->to_null_ptr
&= ~copy
->to_bit
;
222 (copy
->do_copy2
)(copy
);
227 static void do_outer_field_null(Copy_field
*copy
)
229 if (*copy
->null_row
||
230 (copy
->from_null_ptr
&& (*copy
->from_null_ptr
& copy
->from_bit
)))
232 *copy
->to_null_ptr
|=copy
->to_bit
;
233 copy
->to_field
->reset();
237 *copy
->to_null_ptr
&= ~copy
->to_bit
;
238 (copy
->do_copy2
)(copy
);
243 static void do_copy_not_null(Copy_field
*copy
)
245 if (*copy
->from_null_ptr
& copy
->from_bit
)
247 copy
->to_field
->set_warning(MYSQL_ERROR::WARN_LEVEL_WARN
,
248 WARN_DATA_TRUNCATED
, 1);
249 copy
->to_field
->reset();
252 (copy
->do_copy2
)(copy
);
256 static void do_copy_maybe_null(Copy_field
*copy
)
258 *copy
->to_null_ptr
&= ~copy
->to_bit
;
259 (copy
->do_copy2
)(copy
);
262 /* timestamp and next_number has special handling in case of NULL values */
264 static void do_copy_timestamp(Copy_field
*copy
)
266 if (*copy
->from_null_ptr
& copy
->from_bit
)
268 /* Same as in set_field_to_null_with_conversions() */
269 ((Field_timestamp
*) copy
->to_field
)->set_time();
272 (copy
->do_copy2
)(copy
);
276 static void do_copy_next_number(Copy_field
*copy
)
278 if (*copy
->from_null_ptr
& copy
->from_bit
)
280 /* Same as in set_field_to_null_with_conversions() */
281 copy
->to_field
->table
->auto_increment_field_not_null
= FALSE
;
282 copy
->to_field
->reset();
285 (copy
->do_copy2
)(copy
);
289 static void do_copy_blob(Copy_field
*copy
)
291 ulong length
=((Field_blob
*) copy
->from_field
)->get_length();
292 ((Field_blob
*) copy
->to_field
)->store_length(length
);
293 memcpy_fixed(copy
->to_ptr
,copy
->from_ptr
,sizeof(char*));
296 static void do_conv_blob(Copy_field
*copy
)
298 copy
->from_field
->val_str(©
->tmp
);
299 ((Field_blob
*) copy
->to_field
)->store(copy
->tmp
.ptr(),
301 copy
->tmp
.charset());
304 /** Save blob in copy->tmp for GROUP BY. */
306 static void do_save_blob(Copy_field
*copy
)
308 char buff
[MAX_FIELD_WIDTH
];
309 String
res(buff
,sizeof(buff
),copy
->tmp
.charset());
310 copy
->from_field
->val_str(&res
);
312 ((Field_blob
*) copy
->to_field
)->store(copy
->tmp
.ptr(),
314 copy
->tmp
.charset());
318 static void do_field_string(Copy_field
*copy
)
320 char buff
[MAX_FIELD_WIDTH
];
321 copy
->tmp
.set_quick(buff
,sizeof(buff
),copy
->tmp
.charset());
322 copy
->from_field
->val_str(©
->tmp
);
323 copy
->to_field
->store(copy
->tmp
.c_ptr_quick(),copy
->tmp
.length(),
324 copy
->tmp
.charset());
328 static void do_field_enum(Copy_field
*copy
)
330 if (copy
->from_field
->val_int() == 0)
331 ((Field_enum
*) copy
->to_field
)->store_type((ulonglong
) 0);
333 do_field_string(copy
);
337 static void do_field_varbinary_pre50(Copy_field
*copy
)
339 char buff
[MAX_FIELD_WIDTH
];
340 copy
->tmp
.set_quick(buff
,sizeof(buff
),copy
->tmp
.charset());
341 copy
->from_field
->val_str(©
->tmp
);
343 /* Use the same function as in 4.1 to trim trailing spaces */
344 uint length
= my_lengthsp_8bit(&my_charset_bin
, copy
->tmp
.c_ptr_quick(),
345 copy
->from_field
->field_length
);
347 copy
->to_field
->store(copy
->tmp
.c_ptr_quick(), length
,
348 copy
->tmp
.charset());
352 static void do_field_int(Copy_field
*copy
)
354 longlong value
= copy
->from_field
->val_int();
355 copy
->to_field
->store(value
,
356 test(copy
->from_field
->flags
& UNSIGNED_FLAG
));
359 static void do_field_real(Copy_field
*copy
)
361 double value
=copy
->from_field
->val_real();
362 copy
->to_field
->store(value
);
366 static void do_field_decimal(Copy_field
*copy
)
369 copy
->to_field
->store_decimal(copy
->from_field
->val_decimal(&value
));
374 string copy for single byte characters set when to string is shorter than
378 static void do_cut_string(Copy_field
*copy
)
380 CHARSET_INFO
*cs
= copy
->from_field
->charset();
381 memcpy(copy
->to_ptr
,copy
->from_ptr
,copy
->to_length
);
383 /* Check if we loosed any important characters */
384 if (cs
->cset
->scan(cs
,
385 (char*) copy
->from_ptr
+ copy
->to_length
,
386 (char*) copy
->from_ptr
+ copy
->from_length
,
387 MY_SEQ_SPACES
) < copy
->from_length
- copy
->to_length
)
389 copy
->to_field
->set_warning(MYSQL_ERROR::WARN_LEVEL_WARN
,
390 WARN_DATA_TRUNCATED
, 1);
396 string copy for multi byte characters set when to string is shorter than
400 static void do_cut_string_complex(Copy_field
*copy
)
401 { // Shorter string field
402 int well_formed_error
;
403 CHARSET_INFO
*cs
= copy
->from_field
->charset();
404 const uchar
*from_end
= copy
->from_ptr
+ copy
->from_length
;
405 uint copy_length
= cs
->cset
->well_formed_len(cs
,
406 (char*) copy
->from_ptr
,
408 copy
->to_length
/ cs
->mbmaxlen
,
410 if (copy
->to_length
< copy_length
)
411 copy_length
= copy
->to_length
;
412 memcpy(copy
->to_ptr
, copy
->from_ptr
, copy_length
);
414 /* Check if we lost any important characters */
415 if (well_formed_error
||
416 cs
->cset
->scan(cs
, (char*) copy
->from_ptr
+ copy_length
,
418 MY_SEQ_SPACES
) < (copy
->from_length
- copy_length
))
420 copy
->to_field
->set_warning(MYSQL_ERROR::WARN_LEVEL_WARN
,
421 WARN_DATA_TRUNCATED
, 1);
424 if (copy_length
< copy
->to_length
)
425 cs
->cset
->fill(cs
, (char*) copy
->to_ptr
+ copy_length
,
426 copy
->to_length
- copy_length
, ' ');
432 static void do_expand_binary(Copy_field
*copy
)
434 CHARSET_INFO
*cs
= copy
->from_field
->charset();
435 memcpy(copy
->to_ptr
,copy
->from_ptr
,copy
->from_length
);
436 cs
->cset
->fill(cs
, (char*) copy
->to_ptr
+copy
->from_length
,
437 copy
->to_length
-copy
->from_length
, '\0');
442 static void do_expand_string(Copy_field
*copy
)
444 CHARSET_INFO
*cs
= copy
->from_field
->charset();
445 memcpy(copy
->to_ptr
,copy
->from_ptr
,copy
->from_length
);
446 cs
->cset
->fill(cs
, (char*) copy
->to_ptr
+copy
->from_length
,
447 copy
->to_length
-copy
->from_length
, ' ');
451 static void do_varstring1(Copy_field
*copy
)
453 uint length
= (uint
) *(uchar
*) copy
->from_ptr
;
454 if (length
> copy
->to_length
- 1)
456 length
=copy
->to_length
- 1;
457 if (copy
->from_field
->table
->in_use
->count_cuted_fields
)
458 copy
->to_field
->set_warning(MYSQL_ERROR::WARN_LEVEL_WARN
,
459 WARN_DATA_TRUNCATED
, 1);
461 *(uchar
*) copy
->to_ptr
= (uchar
) length
;
462 memcpy(copy
->to_ptr
+1, copy
->from_ptr
+ 1, length
);
466 static void do_varstring1_mb(Copy_field
*copy
)
468 int well_formed_error
;
469 CHARSET_INFO
*cs
= copy
->from_field
->charset();
470 uint from_length
= (uint
) *(uchar
*) copy
->from_ptr
;
471 const uchar
*from_ptr
= copy
->from_ptr
+ 1;
472 uint to_char_length
= (copy
->to_length
- 1) / cs
->mbmaxlen
;
473 uint length
= cs
->cset
->well_formed_len(cs
, (char*) from_ptr
,
474 (char*) from_ptr
+ from_length
,
475 to_char_length
, &well_formed_error
);
476 if (length
< from_length
)
478 if (current_thd
->count_cuted_fields
)
479 copy
->to_field
->set_warning(MYSQL_ERROR::WARN_LEVEL_WARN
,
480 WARN_DATA_TRUNCATED
, 1);
482 *copy
->to_ptr
= (uchar
) length
;
483 memcpy(copy
->to_ptr
+ 1, from_ptr
, length
);
487 static void do_varstring2(Copy_field
*copy
)
489 uint length
=uint2korr(copy
->from_ptr
);
490 if (length
> copy
->to_length
- HA_KEY_BLOB_LENGTH
)
492 length
=copy
->to_length
-HA_KEY_BLOB_LENGTH
;
493 if (copy
->from_field
->table
->in_use
->count_cuted_fields
)
494 copy
->to_field
->set_warning(MYSQL_ERROR::WARN_LEVEL_WARN
,
495 WARN_DATA_TRUNCATED
, 1);
497 int2store(copy
->to_ptr
,length
);
498 memcpy(copy
->to_ptr
+HA_KEY_BLOB_LENGTH
, copy
->from_ptr
+ HA_KEY_BLOB_LENGTH
,
503 static void do_varstring2_mb(Copy_field
*copy
)
505 int well_formed_error
;
506 CHARSET_INFO
*cs
= copy
->from_field
->charset();
507 uint char_length
= (copy
->to_length
- HA_KEY_BLOB_LENGTH
) / cs
->mbmaxlen
;
508 uint from_length
= uint2korr(copy
->from_ptr
);
509 const uchar
*from_beg
= copy
->from_ptr
+ HA_KEY_BLOB_LENGTH
;
510 uint length
= cs
->cset
->well_formed_len(cs
, (char*) from_beg
,
511 (char*) from_beg
+ from_length
,
512 char_length
, &well_formed_error
);
513 if (length
< from_length
)
515 if (current_thd
->count_cuted_fields
)
516 copy
->to_field
->set_warning(MYSQL_ERROR::WARN_LEVEL_WARN
,
517 WARN_DATA_TRUNCATED
, 1);
519 int2store(copy
->to_ptr
, length
);
520 memcpy(copy
->to_ptr
+HA_KEY_BLOB_LENGTH
, from_beg
, length
);
524 /***************************************************************************
525 ** The different functions that fills in a Copy_field class
526 ***************************************************************************/
529 copy of field to maybe null string.
530 If field is null then the all bytes are set to 0.
531 if field is not null then the first byte is set to 1 and the rest of the
532 string is the field value.
533 The 'to' buffer should have a size of field->pack_length()+1
536 void Copy_field::set(uchar
*to
,Field
*from
)
540 from_length
=from
->pack_length();
541 if (from
->maybe_null())
543 from_null_ptr
=from
->null_ptr
;
544 from_bit
= from
->null_bit
;
545 to_ptr
[0]= 1; // Null as default value
546 to_null_ptr
= (uchar
*) to_ptr
++;
548 if (from
->table
->maybe_null
)
550 null_row
= &from
->table
->null_row
;
551 do_copy
= do_outer_field_to_null_str
;
554 do_copy
= do_field_to_null_str
;
558 to_null_ptr
= 0; // For easy debugging
559 do_copy
= do_field_eq
;
567 If 'save\ is set to true and the 'from' is a blob field, do_copy is set to
568 do_save_blob rather than do_conv_blob. The only differences between them
571 - do_save_blob allocates and uses an intermediate buffer before calling
572 Field_blob::store. Is this in order to trigger the call to
573 well_formed_copy_nchars, by changing the pointer copy->tmp.ptr()?
574 That call will take place anyway in all known cases.
576 - The above causes a truncation to MAX_FIELD_WIDTH. Is this the intended
577 effect? Truncation is handled by well_formed_copy_nchars anyway.
579 void Copy_field::set(Field
*to
,Field
*from
,bool save
)
581 if (to
->type() == MYSQL_TYPE_NULL
)
583 to_null_ptr
=0; // For easy debugging
591 from_length
=from
->pack_length();
593 to_length
=to_field
->pack_length();
595 // set up null handling
596 from_null_ptr
=to_null_ptr
=0;
597 if (from
->maybe_null())
599 from_null_ptr
= from
->null_ptr
;
600 from_bit
= from
->null_bit
;
601 if (to_field
->real_maybe_null())
603 to_null_ptr
= to
->null_ptr
;
604 to_bit
= to
->null_bit
;
606 do_copy
= do_copy_null
;
609 null_row
= &from
->table
->null_row
;
610 do_copy
= do_outer_field_null
;
615 if (to_field
->type() == MYSQL_TYPE_TIMESTAMP
)
616 do_copy
= do_copy_timestamp
; // Automatic timestamp
617 else if (to_field
== to_field
->table
->next_number_field
)
618 do_copy
= do_copy_next_number
;
620 do_copy
= do_copy_not_null
;
623 else if (to_field
->real_maybe_null())
625 to_null_ptr
= to
->null_ptr
;
626 to_bit
= to
->null_bit
;
627 do_copy
= do_copy_maybe_null
;
632 if ((to
->flags
& BLOB_FLAG
) && save
)
633 do_copy2
= do_save_blob
;
635 do_copy2
= get_copy_func(to
,from
);
636 if (!do_copy
) // Not null
641 Copy_field::Copy_func
*
642 Copy_field::get_copy_func(Field
*to
,Field
*from
)
644 bool compatible_db_low_byte_first
= (to
->table
->s
->db_low_byte_first
==
645 from
->table
->s
->db_low_byte_first
);
646 if (to
->flags
& BLOB_FLAG
)
648 if (!(from
->flags
& BLOB_FLAG
) || from
->charset() != to
->charset())
650 if (from_length
!= to_length
|| !compatible_db_low_byte_first
)
652 // Correct pointer to point at char pointer
653 to_ptr
+= to_length
- to
->table
->s
->blob_ptr_size
;
654 from_ptr
+= from_length
- from
->table
->s
->blob_ptr_size
;
660 if (to
->real_type() == MYSQL_TYPE_BIT
||
661 from
->real_type() == MYSQL_TYPE_BIT
)
663 if (to
->result_type() == DECIMAL_RESULT
)
664 return do_field_decimal
;
665 // Check if identical fields
666 if (from
->result_type() == STRING_RESULT
)
669 Detect copy from pre 5.0 varbinary to varbinary as of 5.0 and
670 use special copy function that removes trailing spaces and thus
673 if (from
->type() == MYSQL_TYPE_VAR_STRING
&& !from
->has_charset() &&
674 to
->type() == MYSQL_TYPE_VARCHAR
&& !to
->has_charset())
675 return do_field_varbinary_pre50
;
678 If we are copying date or datetime's we have to check the dates
679 if we don't allow 'all' dates.
681 if (to
->real_type() != from
->real_type() ||
682 !compatible_db_low_byte_first
||
683 (((to
->table
->in_use
->variables
.sql_mode
&
684 (MODE_NO_ZERO_IN_DATE
| MODE_NO_ZERO_DATE
| MODE_INVALID_DATES
)) &&
685 to
->type() == MYSQL_TYPE_DATE
) ||
686 to
->type() == MYSQL_TYPE_DATETIME
))
688 if (from
->real_type() == MYSQL_TYPE_ENUM
||
689 from
->real_type() == MYSQL_TYPE_SET
)
690 if (to
->result_type() != STRING_RESULT
)
691 return do_field_int
; // Convert SET to number
692 return do_field_string
;
694 if (to
->real_type() == MYSQL_TYPE_ENUM
||
695 to
->real_type() == MYSQL_TYPE_SET
)
697 if (!to
->eq_def(from
))
699 if (from
->real_type() == MYSQL_TYPE_ENUM
&&
700 to
->real_type() == MYSQL_TYPE_ENUM
)
701 return do_field_enum
;
703 return do_field_string
;
706 else if (to
->charset() != from
->charset())
707 return do_field_string
;
708 else if (to
->real_type() == MYSQL_TYPE_VARCHAR
)
710 if (((Field_varstring
*) to
)->length_bytes
!=
711 ((Field_varstring
*) from
)->length_bytes
)
712 return do_field_string
;
714 return (((Field_varstring
*) to
)->length_bytes
== 1 ?
715 (from
->charset()->mbmaxlen
== 1 ? do_varstring1
:
717 (from
->charset()->mbmaxlen
== 1 ? do_varstring2
:
720 else if (to_length
< from_length
)
721 return (from
->charset()->mbmaxlen
== 1 ?
722 do_cut_string
: do_cut_string_complex
);
723 else if (to_length
> from_length
)
725 if (to
->charset() == &my_charset_bin
)
726 return do_expand_binary
;
728 return do_expand_string
;
732 else if (to
->real_type() != from
->real_type() ||
733 to_length
!= from_length
||
734 !compatible_db_low_byte_first
)
736 if (to
->real_type() == MYSQL_TYPE_DECIMAL
||
737 to
->result_type() == STRING_RESULT
)
738 return do_field_string
;
739 if (to
->result_type() == INT_RESULT
)
741 return do_field_real
;
745 if (!to
->eq_def(from
) || !compatible_db_low_byte_first
)
747 if (to
->real_type() == MYSQL_TYPE_DECIMAL
)
748 return do_field_string
;
749 if (to
->result_type() == INT_RESULT
)
752 return do_field_real
;
758 case 1: return do_field_1
;
759 case 2: return do_field_2
;
760 case 3: return do_field_3
;
761 case 4: return do_field_4
;
762 case 6: return do_field_6
;
763 case 8: return do_field_8
;
769 /** Simple quick field convert that is called on insert. */
771 int field_conv(Field
*to
,Field
*from
)
773 if (to
->real_type() == from
->real_type() &&
774 !(to
->type() == MYSQL_TYPE_BLOB
&& to
->table
->copy_blobs
))
776 if (to
->pack_length() == from
->pack_length() &&
777 !(to
->flags
& UNSIGNED_FLAG
&& !(from
->flags
& UNSIGNED_FLAG
)) &&
778 to
->real_type() != MYSQL_TYPE_ENUM
&&
779 to
->real_type() != MYSQL_TYPE_SET
&&
780 to
->real_type() != MYSQL_TYPE_BIT
&&
781 (to
->real_type() != MYSQL_TYPE_NEWDECIMAL
||
782 (to
->field_length
== from
->field_length
&&
783 (((Field_num
*)to
)->dec
== ((Field_num
*)from
)->dec
))) &&
784 from
->charset() == to
->charset() &&
785 to
->table
->s
->db_low_byte_first
== from
->table
->s
->db_low_byte_first
&&
786 (!(to
->table
->in_use
->variables
.sql_mode
&
787 (MODE_NO_ZERO_IN_DATE
| MODE_NO_ZERO_DATE
| MODE_INVALID_DATES
)) ||
788 (to
->type() != MYSQL_TYPE_DATE
&&
789 to
->type() != MYSQL_TYPE_DATETIME
)) &&
790 (from
->real_type() != MYSQL_TYPE_VARCHAR
||
791 ((Field_varstring
*)from
)->length_bytes
==
792 ((Field_varstring
*)to
)->length_bytes
))
793 { // Identical fields
794 // to->ptr==from->ptr may happen if one does 'UPDATE ... SET x=x'
795 memmove(to
->ptr
, from
->ptr
, to
->pack_length());
799 if (to
->type() == MYSQL_TYPE_BLOB
)
800 { // Be sure the value is stored
801 Field_blob
*blob
=(Field_blob
*) to
;
802 from
->val_str(&blob
->value
);
804 Copy value if copy_blobs is set, or source is not a string and
805 we have a pointer to its internal string conversion buffer.
807 if (to
->table
->copy_blobs
||
808 (!blob
->value
.is_alloced() &&
809 from
->real_type() != MYSQL_TYPE_STRING
&&
810 from
->real_type() != MYSQL_TYPE_VARCHAR
))
812 return blob
->store(blob
->value
.ptr(),blob
->value
.length(),from
->charset());
814 if (from
->real_type() == MYSQL_TYPE_ENUM
&&
815 to
->real_type() == MYSQL_TYPE_ENUM
&&
816 from
->val_int() == 0)
818 ((Field_enum
*)(to
))->store_type(0);
821 else if ((from
->result_type() == STRING_RESULT
&&
822 (to
->result_type() == STRING_RESULT
||
823 (from
->real_type() != MYSQL_TYPE_ENUM
&&
824 from
->real_type() != MYSQL_TYPE_SET
))) ||
825 to
->type() == MYSQL_TYPE_DECIMAL
)
827 char buff
[MAX_FIELD_WIDTH
];
828 String
result(buff
,sizeof(buff
),from
->charset());
829 from
->val_str(&result
);
831 We use c_ptr_quick() here to make it easier if to is a float/double
832 as the conversion routines will do a copy of the result doesn't
833 end with \0. Can be replaced with .ptr() when we have our own
834 string->double conversion.
836 return to
->store(result
.c_ptr_quick(),result
.length(),from
->charset());
838 else if (from
->result_type() == REAL_RESULT
)
839 return to
->store(from
->val_real());
840 else if (from
->result_type() == DECIMAL_RESULT
)
843 return to
->store_decimal(from
->val_decimal(&buff
));
846 return to
->store(from
->val_int(), test(from
->flags
& UNSIGNED_FLAG
));