00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00027 #include <config.h>
00028
00029 #include <drizzled/error.h>
00030 #include <drizzled/table.h>
00031 #include <drizzled/session.h>
00032 #include <drizzled/current_session.h>
00033
00034 #include <drizzled/copy_field.h>
00035 #include <drizzled/field/blob.h>
00036 #include <drizzled/field/date.h>
00037 #include <drizzled/field/datetime.h>
00038 #include <drizzled/field/decimal.h>
00039 #include <drizzled/field/double.h>
00040 #include <drizzled/field/enum.h>
00041 #include <drizzled/field/epoch.h>
00042 #include <drizzled/field/int32.h>
00043 #include <drizzled/field/int64.h>
00044 #include <drizzled/field/null.h>
00045 #include <drizzled/field/num.h>
00046 #include <drizzled/field/num.h>
00047 #include <drizzled/field/real.h>
00048 #include <drizzled/field/str.h>
00049 #include <drizzled/field/varstring.h>
00050
00051 namespace drizzled
00052 {
00053
00054 static void do_field_eq(CopyField *copy)
00055 {
00056 memcpy(copy->to_ptr, copy->from_ptr, copy->from_length);
00057 }
00058
00059 static void do_field_1(CopyField *copy)
00060 {
00061 copy->to_ptr[0]= copy->from_ptr[0];
00062 }
00063
00064 static void do_field_2(CopyField *copy)
00065 {
00066 copy->to_ptr[0]= copy->from_ptr[0];
00067 copy->to_ptr[1]= copy->from_ptr[1];
00068 }
00069
00070 static void do_field_3(CopyField *copy)
00071 {
00072 copy->to_ptr[0]= copy->from_ptr[0];
00073 copy->to_ptr[1]= copy->from_ptr[1];
00074 copy->to_ptr[2]= copy->from_ptr[2];
00075 }
00076
00077 static void do_field_4(CopyField *copy)
00078 {
00079 copy->to_ptr[0]= copy->from_ptr[0];
00080 copy->to_ptr[1]= copy->from_ptr[1];
00081 copy->to_ptr[2]= copy->from_ptr[2];
00082 copy->to_ptr[3]= copy->from_ptr[3];
00083 }
00084
00085 static void do_field_6(CopyField *copy)
00086 {
00087 copy->to_ptr[0]= copy->from_ptr[0];
00088 copy->to_ptr[1]= copy->from_ptr[1];
00089 copy->to_ptr[2]= copy->from_ptr[2];
00090 copy->to_ptr[3]= copy->from_ptr[3];
00091 copy->to_ptr[4]= copy->from_ptr[4];
00092 copy->to_ptr[5]= copy->from_ptr[5];
00093 }
00094
00095 static void do_field_8(CopyField *copy)
00096 {
00097 copy->to_ptr[0]= copy->from_ptr[0];
00098 copy->to_ptr[1]= copy->from_ptr[1];
00099 copy->to_ptr[2]= copy->from_ptr[2];
00100 copy->to_ptr[3]= copy->from_ptr[3];
00101 copy->to_ptr[4]= copy->from_ptr[4];
00102 copy->to_ptr[5]= copy->from_ptr[5];
00103 copy->to_ptr[6]= copy->from_ptr[6];
00104 copy->to_ptr[7]= copy->from_ptr[7];
00105 }
00106
00107
00108 static void do_field_to_null_str(CopyField *copy)
00109 {
00110 if (*copy->from_null_ptr & copy->from_bit)
00111 {
00112 memset(copy->to_ptr, 0, copy->from_length);
00113 copy->to_null_ptr[0]= 1;
00114 }
00115 else
00116 {
00117 copy->to_null_ptr[0]= 0;
00118 memcpy(copy->to_ptr, copy->from_ptr, copy->from_length);
00119 }
00120 }
00121
00122
00123 static void do_outer_field_to_null_str(CopyField *copy)
00124 {
00125 if (*copy->null_row ||
00126 (copy->from_null_ptr && (*copy->from_null_ptr & copy->from_bit)))
00127 {
00128 memset(copy->to_ptr, 0, copy->from_length);
00129 copy->to_null_ptr[0]= 1;
00130 }
00131 else
00132 {
00133 copy->to_null_ptr[0]= 0;
00134 memcpy(copy->to_ptr, copy->from_ptr, copy->from_length);
00135 }
00136 }
00137
00138
00139 int
00140 set_field_to_null(Field *field)
00141 {
00142 if (field->real_maybe_null())
00143 {
00144 field->set_null();
00145 field->reset();
00146 return 0;
00147 }
00148 field->reset();
00149 if (field->getTable()->in_use->count_cuted_fields == CHECK_FIELD_WARN)
00150 {
00151 field->set_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED, 1);
00152 return 0;
00153 }
00154 if (!field->getTable()->in_use->no_errors)
00155 my_error(ER_BAD_NULL_ERROR, MYF(0), field->field_name);
00156 return -1;
00157 }
00158
00159
00177 int
00178 set_field_to_null_with_conversions(Field *field, bool no_conversions)
00179 {
00180 if (field->real_maybe_null())
00181 {
00182 field->set_null();
00183 field->reset();
00184 return 0;
00185 }
00186
00187 if (no_conversions)
00188 return -1;
00189
00190
00191
00192
00193
00194
00195 if (field->is_timestamp())
00196 {
00197 ((field::Epoch::pointer) field)->set_time();
00198 return 0;
00199 }
00200
00201 field->reset();
00202 if (field == field->getTable()->next_number_field)
00203 {
00204 field->getTable()->auto_increment_field_not_null= false;
00205 return 0;
00206 }
00207
00208 if (field->getTable()->in_use->count_cuted_fields == CHECK_FIELD_WARN)
00209 {
00210 field->set_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_BAD_NULL_ERROR, 1);
00211 return 0;
00212 }
00213
00214 if (!field->getTable()->in_use->no_errors)
00215 my_error(ER_BAD_NULL_ERROR, MYF(0), field->field_name);
00216
00217 return -1;
00218 }
00219
00220
00221 static void do_skip(CopyField *)
00222 {
00223 }
00224
00225
00226 static void do_copy_null(CopyField *copy)
00227 {
00228 if (*copy->from_null_ptr & copy->from_bit)
00229 {
00230 *copy->to_null_ptr|= copy->to_bit;
00231 copy->to_field->reset();
00232 }
00233 else
00234 {
00235 *copy->to_null_ptr&= ~copy->to_bit;
00236 (copy->do_copy2)(copy);
00237 }
00238 }
00239
00240
00241 static void do_outer_field_null(CopyField *copy)
00242 {
00243 if (*copy->null_row ||
00244 (copy->from_null_ptr && (*copy->from_null_ptr & copy->from_bit)))
00245 {
00246 *copy->to_null_ptr|=copy->to_bit;
00247 copy->to_field->reset();
00248 }
00249 else
00250 {
00251 *copy->to_null_ptr&= ~copy->to_bit;
00252 (copy->do_copy2)(copy);
00253 }
00254 }
00255
00256
00257 static void do_copy_not_null(CopyField *copy)
00258 {
00259 if (copy->to_field->hasDefault() and *copy->from_null_ptr & copy->from_bit)
00260 {
00261 copy->to_field->set_default();
00262 }
00263 else if (*copy->from_null_ptr & copy->from_bit)
00264 {
00265 copy->to_field->set_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN,
00266 ER_WARN_DATA_TRUNCATED, 1);
00267 copy->to_field->reset();
00268 }
00269 else
00270 {
00271 (copy->do_copy2)(copy);
00272 }
00273 }
00274
00275
00276 static void do_copy_maybe_null(CopyField *copy)
00277 {
00278 *copy->to_null_ptr&= ~copy->to_bit;
00279 (copy->do_copy2)(copy);
00280 }
00281
00282
00283
00284 static void do_copy_timestamp(CopyField *copy)
00285 {
00286 if (*copy->from_null_ptr & copy->from_bit)
00287 {
00288
00289 ((field::Epoch::pointer) copy->to_field)->set_time();
00290 }
00291 else
00292 {
00293 (copy->do_copy2)(copy);
00294 }
00295 }
00296
00297
00298 static void do_copy_next_number(CopyField *copy)
00299 {
00300 if (*copy->from_null_ptr & copy->from_bit)
00301 {
00302
00303 copy->to_field->getTable()->auto_increment_field_not_null= false;
00304 copy->to_field->reset();
00305 }
00306 else
00307 {
00308 (copy->do_copy2)(copy);
00309 }
00310 }
00311
00312
00313 static void do_copy_blob(CopyField *copy)
00314 {
00315 ulong length= ((Field_blob*) copy->from_field)->get_length();
00316 ((Field_blob*) copy->to_field)->store_length(length);
00317 memcpy(copy->to_ptr, copy->from_ptr, sizeof(char*));
00318 }
00319
00320 static void do_conv_blob(CopyField *copy)
00321 {
00322 copy->from_field->val_str_internal(©->tmp);
00323 ((Field_blob *) copy->to_field)->store(copy->tmp.ptr(),
00324 copy->tmp.length(),
00325 copy->tmp.charset());
00326 }
00327
00330 static void do_save_blob(CopyField *copy)
00331 {
00332 char buff[MAX_FIELD_WIDTH];
00333 String res(buff, sizeof(buff), copy->tmp.charset());
00334 copy->from_field->val_str_internal(&res);
00335 copy->tmp.copy(res);
00336 ((Field_blob *) copy->to_field)->store(copy->tmp.ptr(),
00337 copy->tmp.length(),
00338 copy->tmp.charset());
00339 }
00340
00341
00342 static void do_field_string(CopyField *copy)
00343 {
00344 char buff[MAX_FIELD_WIDTH];
00345 copy->tmp.set_quick(buff,sizeof(buff),copy->tmp.charset());
00346 copy->from_field->val_str_internal(©->tmp);
00347 copy->to_field->store(copy->tmp.c_ptr_quick(),copy->tmp.length(),
00348 copy->tmp.charset());
00349 }
00350
00351
00352 static void do_field_enum(CopyField *copy)
00353 {
00354 if (copy->from_field->val_int() == 0)
00355 ((Field_enum *) copy->to_field)->store_type((uint64_t) 0);
00356 else
00357 do_field_string(copy);
00358 }
00359
00360
00361 static void do_field_int(CopyField *copy)
00362 {
00363 int64_t value= copy->from_field->val_int();
00364 copy->to_field->store(value,
00365 test(copy->from_field->flags & UNSIGNED_FLAG));
00366 }
00367
00368 static void do_field_real(CopyField *copy)
00369 {
00370 double value=copy->from_field->val_real();
00371 copy->to_field->store(value);
00372 }
00373
00374
00375 static void do_field_decimal(CopyField *copy)
00376 {
00377 type::Decimal value;
00378 copy->to_field->store_decimal(copy->from_field->val_decimal(&value));
00379 }
00380
00381
00387 static void do_cut_string(CopyField *copy)
00388 {
00389 const CHARSET_INFO * const cs= copy->from_field->charset();
00390 memcpy(copy->to_ptr, copy->from_ptr, copy->to_length);
00391
00392
00393 if (cs->cset->scan(cs,
00394 (char*) copy->from_ptr + copy->to_length,
00395 (char*) copy->from_ptr + copy->from_length,
00396 MY_SEQ_SPACES) < copy->from_length - copy->to_length)
00397 {
00398 copy->to_field->set_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN,
00399 ER_WARN_DATA_TRUNCATED, 1);
00400 }
00401 }
00402
00403
00409 static void do_cut_string_complex(CopyField *copy)
00410 {
00411 int well_formed_error;
00412 const CHARSET_INFO * const cs= copy->from_field->charset();
00413 const unsigned char *from_end= copy->from_ptr + copy->from_length;
00414 uint32_t copy_length= cs->cset->well_formed_len(cs,
00415 (char*) copy->from_ptr,
00416 (char*) from_end,
00417 copy->to_length / cs->mbmaxlen,
00418 &well_formed_error);
00419 if (copy->to_length < copy_length)
00420 copy_length= copy->to_length;
00421 memcpy(copy->to_ptr, copy->from_ptr, copy_length);
00422
00423
00424 if (well_formed_error ||
00425 cs->cset->scan(cs, (char*) copy->from_ptr + copy_length,
00426 (char*) from_end,
00427 MY_SEQ_SPACES) < (copy->from_length - copy_length))
00428 {
00429 copy->to_field->set_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN,
00430 ER_WARN_DATA_TRUNCATED, 1);
00431 }
00432
00433 if (copy_length < copy->to_length)
00434 cs->cset->fill(cs, (char*) copy->to_ptr + copy_length,
00435 copy->to_length - copy_length, ' ');
00436 }
00437
00438
00439
00440
00441 static void do_expand_binary(CopyField *copy)
00442 {
00443 const CHARSET_INFO * const cs= copy->from_field->charset();
00444 memcpy(copy->to_ptr, copy->from_ptr, copy->from_length);
00445 cs->cset->fill(cs, (char*) copy->to_ptr+copy->from_length,
00446 copy->to_length-copy->from_length, '\0');
00447 }
00448
00449
00450
00451 static void do_expand_string(CopyField *copy)
00452 {
00453 const CHARSET_INFO * const cs= copy->from_field->charset();
00454 memcpy(copy->to_ptr,copy->from_ptr,copy->from_length);
00455 cs->cset->fill(cs, (char*) copy->to_ptr+copy->from_length,
00456 copy->to_length-copy->from_length, ' ');
00457 }
00458
00459
00460 static void do_varstring1(CopyField *copy)
00461 {
00462 uint32_t length= (uint32_t) *(unsigned char*) copy->from_ptr;
00463 if (length > copy->to_length- 1)
00464 {
00465 length= copy->to_length - 1;
00466 if (copy->from_field->getTable()->in_use->count_cuted_fields)
00467 {
00468 copy->to_field->set_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN,
00469 ER_WARN_DATA_TRUNCATED, 1);
00470 }
00471 }
00472 *(unsigned char*) copy->to_ptr= (unsigned char) length;
00473 memcpy(copy->to_ptr+1, copy->from_ptr + 1, length);
00474 }
00475
00476
00477 static void do_varstring1_mb(CopyField *copy)
00478 {
00479 int well_formed_error;
00480 const CHARSET_INFO * const cs= copy->from_field->charset();
00481 uint32_t from_length= (uint32_t) *(unsigned char*) copy->from_ptr;
00482 const unsigned char *from_ptr= copy->from_ptr + 1;
00483 uint32_t to_char_length= (copy->to_length - 1) / cs->mbmaxlen;
00484 uint32_t length= cs->cset->well_formed_len(cs, (char*) from_ptr,
00485 (char*) from_ptr + from_length,
00486 to_char_length, &well_formed_error);
00487 if (length < from_length)
00488 {
00489 if (current_session->count_cuted_fields)
00490 {
00491 copy->to_field->set_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN,
00492 ER_WARN_DATA_TRUNCATED, 1);
00493 }
00494 }
00495 *copy->to_ptr= (unsigned char) length;
00496 memcpy(copy->to_ptr + 1, from_ptr, length);
00497 }
00498
00499
00500 static void do_varstring2(CopyField *copy)
00501 {
00502 uint32_t length= uint2korr(copy->from_ptr);
00503 if (length > copy->to_length- HA_KEY_BLOB_LENGTH)
00504 {
00505 length=copy->to_length-HA_KEY_BLOB_LENGTH;
00506 if (copy->from_field->getTable()->in_use->count_cuted_fields)
00507 {
00508 copy->to_field->set_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN,
00509 ER_WARN_DATA_TRUNCATED, 1);
00510 }
00511 }
00512 int2store(copy->to_ptr,length);
00513 memcpy(copy->to_ptr+HA_KEY_BLOB_LENGTH, copy->from_ptr + HA_KEY_BLOB_LENGTH,
00514 length);
00515 }
00516
00517
00518 static void do_varstring2_mb(CopyField *copy)
00519 {
00520 int well_formed_error;
00521 const CHARSET_INFO * const cs= copy->from_field->charset();
00522 uint32_t char_length= (copy->to_length - HA_KEY_BLOB_LENGTH) / cs->mbmaxlen;
00523 uint32_t from_length= uint2korr(copy->from_ptr);
00524 const unsigned char *from_beg= copy->from_ptr + HA_KEY_BLOB_LENGTH;
00525 uint32_t length= cs->cset->well_formed_len(cs, (char*) from_beg,
00526 (char*) from_beg + from_length,
00527 char_length, &well_formed_error);
00528 if (length < from_length)
00529 {
00530 if (current_session->count_cuted_fields)
00531 {
00532 copy->to_field->set_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN,
00533 ER_WARN_DATA_TRUNCATED, 1);
00534 }
00535 }
00536 int2store(copy->to_ptr, length);
00537 memcpy(copy->to_ptr+HA_KEY_BLOB_LENGTH, from_beg, length);
00538 }
00539
00540
00541
00542
00543
00544
00553 void CopyField::set(unsigned char *to,Field *from)
00554 {
00555 from_ptr= from->ptr;
00556 to_ptr= to;
00557 from_length= from->pack_length();
00558 if (from->maybe_null())
00559 {
00560 from_null_ptr= from->null_ptr;
00561 from_bit= from->null_bit;
00562 to_ptr[0]= 1;
00563 to_null_ptr= (unsigned char*) to_ptr++;
00564 to_bit= 1;
00565 if (from->getTable()->maybe_null)
00566 {
00567 null_row= &from->getTable()->null_row;
00568 do_copy= do_outer_field_to_null_str;
00569 }
00570 else
00571 do_copy= do_field_to_null_str;
00572 }
00573 else
00574 {
00575 to_null_ptr= 0;
00576 do_copy= do_field_eq;
00577 }
00578 }
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596 void CopyField::set(Field *to,Field *from,bool save)
00597 {
00598 if (to->type() == DRIZZLE_TYPE_NULL)
00599 {
00600 to_null_ptr= 0;
00601 to_ptr= 0;
00602 do_copy= do_skip;
00603 return;
00604 }
00605 from_field= from;
00606 to_field= to;
00607 from_ptr= from->ptr;
00608 from_length= from->pack_length();
00609 to_ptr= to->ptr;
00610 to_length= to_field->pack_length();
00611
00612
00613 from_null_ptr= to_null_ptr= 0;
00614 if (from->maybe_null())
00615 {
00616 from_null_ptr= from->null_ptr;
00617 from_bit= from->null_bit;
00618 if (to_field->real_maybe_null())
00619 {
00620 to_null_ptr= to->null_ptr;
00621 to_bit= to->null_bit;
00622 if (from_null_ptr)
00623 {
00624 do_copy= do_copy_null;
00625 }
00626 else
00627 {
00628 null_row= &from->getTable()->null_row;
00629 do_copy= do_outer_field_null;
00630 }
00631 }
00632 else
00633 {
00634 if (to_field->is_timestamp())
00635 {
00636 do_copy= do_copy_timestamp;
00637 }
00638 else if (to_field == to_field->getTable()->next_number_field)
00639 {
00640 do_copy= do_copy_next_number;
00641 }
00642 else
00643 {
00644 do_copy= do_copy_not_null;
00645 }
00646 }
00647 }
00648 else if (to_field->real_maybe_null())
00649 {
00650 to_null_ptr= to->null_ptr;
00651 to_bit= to->null_bit;
00652 do_copy= do_copy_maybe_null;
00653 }
00654 else
00655 do_copy= 0;
00656
00657 if ((to->flags & BLOB_FLAG) && save)
00658 do_copy2= do_save_blob;
00659 else
00660 do_copy2= get_copy_func(to,from);
00661 if (!do_copy)
00662 do_copy= do_copy2;
00663 }
00664
00665
00666 CopyField::Copy_func *
00667 CopyField::get_copy_func(Field *to,Field *from)
00668 {
00669 bool compatible_db_low_byte_first= (to->getTable()->getShare()->db_low_byte_first ==
00670 from->getTable()->getShare()->db_low_byte_first);
00671 if (to->flags & BLOB_FLAG)
00672 {
00673 if (!(from->flags & BLOB_FLAG) || from->charset() != to->charset())
00674 return do_conv_blob;
00675 if (from_length != to_length || !compatible_db_low_byte_first)
00676 {
00677
00678 to_ptr+= to_length - to->getTable()->getShare()->sizeBlobPtr();
00679 from_ptr+= from_length- from->getTable()->getShare()->sizeBlobPtr();
00680 return do_copy_blob;
00681 }
00682 }
00683 else
00684 {
00685 if (to->result_type() == DECIMAL_RESULT)
00686 return do_field_decimal;
00687
00688
00689 if (from->result_type() == STRING_RESULT)
00690 {
00691
00692
00693
00694
00695 if (to->real_type() != from->real_type() ||
00696 !compatible_db_low_byte_first ||
00697 (((to->getTable()->in_use->variables.sql_mode & (MODE_NO_ZERO_DATE | MODE_INVALID_DATES)) && to->type() == DRIZZLE_TYPE_DATE) || to->type() == DRIZZLE_TYPE_DATETIME))
00698 {
00699 if (from->real_type() == DRIZZLE_TYPE_ENUM)
00700 {
00701 if (to->result_type() != STRING_RESULT)
00702 {
00703 return do_field_int;
00704 }
00705
00706 return do_field_string;
00707 }
00708 }
00709
00710 if (to->real_type() == DRIZZLE_TYPE_ENUM)
00711 {
00712 if (!to->eq_def(from))
00713 {
00714 if (from->real_type() == DRIZZLE_TYPE_ENUM &&
00715 to->real_type() == DRIZZLE_TYPE_ENUM)
00716 return do_field_enum;
00717 else
00718 return do_field_string;
00719 }
00720 }
00721 else if (to->charset() != from->charset())
00722 return do_field_string;
00723 else if (to->real_type() == DRIZZLE_TYPE_VARCHAR)
00724 {
00725
00726
00727
00728
00729
00730
00731
00732
00733 if (from->flags & BLOB_FLAG)
00734 return do_field_string;
00735
00736 if ((static_cast<Field_varstring*>(to))->pack_length_no_ptr() !=
00737 (static_cast<Field_varstring*>(from))->pack_length_no_ptr())
00738 {
00739 return do_field_string;
00740 }
00741
00742 if (to_length != from_length)
00743 {
00744 return (((Field_varstring*) to)->pack_length_no_ptr() == 1 ?
00745 (from->charset()->mbmaxlen == 1 ? do_varstring1 :
00746 do_varstring1_mb) :
00747 (from->charset()->mbmaxlen == 1 ? do_varstring2 :
00748 do_varstring2_mb));
00749 }
00750 }
00751 else if (to_length < from_length)
00752 {
00753 return (from->charset()->mbmaxlen == 1 ?
00754 do_cut_string : do_cut_string_complex);
00755 }
00756 else if (to_length > from_length)
00757 {
00758 if (to->charset() == &my_charset_bin)
00759 return do_expand_binary;
00760 else
00761 return do_expand_string;
00762 }
00763 }
00764 else if (to->real_type() != from->real_type() ||
00765 to_length != from_length ||
00766 !compatible_db_low_byte_first)
00767 {
00768 if (to->result_type() == STRING_RESULT)
00769 return do_field_string;
00770 if (to->result_type() == INT_RESULT)
00771 return do_field_int;
00772
00773 return do_field_real;
00774 }
00775 else
00776 {
00777 if (!to->eq_def(from) || !compatible_db_low_byte_first)
00778 {
00779 if (to->result_type() == INT_RESULT)
00780 return do_field_int;
00781 else
00782 return do_field_real;
00783 }
00784 }
00785 }
00786
00787
00788 switch (to_length)
00789 {
00790 case 1: return do_field_1;
00791 case 2: return do_field_2;
00792 case 3: return do_field_3;
00793 case 4: return do_field_4;
00794 case 6: return do_field_6;
00795 case 8: return do_field_8;
00796 }
00797
00798 return do_field_eq;
00799 }
00800
00801
00804 int field_conv(Field *to,Field *from)
00805 {
00806 if (to->real_type() == from->real_type() &&
00807 !(to->type() == DRIZZLE_TYPE_BLOB && to->getTable()->copy_blobs))
00808 {
00809
00810 if (to->pack_length() == from->pack_length() &&
00811 !(to->flags & UNSIGNED_FLAG && !(from->flags & UNSIGNED_FLAG)) &&
00812 to->real_type() != DRIZZLE_TYPE_ENUM &&
00813 (to->real_type() != DRIZZLE_TYPE_DECIMAL || (to->field_length == from->field_length && (((Field_num*)to)->dec == ((Field_num*)from)->dec))) &&
00814 from->charset() == to->charset() &&
00815 to->getTable()->getShare()->db_low_byte_first == from->getTable()->getShare()->db_low_byte_first &&
00816 (!(to->getTable()->in_use->variables.sql_mode & (MODE_NO_ZERO_DATE | MODE_INVALID_DATES)) || (to->type() != DRIZZLE_TYPE_DATE && to->type() != DRIZZLE_TYPE_DATETIME)) &&
00817 (from->real_type() != DRIZZLE_TYPE_VARCHAR || ((Field_varstring*)from)->pack_length_no_ptr() == ((Field_varstring*)to)->pack_length_no_ptr()))
00818 {
00819
00820 if (to->ptr != from->ptr)
00821 memcpy(to->ptr,from->ptr,to->pack_length());
00822 return 0;
00823 }
00824 }
00825 if (to->type() == DRIZZLE_TYPE_BLOB)
00826 {
00827 Field_blob *blob=(Field_blob*) to;
00828 from->val_str_internal(&blob->value);
00829
00830
00831
00832
00833 if (to->getTable()->copy_blobs ||
00834 (!blob->value.is_alloced() &&
00835 from->real_type() != DRIZZLE_TYPE_VARCHAR))
00836 blob->value.copy();
00837 return blob->store(blob->value.ptr(),blob->value.length(),from->charset());
00838 }
00839 if (from->real_type() == DRIZZLE_TYPE_ENUM &&
00840 to->real_type() == DRIZZLE_TYPE_ENUM &&
00841 from->val_int() == 0)
00842 {
00843 ((Field_enum *)(to))->store_type(0);
00844 return 0;
00845 }
00846 else if ((from->result_type() == STRING_RESULT &&
00847 (to->result_type() == STRING_RESULT ||
00848 (from->real_type() != DRIZZLE_TYPE_ENUM))))
00849 {
00850 char buff[MAX_FIELD_WIDTH];
00851 String result(buff,sizeof(buff),from->charset());
00852 from->val_str_internal(&result);
00853
00854
00855
00856
00857
00858
00859 return to->store(result.c_ptr_quick(),result.length(),from->charset());
00860 }
00861 else if (from->result_type() == REAL_RESULT)
00862 {
00863 return to->store(from->val_real());
00864 }
00865 else if (from->result_type() == DECIMAL_RESULT)
00866 {
00867 type::Decimal buff;
00868 return to->store_decimal(from->val_decimal(&buff));
00869 }
00870 else
00871 {
00872 return to->store(from->val_int(), test(from->flags & UNSIGNED_FLAG));
00873 }
00874 }
00875
00876 }