1
/* Copyright (C) 2000-2003 MySQL AB
3
This program is free software; you can redistribute it and/or modify
4
it under the terms of the GNU General Public License as published by
5
the Free Software Foundation; version 2 of the License.
7
This program is distributed in the hope that it will be useful,
8
but WITHOUT ANY WARRANTY; without even the implied warranty of
9
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
GNU General Public License for more details.
12
You should have received a copy of the GNU General Public License
13
along with this program; if not, write to the Free Software
14
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
21
Functions to copy data to or from fields
23
This could be done with a single short function but opencoding this
24
gives much more speed.
27
#include "mysql_priv.h"
30
static void do_field_eq(Copy_field *copy)
32
memcpy(copy->to_ptr,copy->from_ptr,copy->from_length);
35
static void do_field_1(Copy_field *copy)
37
copy->to_ptr[0]=copy->from_ptr[0];
40
static void do_field_2(Copy_field *copy)
42
copy->to_ptr[0]=copy->from_ptr[0];
43
copy->to_ptr[1]=copy->from_ptr[1];
46
static void do_field_3(Copy_field *copy)
48
copy->to_ptr[0]=copy->from_ptr[0];
49
copy->to_ptr[1]=copy->from_ptr[1];
50
copy->to_ptr[2]=copy->from_ptr[2];
53
static void do_field_4(Copy_field *copy)
55
copy->to_ptr[0]=copy->from_ptr[0];
56
copy->to_ptr[1]=copy->from_ptr[1];
57
copy->to_ptr[2]=copy->from_ptr[2];
58
copy->to_ptr[3]=copy->from_ptr[3];
61
static void do_field_6(Copy_field *copy)
63
copy->to_ptr[0]=copy->from_ptr[0];
64
copy->to_ptr[1]=copy->from_ptr[1];
65
copy->to_ptr[2]=copy->from_ptr[2];
66
copy->to_ptr[3]=copy->from_ptr[3];
67
copy->to_ptr[4]=copy->from_ptr[4];
68
copy->to_ptr[5]=copy->from_ptr[5];
71
static void do_field_8(Copy_field *copy)
73
copy->to_ptr[0]=copy->from_ptr[0];
74
copy->to_ptr[1]=copy->from_ptr[1];
75
copy->to_ptr[2]=copy->from_ptr[2];
76
copy->to_ptr[3]=copy->from_ptr[3];
77
copy->to_ptr[4]=copy->from_ptr[4];
78
copy->to_ptr[5]=copy->from_ptr[5];
79
copy->to_ptr[6]=copy->from_ptr[6];
80
copy->to_ptr[7]=copy->from_ptr[7];
84
static void do_field_to_null_str(Copy_field *copy)
86
if (*copy->from_null_ptr & copy->from_bit)
88
bzero(copy->to_ptr,copy->from_length);
89
copy->to_null_ptr[0]=1; // Always bit 1
93
copy->to_null_ptr[0]=0;
94
memcpy(copy->to_ptr,copy->from_ptr,copy->from_length);
99
static void do_outer_field_to_null_str(Copy_field *copy)
101
if (*copy->null_row ||
102
(copy->from_null_ptr && (*copy->from_null_ptr & copy->from_bit)))
104
bzero(copy->to_ptr,copy->from_length);
105
copy->to_null_ptr[0]=1; // Always bit 1
109
copy->to_null_ptr[0]=0;
110
memcpy(copy->to_ptr,copy->from_ptr,copy->from_length);
116
set_field_to_null(Field *field)
118
if (field->real_maybe_null())
125
if (field->table->in_use->count_cuted_fields == CHECK_FIELD_WARN)
127
field->set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, 1);
130
if (!field->table->in_use->no_errors)
131
my_error(ER_BAD_NULL_ERROR, MYF(0), field->field_name);
137
Set field to NULL or TIMESTAMP or to next auto_increment number.
139
@param field Field to update
140
@param no_conversions Set to 1 if we should return 1 if field can't
142
If set to 0 we will do store the 'default value'
143
if the field is a special field. If not we will
147
0 Field could take 0 or an automatic conversion was used
149
-1 Field could not take NULL and no conversion was used.
150
If no_conversion was not set, an error message is printed
154
set_field_to_null_with_conversions(Field *field, bool no_conversions)
156
if (field->real_maybe_null())
166
Check if this is a special type, which will get a special walue
167
when set to NULL (TIMESTAMP fields which allow setting to NULL
168
are handled by first check).
170
if (field->type() == MYSQL_TYPE_TIMESTAMP)
172
((Field_timestamp*) field)->set_time();
173
return 0; // Ok to set time to NULL
176
if (field == field->table->next_number_field)
178
field->table->auto_increment_field_not_null= FALSE;
179
return 0; // field is set in fill_record()
181
if (field->table->in_use->count_cuted_fields == CHECK_FIELD_WARN)
183
field->set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_BAD_NULL_ERROR, 1);
186
if (!field->table->in_use->no_errors)
187
my_error(ER_BAD_NULL_ERROR, MYF(0), field->field_name);
192
static void do_skip(Copy_field *copy __attribute__((unused)))
197
static void do_copy_null(Copy_field *copy)
199
if (*copy->from_null_ptr & copy->from_bit)
201
*copy->to_null_ptr|=copy->to_bit;
202
copy->to_field->reset();
206
*copy->to_null_ptr&= ~copy->to_bit;
207
(copy->do_copy2)(copy);
212
static void do_outer_field_null(Copy_field *copy)
214
if (*copy->null_row ||
215
(copy->from_null_ptr && (*copy->from_null_ptr & copy->from_bit)))
217
*copy->to_null_ptr|=copy->to_bit;
218
copy->to_field->reset();
222
*copy->to_null_ptr&= ~copy->to_bit;
223
(copy->do_copy2)(copy);
228
static void do_copy_not_null(Copy_field *copy)
230
if (*copy->from_null_ptr & copy->from_bit)
232
copy->to_field->set_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
233
WARN_DATA_TRUNCATED, 1);
234
copy->to_field->reset();
237
(copy->do_copy2)(copy);
241
static void do_copy_maybe_null(Copy_field *copy)
243
*copy->to_null_ptr&= ~copy->to_bit;
244
(copy->do_copy2)(copy);
247
/* timestamp and next_number has special handling in case of NULL values */
249
static void do_copy_timestamp(Copy_field *copy)
251
if (*copy->from_null_ptr & copy->from_bit)
253
/* Same as in set_field_to_null_with_conversions() */
254
((Field_timestamp*) copy->to_field)->set_time();
257
(copy->do_copy2)(copy);
261
static void do_copy_next_number(Copy_field *copy)
263
if (*copy->from_null_ptr & copy->from_bit)
265
/* Same as in set_field_to_null_with_conversions() */
266
copy->to_field->table->auto_increment_field_not_null= FALSE;
267
copy->to_field->reset();
270
(copy->do_copy2)(copy);
274
static void do_copy_blob(Copy_field *copy)
276
ulong length=((Field_blob*) copy->from_field)->get_length();
277
((Field_blob*) copy->to_field)->store_length(length);
278
memcpy_fixed(copy->to_ptr,copy->from_ptr,sizeof(char*));
281
static void do_conv_blob(Copy_field *copy)
283
copy->from_field->val_str(©->tmp);
284
((Field_blob *) copy->to_field)->store(copy->tmp.ptr(),
286
copy->tmp.charset());
289
/** Save blob in copy->tmp for GROUP BY. */
291
static void do_save_blob(Copy_field *copy)
293
char buff[MAX_FIELD_WIDTH];
294
String res(buff,sizeof(buff),copy->tmp.charset());
295
copy->from_field->val_str(&res);
297
((Field_blob *) copy->to_field)->store(copy->tmp.ptr(),
299
copy->tmp.charset());
303
static void do_field_string(Copy_field *copy)
305
char buff[MAX_FIELD_WIDTH];
306
copy->tmp.set_quick(buff,sizeof(buff),copy->tmp.charset());
307
copy->from_field->val_str(©->tmp);
308
copy->to_field->store(copy->tmp.c_ptr_quick(),copy->tmp.length(),
309
copy->tmp.charset());
313
static void do_field_enum(Copy_field *copy)
315
if (copy->from_field->val_int() == 0)
316
((Field_enum *) copy->to_field)->store_type((ulonglong) 0);
318
do_field_string(copy);
322
static void do_field_varbinary_pre50(Copy_field *copy)
324
char buff[MAX_FIELD_WIDTH];
325
copy->tmp.set_quick(buff,sizeof(buff),copy->tmp.charset());
326
copy->from_field->val_str(©->tmp);
328
/* Use the same function as in 4.1 to trim trailing spaces */
329
uint length= my_lengthsp_8bit(&my_charset_bin, copy->tmp.c_ptr_quick(),
330
copy->from_field->field_length);
332
copy->to_field->store(copy->tmp.c_ptr_quick(), length,
333
copy->tmp.charset());
337
static void do_field_int(Copy_field *copy)
339
longlong value= copy->from_field->val_int();
340
copy->to_field->store(value,
341
test(copy->from_field->flags & UNSIGNED_FLAG));
344
static void do_field_real(Copy_field *copy)
346
double value=copy->from_field->val_real();
347
copy->to_field->store(value);
351
static void do_field_decimal(Copy_field *copy)
354
copy->to_field->store_decimal(copy->from_field->val_decimal(&value));
359
string copy for single byte characters set when to string is shorter than
363
static void do_cut_string(Copy_field *copy)
365
CHARSET_INFO *cs= copy->from_field->charset();
366
memcpy(copy->to_ptr,copy->from_ptr,copy->to_length);
368
/* Check if we loosed any important characters */
369
if (cs->cset->scan(cs,
370
(char*) copy->from_ptr + copy->to_length,
371
(char*) copy->from_ptr + copy->from_length,
372
MY_SEQ_SPACES) < copy->from_length - copy->to_length)
374
copy->to_field->set_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
375
WARN_DATA_TRUNCATED, 1);
381
string copy for multi byte characters set when to string is shorter than
385
static void do_cut_string_complex(Copy_field *copy)
386
{ // Shorter string field
387
int well_formed_error;
388
CHARSET_INFO *cs= copy->from_field->charset();
389
const uchar *from_end= copy->from_ptr + copy->from_length;
390
uint copy_length= cs->cset->well_formed_len(cs,
391
(char*) copy->from_ptr,
393
copy->to_length / cs->mbmaxlen,
395
if (copy->to_length < copy_length)
396
copy_length= copy->to_length;
397
memcpy(copy->to_ptr, copy->from_ptr, copy_length);
399
/* Check if we lost any important characters */
400
if (well_formed_error ||
401
cs->cset->scan(cs, (char*) copy->from_ptr + copy_length,
403
MY_SEQ_SPACES) < (copy->from_length - copy_length))
405
copy->to_field->set_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
406
WARN_DATA_TRUNCATED, 1);
409
if (copy_length < copy->to_length)
410
cs->cset->fill(cs, (char*) copy->to_ptr + copy_length,
411
copy->to_length - copy_length, ' ');
417
static void do_expand_binary(Copy_field *copy)
419
CHARSET_INFO *cs= copy->from_field->charset();
420
memcpy(copy->to_ptr,copy->from_ptr,copy->from_length);
421
cs->cset->fill(cs, (char*) copy->to_ptr+copy->from_length,
422
copy->to_length-copy->from_length, '\0');
427
static void do_expand_string(Copy_field *copy)
429
CHARSET_INFO *cs= copy->from_field->charset();
430
memcpy(copy->to_ptr,copy->from_ptr,copy->from_length);
431
cs->cset->fill(cs, (char*) copy->to_ptr+copy->from_length,
432
copy->to_length-copy->from_length, ' ');
436
static void do_varstring1(Copy_field *copy)
438
uint length= (uint) *(uchar*) copy->from_ptr;
439
if (length > copy->to_length- 1)
441
length=copy->to_length - 1;
442
if (copy->from_field->table->in_use->count_cuted_fields)
443
copy->to_field->set_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
444
WARN_DATA_TRUNCATED, 1);
446
*(uchar*) copy->to_ptr= (uchar) length;
447
memcpy(copy->to_ptr+1, copy->from_ptr + 1, length);
451
static void do_varstring1_mb(Copy_field *copy)
453
int well_formed_error;
454
CHARSET_INFO *cs= copy->from_field->charset();
455
uint from_length= (uint) *(uchar*) copy->from_ptr;
456
const uchar *from_ptr= copy->from_ptr + 1;
457
uint to_char_length= (copy->to_length - 1) / cs->mbmaxlen;
458
uint length= cs->cset->well_formed_len(cs, (char*) from_ptr,
459
(char*) from_ptr + from_length,
460
to_char_length, &well_formed_error);
461
if (length < from_length)
463
if (current_thd->count_cuted_fields)
464
copy->to_field->set_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
465
WARN_DATA_TRUNCATED, 1);
467
*copy->to_ptr= (uchar) length;
468
memcpy(copy->to_ptr + 1, from_ptr, length);
472
static void do_varstring2(Copy_field *copy)
474
uint length=uint2korr(copy->from_ptr);
475
if (length > copy->to_length- HA_KEY_BLOB_LENGTH)
477
length=copy->to_length-HA_KEY_BLOB_LENGTH;
478
if (copy->from_field->table->in_use->count_cuted_fields)
479
copy->to_field->set_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
480
WARN_DATA_TRUNCATED, 1);
482
int2store(copy->to_ptr,length);
483
memcpy(copy->to_ptr+HA_KEY_BLOB_LENGTH, copy->from_ptr + HA_KEY_BLOB_LENGTH,
488
static void do_varstring2_mb(Copy_field *copy)
490
int well_formed_error;
491
CHARSET_INFO *cs= copy->from_field->charset();
492
uint char_length= (copy->to_length - HA_KEY_BLOB_LENGTH) / cs->mbmaxlen;
493
uint from_length= uint2korr(copy->from_ptr);
494
const uchar *from_beg= copy->from_ptr + HA_KEY_BLOB_LENGTH;
495
uint length= cs->cset->well_formed_len(cs, (char*) from_beg,
496
(char*) from_beg + from_length,
497
char_length, &well_formed_error);
498
if (length < from_length)
500
if (current_thd->count_cuted_fields)
501
copy->to_field->set_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
502
WARN_DATA_TRUNCATED, 1);
504
int2store(copy->to_ptr, length);
505
memcpy(copy->to_ptr+HA_KEY_BLOB_LENGTH, from_beg, length);
509
/***************************************************************************
510
** The different functions that fills in a Copy_field class
511
***************************************************************************/
514
copy of field to maybe null string.
515
If field is null then the all bytes are set to 0.
516
if field is not null then the first byte is set to 1 and the rest of the
517
string is the field value.
518
The 'to' buffer should have a size of field->pack_length()+1
521
void Copy_field::set(uchar *to,Field *from)
525
from_length=from->pack_length();
526
if (from->maybe_null())
528
from_null_ptr=from->null_ptr;
529
from_bit= from->null_bit;
530
to_ptr[0]= 1; // Null as default value
531
to_null_ptr= (uchar*) to_ptr++;
533
if (from->table->maybe_null)
535
null_row= &from->table->null_row;
536
do_copy= do_outer_field_to_null_str;
539
do_copy= do_field_to_null_str;
543
to_null_ptr= 0; // For easy debugging
544
do_copy= do_field_eq;
552
If 'save\ is set to true and the 'from' is a blob field, do_copy is set to
553
do_save_blob rather than do_conv_blob. The only differences between them
556
- do_save_blob allocates and uses an intermediate buffer before calling
557
Field_blob::store. Is this in order to trigger the call to
558
well_formed_copy_nchars, by changing the pointer copy->tmp.ptr()?
559
That call will take place anyway in all known cases.
561
- The above causes a truncation to MAX_FIELD_WIDTH. Is this the intended
562
effect? Truncation is handled by well_formed_copy_nchars anyway.
564
void Copy_field::set(Field *to,Field *from,bool save)
566
if (to->type() == MYSQL_TYPE_NULL)
568
to_null_ptr=0; // For easy debugging
576
from_length=from->pack_length();
578
to_length=to_field->pack_length();
580
// set up null handling
581
from_null_ptr=to_null_ptr=0;
582
if (from->maybe_null())
584
from_null_ptr= from->null_ptr;
585
from_bit= from->null_bit;
586
if (to_field->real_maybe_null())
588
to_null_ptr= to->null_ptr;
589
to_bit= to->null_bit;
591
do_copy= do_copy_null;
594
null_row= &from->table->null_row;
595
do_copy= do_outer_field_null;
600
if (to_field->type() == MYSQL_TYPE_TIMESTAMP)
601
do_copy= do_copy_timestamp; // Automatic timestamp
602
else if (to_field == to_field->table->next_number_field)
603
do_copy= do_copy_next_number;
605
do_copy= do_copy_not_null;
608
else if (to_field->real_maybe_null())
610
to_null_ptr= to->null_ptr;
611
to_bit= to->null_bit;
612
do_copy= do_copy_maybe_null;
617
if ((to->flags & BLOB_FLAG) && save)
618
do_copy2= do_save_blob;
620
do_copy2= get_copy_func(to,from);
621
if (!do_copy) // Not null
626
Copy_field::Copy_func *
627
Copy_field::get_copy_func(Field *to,Field *from)
629
bool compatible_db_low_byte_first= (to->table->s->db_low_byte_first ==
630
from->table->s->db_low_byte_first);
631
if (to->flags & BLOB_FLAG)
633
if (!(from->flags & BLOB_FLAG) || from->charset() != to->charset())
635
if (from_length != to_length || !compatible_db_low_byte_first)
637
// Correct pointer to point at char pointer
638
to_ptr+= to_length - to->table->s->blob_ptr_size;
639
from_ptr+= from_length- from->table->s->blob_ptr_size;
645
if (to->real_type() == MYSQL_TYPE_BIT ||
646
from->real_type() == MYSQL_TYPE_BIT)
648
if (to->result_type() == DECIMAL_RESULT)
649
return do_field_decimal;
650
// Check if identical fields
651
if (from->result_type() == STRING_RESULT)
654
Detect copy from pre 5.0 varbinary to varbinary as of 5.0 and
655
use special copy function that removes trailing spaces and thus
658
if (from->type() == MYSQL_TYPE_VAR_STRING && !from->has_charset() &&
659
to->type() == MYSQL_TYPE_VARCHAR && !to->has_charset())
660
return do_field_varbinary_pre50;
663
If we are copying date or datetime's we have to check the dates
664
if we don't allow 'all' dates.
666
if (to->real_type() != from->real_type() ||
667
!compatible_db_low_byte_first ||
668
(((to->table->in_use->variables.sql_mode & (MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE | MODE_INVALID_DATES)) && to->type() == MYSQL_TYPE_DATE) || to->type() == MYSQL_TYPE_DATETIME))
670
if (from->real_type() == MYSQL_TYPE_ENUM ||
671
from->real_type() == MYSQL_TYPE_SET)
672
if (to->result_type() != STRING_RESULT)
673
return do_field_int; // Convert SET to number
674
return do_field_string;
676
if (to->real_type() == MYSQL_TYPE_ENUM ||
677
to->real_type() == MYSQL_TYPE_SET)
679
if (!to->eq_def(from))
681
if (from->real_type() == MYSQL_TYPE_ENUM &&
682
to->real_type() == MYSQL_TYPE_ENUM)
683
return do_field_enum;
685
return do_field_string;
688
else if (to->charset() != from->charset())
689
return do_field_string;
690
else if (to->real_type() == MYSQL_TYPE_VARCHAR)
692
if (((Field_varstring*) to)->length_bytes !=
693
((Field_varstring*) from)->length_bytes)
694
return do_field_string;
695
if (to_length != from_length)
696
return (((Field_varstring*) to)->length_bytes == 1 ?
697
(from->charset()->mbmaxlen == 1 ? do_varstring1 :
699
(from->charset()->mbmaxlen == 1 ? do_varstring2 :
702
else if (to_length < from_length)
703
return (from->charset()->mbmaxlen == 1 ?
704
do_cut_string : do_cut_string_complex);
705
else if (to_length > from_length)
707
if (to->charset() == &my_charset_bin)
708
return do_expand_binary;
710
return do_expand_string;
714
else if (to->real_type() != from->real_type() ||
715
to_length != from_length ||
716
!compatible_db_low_byte_first)
718
if (to->real_type() == MYSQL_TYPE_DECIMAL ||
719
to->result_type() == STRING_RESULT)
720
return do_field_string;
721
if (to->result_type() == INT_RESULT)
723
return do_field_real;
727
if (!to->eq_def(from) || !compatible_db_low_byte_first)
729
if (to->real_type() == MYSQL_TYPE_DECIMAL)
730
return do_field_string;
731
if (to->result_type() == INT_RESULT)
734
return do_field_real;
740
case 1: return do_field_1;
741
case 2: return do_field_2;
742
case 3: return do_field_3;
743
case 4: return do_field_4;
744
case 6: return do_field_6;
745
case 8: return do_field_8;
751
/** Simple quick field convert that is called on insert. */
753
int field_conv(Field *to,Field *from)
755
if (to->real_type() == from->real_type() &&
756
!(to->type() == MYSQL_TYPE_BLOB && to->table->copy_blobs))
758
/* Please god, will someone rewrite this to be readable :( */
759
if (to->pack_length() == from->pack_length() &&
760
!(to->flags & UNSIGNED_FLAG && !(from->flags & UNSIGNED_FLAG)) &&
761
to->real_type() != MYSQL_TYPE_ENUM &&
762
to->real_type() != MYSQL_TYPE_SET && to->real_type() != MYSQL_TYPE_BIT &&
763
(to->real_type() != MYSQL_TYPE_NEWDECIMAL || (to->field_length == from->field_length && (((Field_num*)to)->dec == ((Field_num*)from)->dec))) &&
764
from->charset() == to->charset() &&
765
to->table->s->db_low_byte_first == from->table->s->db_low_byte_first &&
766
(!(to->table->in_use->variables.sql_mode & (MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE | MODE_INVALID_DATES)) || (to->type() != MYSQL_TYPE_DATE && to->type() != MYSQL_TYPE_DATETIME)) &&
767
(from->real_type() != MYSQL_TYPE_VARCHAR || ((Field_varstring*)from)->length_bytes == ((Field_varstring*)to)->length_bytes))
768
{ // Identical fields
770
/* This may happen if one does 'UPDATE ... SET x=x' */
771
if (to->ptr != from->ptr)
773
memcpy(to->ptr,from->ptr,to->pack_length());
777
if (to->type() == MYSQL_TYPE_BLOB)
778
{ // Be sure the value is stored
779
Field_blob *blob=(Field_blob*) to;
780
from->val_str(&blob->value);
782
Copy value if copy_blobs is set, or source is not a string and
783
we have a pointer to its internal string conversion buffer.
785
if (to->table->copy_blobs ||
786
(!blob->value.is_alloced() &&
787
from->real_type() != MYSQL_TYPE_STRING &&
788
from->real_type() != MYSQL_TYPE_VARCHAR))
790
return blob->store(blob->value.ptr(),blob->value.length(),from->charset());
792
if (from->real_type() == MYSQL_TYPE_ENUM &&
793
to->real_type() == MYSQL_TYPE_ENUM &&
794
from->val_int() == 0)
796
((Field_enum *)(to))->store_type(0);
799
else if ((from->result_type() == STRING_RESULT &&
800
(to->result_type() == STRING_RESULT ||
801
(from->real_type() != MYSQL_TYPE_ENUM &&
802
from->real_type() != MYSQL_TYPE_SET))) ||
803
to->type() == MYSQL_TYPE_DECIMAL)
805
char buff[MAX_FIELD_WIDTH];
806
String result(buff,sizeof(buff),from->charset());
807
from->val_str(&result);
809
We use c_ptr_quick() here to make it easier if to is a float/double
810
as the conversion routines will do a copy of the result doesn't
811
end with \0. Can be replaced with .ptr() when we have our own
812
string->double conversion.
814
return to->store(result.c_ptr_quick(),result.length(),from->charset());
816
else if (from->result_type() == REAL_RESULT)
817
return to->store(from->val_real());
818
else if (from->result_type() == DECIMAL_RESULT)
821
return to->store_decimal(from->val_decimal(&buff));
824
return to->store(from->val_int(), test(from->flags & UNSIGNED_FLAG));