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