~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/field_conv.cc

Merge in Stewart's FK work

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