~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/field_conv.cc

Merge Joe, plus I updated the tests.

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