~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/field_conv.cc

  • Committer: Olaf van der Spek
  • Date: 2011-02-12 18:24:24 UTC
  • mto: (2167.1.2 build) (2172.1.4 build)
  • mto: This revision was merged to the branch mainline in revision 2168.
  • Revision ID: olafvdspek@gmail.com-20110212182424-kgnm9osi7qo97at2
casts

Show diffs side-by-side

added added

removed removed

Lines of Context:
11
11
 
12
12
   You should have received a copy of the GNU General Public License
13
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 */
 
14
   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
15
15
 
16
16
 
17
17
/**
38
38
#include <drizzled/field/decimal.h>
39
39
#include <drizzled/field/real.h>
40
40
#include <drizzled/field/double.h>
41
 
#include <drizzled/field/long.h>
42
 
#include <drizzled/field/int64_t.h>
 
41
#include <drizzled/field/int32.h>
 
42
#include <drizzled/field/int64.h>
43
43
#include <drizzled/field/num.h>
44
 
#include <drizzled/field/timestamp.h>
 
44
#include <drizzled/field/epoch.h>
45
45
#include <drizzled/field/datetime.h>
46
46
#include <drizzled/field/varstring.h>
47
47
 
143
143
    return 0;
144
144
  }
145
145
  field->reset();
146
 
  if (field->table->in_use->count_cuted_fields == CHECK_FIELD_WARN)
 
146
  if (field->getTable()->in_use->count_cuted_fields == CHECK_FIELD_WARN)
147
147
  {
148
148
    field->set_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED, 1);
149
149
    return 0;
150
150
  }
151
 
  if (!field->table->in_use->no_errors)
 
151
  if (!field->getTable()->in_use->no_errors)
152
152
    my_error(ER_BAD_NULL_ERROR, MYF(0), field->field_name);
153
153
  return -1;
154
154
}
180
180
    field->reset();
181
181
    return 0;
182
182
  }
 
183
 
183
184
  if (no_conversions)
184
185
    return -1;
185
186
 
188
189
    when set to NULL (TIMESTAMP fields which allow setting to NULL
189
190
    are handled by first check).
190
191
  */
191
 
  if (field->type() == DRIZZLE_TYPE_TIMESTAMP)
 
192
  if (field->is_timestamp())
192
193
  {
193
 
    ((Field_timestamp*) field)->set_time();
 
194
    ((field::Epoch::pointer) field)->set_time();
194
195
    return 0;                                   // Ok to set time to NULL
195
196
  }
 
197
 
196
198
  field->reset();
197
 
  if (field == field->table->next_number_field)
 
199
  if (field == field->getTable()->next_number_field)
198
200
  {
199
 
    field->table->auto_increment_field_not_null= false;
 
201
    field->getTable()->auto_increment_field_not_null= false;
200
202
    return 0;                             // field is set in fill_record()
201
203
  }
202
 
  if (field->table->in_use->count_cuted_fields == CHECK_FIELD_WARN)
 
204
 
 
205
  if (field->getTable()->in_use->count_cuted_fields == CHECK_FIELD_WARN)
203
206
  {
204
207
    field->set_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_BAD_NULL_ERROR, 1);
205
208
    return 0;
206
209
  }
207
 
  if (!field->table->in_use->no_errors)
 
210
 
 
211
  if (!field->getTable()->in_use->no_errors)
208
212
    my_error(ER_BAD_NULL_ERROR, MYF(0), field->field_name);
 
213
 
209
214
  return -1;
210
215
}
211
216
 
248
253
 
249
254
static void do_copy_not_null(CopyField *copy)
250
255
{
251
 
  if (*copy->from_null_ptr & copy->from_bit)
 
256
  if (copy->to_field->hasDefault() and *copy->from_null_ptr & copy->from_bit)
 
257
  {
 
258
    copy->to_field->set_default();
 
259
  }
 
260
  else if (*copy->from_null_ptr & copy->from_bit)
252
261
  {
253
262
    copy->to_field->set_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN,
254
263
                                ER_WARN_DATA_TRUNCATED, 1);
255
264
    copy->to_field->reset();
256
265
  }
257
266
  else
 
267
  {
258
268
    (copy->do_copy2)(copy);
 
269
  }
259
270
}
260
271
 
261
272
 
272
283
  if (*copy->from_null_ptr & copy->from_bit)
273
284
  {
274
285
    /* Same as in set_field_to_null_with_conversions() */
275
 
    ((Field_timestamp*) copy->to_field)->set_time();
 
286
    ((field::Epoch::pointer) copy->to_field)->set_time();
276
287
  }
277
288
  else
 
289
  {
278
290
    (copy->do_copy2)(copy);
 
291
  }
279
292
}
280
293
 
281
294
 
284
297
  if (*copy->from_null_ptr & copy->from_bit)
285
298
  {
286
299
    /* Same as in set_field_to_null_with_conversions() */
287
 
    copy->to_field->table->auto_increment_field_not_null= false;
 
300
    copy->to_field->getTable()->auto_increment_field_not_null= false;
288
301
    copy->to_field->reset();
289
302
  }
290
303
  else
 
304
  {
291
305
    (copy->do_copy2)(copy);
 
306
  }
292
307
}
293
308
 
294
309
 
301
316
 
302
317
static void do_conv_blob(CopyField *copy)
303
318
{
304
 
  copy->from_field->val_str(&copy->tmp);
 
319
  copy->from_field->val_str_internal(&copy->tmp);
305
320
  ((Field_blob *) copy->to_field)->store(copy->tmp.ptr(),
306
321
                                         copy->tmp.length(),
307
322
                                         copy->tmp.charset());
313
328
{
314
329
  char buff[MAX_FIELD_WIDTH];
315
330
  String res(buff, sizeof(buff), copy->tmp.charset());
316
 
  copy->from_field->val_str(&res);
 
331
  copy->from_field->val_str_internal(&res);
317
332
  copy->tmp.copy(res);
318
333
  ((Field_blob *) copy->to_field)->store(copy->tmp.ptr(),
319
334
                                         copy->tmp.length(),
325
340
{
326
341
  char buff[MAX_FIELD_WIDTH];
327
342
  copy->tmp.set_quick(buff,sizeof(buff),copy->tmp.charset());
328
 
  copy->from_field->val_str(&copy->tmp);
 
343
  copy->from_field->val_str_internal(&copy->tmp);
329
344
  copy->to_field->store(copy->tmp.c_ptr_quick(),copy->tmp.length(),
330
345
                        copy->tmp.charset());
331
346
}
356
371
 
357
372
static void do_field_decimal(CopyField *copy)
358
373
{
359
 
  my_decimal value;
 
374
  type::Decimal value;
360
375
  copy->to_field->store_decimal(copy->from_field->val_decimal(&value));
361
376
}
362
377
 
369
384
static void do_cut_string(CopyField *copy)
370
385
{
371
386
  const CHARSET_INFO * const cs= copy->from_field->charset();
372
 
  memcpy(copy->to_ptr,copy->from_ptr,copy->to_length);
 
387
  memcpy(copy->to_ptr, copy->from_ptr, copy->to_length);
373
388
 
374
389
  /* Check if we loosed any important characters */
375
390
  if (cs->cset->scan(cs,
445
460
  if (length > copy->to_length- 1)
446
461
  {
447
462
    length= copy->to_length - 1;
448
 
    if (copy->from_field->table->in_use->count_cuted_fields)
 
463
    if (copy->from_field->getTable()->in_use->count_cuted_fields)
 
464
    {
449
465
      copy->to_field->set_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN,
450
466
                                  ER_WARN_DATA_TRUNCATED, 1);
 
467
    }
451
468
  }
452
469
  *(unsigned char*) copy->to_ptr= (unsigned char) length;
453
470
  memcpy(copy->to_ptr+1, copy->from_ptr + 1, length);
467
484
  if (length < from_length)
468
485
  {
469
486
    if (current_session->count_cuted_fields)
 
487
    {
470
488
      copy->to_field->set_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN,
471
489
                                  ER_WARN_DATA_TRUNCATED, 1);
 
490
    }
472
491
  }
473
492
  *copy->to_ptr= (unsigned char) length;
474
493
  memcpy(copy->to_ptr + 1, from_ptr, length);
481
500
  if (length > copy->to_length- HA_KEY_BLOB_LENGTH)
482
501
  {
483
502
    length=copy->to_length-HA_KEY_BLOB_LENGTH;
484
 
    if (copy->from_field->table->in_use->count_cuted_fields)
 
503
    if (copy->from_field->getTable()->in_use->count_cuted_fields)
 
504
    {
485
505
      copy->to_field->set_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN,
486
506
                                  ER_WARN_DATA_TRUNCATED, 1);
 
507
    }
487
508
  }
488
509
  int2store(copy->to_ptr,length);
489
510
  memcpy(copy->to_ptr+HA_KEY_BLOB_LENGTH, copy->from_ptr + HA_KEY_BLOB_LENGTH,
504
525
  if (length < from_length)
505
526
  {
506
527
    if (current_session->count_cuted_fields)
 
528
    {
507
529
      copy->to_field->set_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN,
508
530
                                  ER_WARN_DATA_TRUNCATED, 1);
 
531
    }
509
532
  }
510
533
  int2store(copy->to_ptr, length);
511
534
  memcpy(copy->to_ptr+HA_KEY_BLOB_LENGTH, from_beg, length);
536
559
    to_ptr[0]= 1;                             // Null as default value
537
560
    to_null_ptr= (unsigned char*) to_ptr++;
538
561
    to_bit= 1;
539
 
    if (from->table->maybe_null)
 
562
    if (from->getTable()->maybe_null)
540
563
    {
541
 
      null_row= &from->table->null_row;
 
564
      null_row= &from->getTable()->null_row;
542
565
      do_copy= do_outer_field_to_null_str;
543
566
    }
544
567
    else
594
617
      to_null_ptr= to->null_ptr;
595
618
      to_bit= to->null_bit;
596
619
      if (from_null_ptr)
 
620
      {
597
621
        do_copy= do_copy_null;
 
622
      }
598
623
      else
599
624
      {
600
 
        null_row= &from->table->null_row;
 
625
        null_row= &from->getTable()->null_row;
601
626
        do_copy= do_outer_field_null;
602
627
      }
603
628
    }
604
629
    else
605
630
    {
606
 
      if (to_field->type() == DRIZZLE_TYPE_TIMESTAMP)
 
631
      if (to_field->is_timestamp())
 
632
      {
607
633
        do_copy= do_copy_timestamp;               // Automatic timestamp
608
 
      else if (to_field == to_field->table->next_number_field)
 
634
      }
 
635
      else if (to_field == to_field->getTable()->next_number_field)
 
636
      {
609
637
        do_copy= do_copy_next_number;
 
638
      }
610
639
      else
 
640
      {
611
641
        do_copy= do_copy_not_null;
 
642
      }
612
643
    }
613
644
  }
614
645
  else if (to_field->real_maybe_null())
632
663
CopyField::Copy_func *
633
664
CopyField::get_copy_func(Field *to,Field *from)
634
665
{
635
 
  bool compatible_db_low_byte_first= (to->table->s->db_low_byte_first ==
636
 
                                     from->table->s->db_low_byte_first);
 
666
  bool compatible_db_low_byte_first= (to->getTable()->getShare()->db_low_byte_first ==
 
667
                                     from->getTable()->getShare()->db_low_byte_first);
637
668
  if (to->flags & BLOB_FLAG)
638
669
  {
639
670
    if (!(from->flags & BLOB_FLAG) || from->charset() != to->charset())
641
672
    if (from_length != to_length || !compatible_db_low_byte_first)
642
673
    {
643
674
      // Correct pointer to point at char pointer
644
 
      to_ptr+= to_length - to->table->s->blob_ptr_size;
645
 
      from_ptr+= from_length- from->table->s->blob_ptr_size;
 
675
      to_ptr+= to_length - to->getTable()->getShare()->sizeBlobPtr();
 
676
      from_ptr+= from_length- from->getTable()->getShare()->sizeBlobPtr();
646
677
      return do_copy_blob;
647
678
    }
648
679
  }
660
691
      */
661
692
      if (to->real_type() != from->real_type() ||
662
693
          !compatible_db_low_byte_first ||
663
 
          (((to->table->in_use->variables.sql_mode & (MODE_NO_ZERO_DATE | MODE_INVALID_DATES)) && to->type() == DRIZZLE_TYPE_DATE) || to->type() == DRIZZLE_TYPE_DATETIME))
 
694
          (((to->getTable()->in_use->variables.sql_mode & (MODE_NO_ZERO_DATE | MODE_INVALID_DATES)) && to->type() == DRIZZLE_TYPE_DATE) || to->type() == DRIZZLE_TYPE_DATETIME))
664
695
      {
665
696
        if (from->real_type() == DRIZZLE_TYPE_ENUM)
666
697
        {
668
699
          {
669
700
            return do_field_int;  // Convert SET to number
670
701
          }
671
 
          
 
702
 
672
703
          return do_field_string;
673
704
        }
674
705
      }
675
 
      
 
706
 
676
707
      if (to->real_type() == DRIZZLE_TYPE_ENUM)
677
708
      {
678
709
        if (!to->eq_def(from))
688
719
        return do_field_string;
689
720
      else if (to->real_type() == DRIZZLE_TYPE_VARCHAR)
690
721
      {
691
 
        if (((Field_varstring*) to)->length_bytes !=
692
 
            ((Field_varstring*) from)->length_bytes)
 
722
        /* Field_blob is not part of the Field_varstring hierarchy,
 
723
          and casting to varstring for calling pack_length_no_ptr()
 
724
          is always incorrect. Previously the below comparison has
 
725
          always evaluated to false as pack_length_no_ptr() for BLOB
 
726
          will return 4 and varstring can only be <= 2.
 
727
          If your brain slightly bleeds as to why this worked for
 
728
          so many years, you are in no way alone.
 
729
        */
 
730
        if (from->flags & BLOB_FLAG)
 
731
          return do_field_string;
 
732
 
 
733
        if ((static_cast<Field_varstring*>(to))->pack_length_no_ptr() !=
 
734
            (static_cast<Field_varstring*>(from))->pack_length_no_ptr())
693
735
        {
694
736
          return do_field_string;
695
737
        }
696
 
        
 
738
 
697
739
        if (to_length != from_length)
698
740
        {
699
 
          return (((Field_varstring*) to)->length_bytes == 1 ?
 
741
          return (((Field_varstring*) to)->pack_length_no_ptr() == 1 ?
700
742
                  (from->charset()->mbmaxlen == 1 ? do_varstring1 :
701
 
                                                    do_varstring1_mb) :
 
743
                   do_varstring1_mb) :
702
744
                  (from->charset()->mbmaxlen == 1 ? do_varstring2 :
703
 
                                                    do_varstring2_mb));
 
745
                   do_varstring2_mb));
704
746
        }
705
747
      }
706
748
      else if (to_length < from_length)
759
801
int field_conv(Field *to,Field *from)
760
802
{
761
803
  if (to->real_type() == from->real_type() &&
762
 
      !(to->type() == DRIZZLE_TYPE_BLOB && to->table->copy_blobs))
 
804
      !(to->type() == DRIZZLE_TYPE_BLOB && to->getTable()->copy_blobs))
763
805
  {
764
806
    /* Please god, will someone rewrite this to be readable :( */
765
807
    if (to->pack_length() == from->pack_length() &&
767
809
        to->real_type() != DRIZZLE_TYPE_ENUM &&
768
810
        (to->real_type() != DRIZZLE_TYPE_DECIMAL || (to->field_length == from->field_length && (((Field_num*)to)->dec == ((Field_num*)from)->dec))) &&
769
811
        from->charset() == to->charset() &&
770
 
        to->table->s->db_low_byte_first == from->table->s->db_low_byte_first &&
771
 
        (!(to->table->in_use->variables.sql_mode & (MODE_NO_ZERO_DATE | MODE_INVALID_DATES)) || (to->type() != DRIZZLE_TYPE_DATE && to->type() != DRIZZLE_TYPE_DATETIME)) &&
772
 
        (from->real_type() != DRIZZLE_TYPE_VARCHAR || ((Field_varstring*)from)->length_bytes == ((Field_varstring*)to)->length_bytes))
 
812
        to->getTable()->getShare()->db_low_byte_first == from->getTable()->getShare()->db_low_byte_first &&
 
813
        (!(to->getTable()->in_use->variables.sql_mode & (MODE_NO_ZERO_DATE | MODE_INVALID_DATES)) || (to->type() != DRIZZLE_TYPE_DATE && to->type() != DRIZZLE_TYPE_DATETIME)) &&
 
814
        (from->real_type() != DRIZZLE_TYPE_VARCHAR || ((Field_varstring*)from)->pack_length_no_ptr() == ((Field_varstring*)to)->pack_length_no_ptr()))
773
815
    {                                           // Identical fields
774
816
      /* This may happen if one does 'UPDATE ... SET x=x' */
775
817
      if (to->ptr != from->ptr)
780
822
  if (to->type() == DRIZZLE_TYPE_BLOB)
781
823
  {                                             // Be sure the value is stored
782
824
    Field_blob *blob=(Field_blob*) to;
783
 
    from->val_str(&blob->value);
 
825
    from->val_str_internal(&blob->value);
784
826
    /*
785
827
      Copy value if copy_blobs is set, or source is not a string and
786
828
      we have a pointer to its internal string conversion buffer.
787
829
    */
788
 
    if (to->table->copy_blobs ||
 
830
    if (to->getTable()->copy_blobs ||
789
831
        (!blob->value.is_alloced() &&
790
832
         from->real_type() != DRIZZLE_TYPE_VARCHAR))
791
833
      blob->value.copy();
804
846
  {
805
847
    char buff[MAX_FIELD_WIDTH];
806
848
    String result(buff,sizeof(buff),from->charset());
807
 
    from->val_str(&result);
 
849
    from->val_str_internal(&result);
808
850
    /*
809
851
      We use c_ptr_quick() here to make it easier if to is a float/double
810
852
      as the conversion routines will do a copy of the result doesn't
814
856
    return to->store(result.c_ptr_quick(),result.length(),from->charset());
815
857
  }
816
858
  else if (from->result_type() == REAL_RESULT)
 
859
  {
817
860
    return to->store(from->val_real());
 
861
  }
818
862
  else if (from->result_type() == DECIMAL_RESULT)
819
863
  {
820
 
    my_decimal buff;
 
864
    type::Decimal buff;
821
865
    return to->store_decimal(from->val_decimal(&buff));
822
866
  }
823
867
  else
 
868
  {
824
869
    return to->store(from->val_int(), test(from->flags & UNSIGNED_FLAG));
 
870
  }
825
871
}
826
872
 
827
873
} /* namespace drizzled */