~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/table.cc

Create default_values record from proto instead of reading from FRM. assert if different to FRM.

Restore the "blob can't have default value" error message.

Fix default values for: blob, vachar, enum and varbinary.
Default value for a BLOB can be "" thanks to TINYTEXT or something.
proto now has default_bin_value as well as default_value. the default_bin_value used for varbinary and in future, blobs.

Load enum values out of proto instead of FRM and fill in the crazy interval structures.

Jay will fix up the create.test change (incorrect datetime for timestamp "0").

Show diffs side-by-side

added added

removed removed

Lines of Context:
341
341
  return field_type;
342
342
}
343
343
 
344
 
Item * default_value_item(enum_field_types field_type, bool default_null,
345
 
                          string default_value)
 
344
Item * default_value_item(enum_field_types field_type,
 
345
                          const CHARSET_INFO *charset,
 
346
                          bool default_null, string default_value,
 
347
                          string default_bin_value)
346
348
{
347
349
  Item *default_item= NULL;
348
350
  int error= 0;
367
369
    default_item= new Item_float(default_value.c_str(), default_value.length());
368
370
    break;
369
371
  case DRIZZLE_TYPE_NULL:
 
372
    abort();
 
373
    break;
370
374
  case DRIZZLE_TYPE_TIMESTAMP:
371
375
  case DRIZZLE_TYPE_TIME:
372
376
  case DRIZZLE_TYPE_DATETIME:
373
377
  case DRIZZLE_TYPE_DATE:
374
 
    break;
375
 
  case DRIZZLE_TYPE_VARCHAR:
 
378
    if(default_value.compare("NOW()")==0)
 
379
      break;
 
380
  case DRIZZLE_TYPE_ENUM:
376
381
    default_item= new Item_string(default_value.c_str(),
377
382
                                  default_value.length(),
378
383
                                  system_charset_info);
379
384
    break;
 
385
  case DRIZZLE_TYPE_VARCHAR:
 
386
  case DRIZZLE_TYPE_BLOB: /* Blob is here due to TINYTEXT. Feel the hate. */
 
387
    if(charset==&my_charset_bin)
 
388
    {
 
389
      default_item= new Item_string(default_bin_value.c_str(),
 
390
                                    default_bin_value.length(),
 
391
                                    &my_charset_bin);
 
392
    }
 
393
    else
 
394
    {
 
395
      default_item= new Item_string(default_value.c_str(),
 
396
                                    default_value.length(),
 
397
                                    system_charset_info);
 
398
    }
 
399
    break;
380
400
  case DRIZZLE_TYPE_VIRTUAL:
381
401
    break;
382
402
  case DRIZZLE_TYPE_NEWDECIMAL:
384
404
                                   default_value.length(),
385
405
                                   system_charset_info);
386
406
    break;
387
 
  case DRIZZLE_TYPE_ENUM:
388
 
  case DRIZZLE_TYPE_BLOB:
389
 
    const char* foo= default_value.c_str();
390
 
    foo= NULL;
391
 
    break;
392
407
  }
393
408
 
394
409
  return default_item;
649
664
 
650
665
  assert(field_offsets && field_pack_length); // TODO: fixme
651
666
 
 
667
  uint32_t interval_count= 0;
 
668
  uint32_t interval_parts= 0;
 
669
 
 
670
 
652
671
  for(unsigned int fieldnr=0; fieldnr < share->fields; fieldnr++)
653
672
  {
654
673
    drizzle::Table::Field pfield= table.field(fieldnr);
699
718
 
700
719
        field_pack_length[fieldnr]=
701
720
          get_enum_pack_length(field_options.field_value_size());
 
721
 
 
722
        interval_count++;
 
723
        interval_parts+= field_options.field_value_size();
702
724
      }
703
725
      break;
704
726
    case DRIZZLE_TYPE_NEWDECIMAL:
751
773
                                     rec_buff_length)))
752
774
    abort();
753
775
 
 
776
  memset(record, 0, rec_buff_length);
 
777
 
 
778
  int null_count= 0;
 
779
 
 
780
  if(!table_options.pack_record())
 
781
  {
 
782
    null_count++; // one bit for delete mark.
 
783
    *record|= 1;
 
784
  }
 
785
 
754
786
  share->default_values= record;
755
 
 
 
787
  share->stored_rec_length= share->reclength;
 
788
 
 
789
  if(interval_count)
 
790
  {
 
791
    share->intervals= (TYPELIB*)alloc_root(&share->mem_root,
 
792
                                           interval_count*sizeof(TYPELIB));
 
793
  }
 
794
  else
 
795
    share->intervals= NULL;
 
796
 
 
797
  /* Now fix the TYPELIBs for the intervals (enum values) */
 
798
 
 
799
  uint32_t interval_nr= 0;
 
800
 
 
801
  for(unsigned int fieldnr=0; fieldnr < share->fields; fieldnr++)
 
802
  {
 
803
    drizzle::Table::Field pfield= table.field(fieldnr);
 
804
 
 
805
    if(pfield.type() != drizzle::Table::Field::ENUM)
 
806
      continue;
 
807
 
 
808
    drizzle::Table::Field::SetFieldOptions field_options=
 
809
      pfield.set_options();
 
810
 
 
811
    TYPELIB *t= &(share->intervals[interval_nr]);
 
812
 
 
813
    t->type_names= (const char**)alloc_root(&share->mem_root,
 
814
                           (field_options.field_value_size()+1)*sizeof(char*));
 
815
 
 
816
    t->type_lengths= (unsigned int*) alloc_root(&share->mem_root,
 
817
                     (field_options.field_value_size()+1)*sizeof(unsigned int));
 
818
 
 
819
    t->type_names[field_options.field_value_size()]= NULL;
 
820
    t->type_lengths[field_options.field_value_size()]= 0;
 
821
 
 
822
    t->count= field_options.field_value_size();
 
823
    t->name= NULL;
 
824
 
 
825
    for(int n=0; n < field_options.field_value_size(); n++)
 
826
    {
 
827
      t->type_names[n]= strmake_root(&share->mem_root,
 
828
                                     field_options.field_value(n).c_str(),
 
829
                                     field_options.field_value(n).length());
 
830
 
 
831
      t->type_lengths[n]= field_options.field_value(n).length();
 
832
    }
 
833
    interval_nr++;
 
834
  }
 
835
 
 
836
 
 
837
  /* and read the fields */
756
838
  ulong recordpos= 0;
757
839
 
758
 
  int null_count= 0;
 
840
  interval_nr= 0;
759
841
 
760
842
  for(unsigned int fieldnr=0; fieldnr < share->fields; fieldnr++)
761
843
  {
849
931
      share->vfields++;
850
932
    }
851
933
 
852
 
 
853
934
    const CHARSET_INFO *charset= &my_charset_bin;
854
935
 
855
936
    if(field_type==DRIZZLE_TYPE_BLOB
869
950
    Item *default_value= NULL;
870
951
 
871
952
    if(pfield.options().has_default_value()
872
 
       || pfield.options().has_default_null())
 
953
       || pfield.options().has_default_null()
 
954
       || pfield.options().has_default_bin_value())
873
955
    {
874
956
      default_value= default_value_item(field_type,
 
957
                                        charset,
875
958
                                        pfield.options().default_null(),
876
 
                                        pfield.options().default_value());
 
959
                                        pfield.options().default_value(),
 
960
                                        pfield.options().default_bin_value());
877
961
    }
878
962
 
879
 
    if(pfield.has_constraints() && pfield.constraints().is_nullable())
880
 
      null_count++;
881
 
 
882
963
    uint32_t pack_flag= pfield.pack_flag(); /* TODO: MUST DIE */
883
964
 
884
965
    TABLE_SHARE temp_share;
 
966
    Table temp_table;
885
967
 
886
 
    memset(&temp_share, 0, sizeof(share));
 
968
    memset(&temp_share, 0, sizeof(temp_share));
 
969
    memset(&temp_table, 0, sizeof(temp_table));
 
970
    temp_table.s= &temp_share;
 
971
    temp_table.in_use= session;
 
972
    temp_table.s->db_low_byte_first= 1; //handler->low_byte_first();
 
973
    temp_table.s->blob_ptr_size= portable_sizeof_char_ptr;
887
974
 
888
975
    Field* f= make_field(&temp_share, record+recordpos+data_offset,
889
976
                         pfield.options().length(),
893
980
                         field_type,
894
981
                         charset,
895
982
                         (Field::utype) MTYP_TYPENR(unireg_type),
896
 
//                       (interval_nr ?
897
 
//                        share->intervals+interval_nr-1 :
898
 
                         (                        (TYPELIB*) 0),
 
983
                         ((field_type==DRIZZLE_TYPE_ENUM)?
 
984
                         share->intervals+(interval_nr++)
 
985
                         : (TYPELIB*) 0),
899
986
                         pfield.name().c_str());
900
 
    (void)f;
 
987
 
 
988
    f->init(&temp_table);
 
989
 
 
990
    if(!(f->flags & NOT_NULL_FLAG))
 
991
    {
 
992
      *f->null_ptr|= f->null_bit;
 
993
      null_count++;
 
994
    }
901
995
 
902
996
    if(default_value)
903
997
    {
904
998
      int res= default_value->save_in_field(f, 1);
905
999
      (void)res; // TODO error handle;
906
1000
    }
 
1001
    else if(f->real_type() == DRIZZLE_TYPE_ENUM &&
 
1002
            (f->flags & NOT_NULL_FLAG))
 
1003
    {
 
1004
      f->set_notnull();
 
1005
      f->store((int64_t) 1, true);
 
1006
    }
 
1007
    else
 
1008
      f->reset();
907
1009
 
908
1010
    recordpos+= field_pack_length[fieldnr];
909
1011
  }
910
1012
 
 
1013
  /*
 
1014
    We need to set the unused bits to 1. If the number of bits is a multiple
 
1015
    of 8 there are no unused bits.
 
1016
  */
 
1017
 
 
1018
  if (null_count & 7)
 
1019
    *(record + null_count / 8)|= ~(((unsigned char) 1 << (null_count & 7)) - 1);
 
1020
 
911
1021
  free(field_offsets);
912
1022
  free(field_pack_length);
913
1023
 
1194
1304
  }
1195
1305
 
1196
1306
  assert(share->reclength == uint2korr((head+16)));
1197
 
  share->stored_rec_length= share->reclength;
1198
1307
 
1199
1308
  record_offset= (ulong) (uint2korr(head+6)+
1200
1309
                          ((uint2korr(head+14) == 0xffff ?
1278
1387
  error=4;
1279
1388
  /* head+59 was extra_rec_buf_length */
1280
1389
  rec_buff_length= ALIGN_SIZE(share->reclength + 1);
1281
 
  share->rec_buff_length= rec_buff_length;
 
1390
 
1282
1391
  if (!(record= (unsigned char *) alloc_root(&share->mem_root,
1283
1392
                                     rec_buff_length)))
1284
1393
    goto err;                                   /* purecov: inspected */
1285
 
  share->default_values= record;
 
1394
 
1286
1395
  if (pread(file, record, (size_t) share->reclength, record_offset) == 0)
1287
1396
    goto err;                                   /* purecov: inspected */
1288
1397
 
 
1398
  assert(memcmp(share->default_values, record, share->reclength)==0);
 
1399
 
1289
1400
  lseek(file,pos+288,SEEK_SET);
1290
1401
 
1291
1402
//  share->fields= uint2korr(forminfo+258);
1320
1431
    goto err;                                   /* purecov: inspected */
1321
1432
  strpos= disk_buff+pos;
1322
1433
 
1323
 
  share->intervals= (TYPELIB*) (field_ptr+share->fields+1);
1324
 
  interval_array= (const char **) (share->intervals+interval_count);
 
1434
//  share->intervals= (TYPELIB*) (field_ptr+share->fields+1);
 
1435
  interval_array= (const char **) ((field_ptr+share->fields+1)+interval_count);
1325
1436
  names= (char*) (interval_array+share->fields+interval_parts+keys+3);
1326
 
  if (!interval_count)
1327
 
    share->intervals= 0;                        // For better debugging
 
1437
 
1328
1438
  memcpy(names, strpos+(share->fields*field_pack_length),
1329
1439
         (uint32_t) (n_length+int_length));
1330
1440
  comment_pos= (char *)(disk_buff+read_length-com_length-vcol_screen_length);
1335
1445
  fix_type_pointers(&interval_array, &share->fieldnames, 1, &names);
1336
1446
  if (share->fieldnames.count != share->fields)
1337
1447
    goto err;
1338
 
  fix_type_pointers(&interval_array, share->intervals, interval_count,
1339
 
                    &names);
1340
 
 
1341
 
  {
1342
 
    /* Set ENUM and SET lengths */
1343
 
    TYPELIB *interval;
1344
 
    for (interval= share->intervals;
1345
 
         interval < share->intervals + interval_count;
1346
 
         interval++)
1347
 
    {
1348
 
      uint32_t count= (uint32_t) (interval->count + 1) * sizeof(uint32_t);
1349
 
      if (!(interval->type_lengths= (uint32_t *) alloc_root(&share->mem_root,
1350
 
                                                        count)))
1351
 
        goto err;
1352
 
      for (count= 0; count < interval->count; count++)
1353
 
      {
1354
 
        char *val= (char*) interval->type_names[count];
1355
 
        interval->type_lengths[count]= strlen(val);
1356
 
      }
1357
 
      interval->type_lengths[count]= 0;
1358
 
    }
1359
 
  }
1360
1448
 
1361
1449
/*  if (keynames)
1362
1450
    fix_type_pointers(&interval_array, &share->keynames, 1, &keynames);*/