home *** CD-ROM | disk | FTP | other *** search
/ Chip 2001 January / Chip_2001-01_cd1.bin / tema / mysql / mysql-3.23.28g-win-source.exe / sql / unireg.cpp < prev    next >
C/C++ Source or Header  |  2000-11-17  |  18KB  |  582 lines

  1. /* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
  2.    
  3.    This program is free software; you can redistribute it and/or modify
  4.    it under the terms of the GNU General Public License as published by
  5.    the Free Software Foundation; either version 2 of the License, or
  6.    (at your option) any later version.
  7.    
  8.    This program is distributed in the hope that it will be useful,
  9.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  10.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  11.    GNU General Public License for more details.
  12.    
  13.    You should have received a copy of the GNU General Public License
  14.    along with this program; if not, write to the Free Software
  15.    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
  16.  
  17.  
  18. /*
  19.   Functions to create a unireg form-file from a FIELD and a fieldname-fieldinfo
  20.   struct.
  21.   In the following functions FIELD * is a ordinary field-structure with
  22.   the following exeptions:
  23.     sc_length,typepos,row,kol,dtype,regnr and field nead not to be set.
  24.     str is a (long) to record position where 0 is the first position.
  25. */
  26.  
  27. #define USES_TYPES
  28. #include "mysql_priv.h"
  29. #include <m_ctype.h>
  30.  
  31. #define FCOMP            11        /* Byte per packat f{lt */
  32.  
  33. static uchar * pack_screens(List<create_field> &create_fields,
  34.                 uint *info_length, uint *screens, bool small_file);
  35. static uint pack_keys(uchar *keybuff,uint key_count, KEY *key_info);
  36. static bool pack_header(uchar *forminfo, enum db_type table_type,
  37.             List<create_field> &create_fields,
  38.             uint info_length, uint screens, uint table_options,
  39.             handler *file);
  40. static uint get_interval_id(uint *int_count,List<create_field> &create_fields,
  41.                 create_field *last_field);
  42. static bool pack_fields(File file, List<create_field> &create_fields);
  43. static bool make_empty_rec(int file, enum db_type table_type,
  44.                uint table_options,
  45.                List<create_field> &create_fields,
  46.                uint reclength,uint null_fields);
  47.  
  48.  
  49. int rea_create_table(my_string file_name,
  50.              HA_CREATE_INFO *create_info,
  51.              List<create_field> &create_fields,
  52.              uint keys, KEY *key_info)
  53. {
  54.   uint reclength,info_length,screens,key_info_length,maxlength,null_fields;
  55.   File file;
  56.   ulong filepos;
  57.   uchar fileinfo[64],forminfo[288],*keybuff;
  58.   TYPELIB formnames;
  59.   uchar *screen_buff;
  60.   handler *db_file;
  61.   DBUG_ENTER("rea_create_table");
  62.  
  63.   formnames.type_names=0;
  64.   if (!(screen_buff=pack_screens(create_fields,&info_length,&screens,0)))
  65.     DBUG_RETURN(1);
  66.   db_file=get_new_handler((TABLE*) 0, create_info->db_type);
  67.   if (pack_header(forminfo, create_info->db_type,create_fields,info_length,
  68.           screens, create_info->table_options, db_file))
  69.   {
  70.     NET *net=my_pthread_getspecific_ptr(NET*,THR_NET);
  71.     my_free((gptr) screen_buff,MYF(0));
  72.     if (net->last_errno != ER_TOO_MANY_FIELDS)
  73.       DBUG_RETURN(1);
  74.  
  75.     // Try again without UNIREG screens (to get more columns)
  76.     net->last_error[0]=0;
  77.     if (!(screen_buff=pack_screens(create_fields,&info_length,&screens,1)))
  78.       DBUG_RETURN(1);
  79.     if (pack_header(forminfo, create_info->db_type, create_fields,info_length,
  80.             screens, create_info->table_options, db_file))
  81.     {
  82.       my_free((gptr) screen_buff,MYF(0));
  83.       DBUG_RETURN(1);
  84.     }
  85.   }
  86.   reclength=uint2korr(forminfo+266);
  87.   null_fields=uint2korr(forminfo+282);
  88.  
  89.   if ((file=create_frm(file_name, reclength, fileinfo,
  90.                create_info, keys)) < 0)
  91.   {
  92.     my_free((gptr) screen_buff,MYF(0));
  93.     DBUG_RETURN(1);
  94.   }
  95.  
  96.   uint key_buff_length=uint2korr(fileinfo+14);
  97.   keybuff=(uchar*) my_alloca(key_buff_length);
  98.   key_info_length=pack_keys(keybuff,keys,key_info);
  99.   VOID(get_form_pos(file,fileinfo,&formnames));
  100.   if (!(filepos=make_new_entry(file,fileinfo,&formnames,"")))
  101.     goto err;
  102.   maxlength=(uint) next_io_size((ulong) (uint2korr(forminfo)+1000));
  103.   int2store(forminfo+2,maxlength);
  104.   int4store(fileinfo+10,(ulong) (filepos+maxlength));
  105.   fileinfo[26]= (uchar) test((create_info->max_rows == 1) &&
  106.                  (create_info->min_rows == 1) && (keys == 0));
  107.   int2store(fileinfo+28,key_info_length);
  108.   strnmov((char*) forminfo+47,create_info->comment ? create_info->comment : "",
  109.       60);
  110.   forminfo[46]=(uchar) strlen((char*)forminfo+47);    // Length of comment
  111.  
  112.   if (my_pwrite(file,(byte*) fileinfo,64,0L,MYF_RW) ||
  113.       my_pwrite(file,(byte*) keybuff,key_info_length,
  114.         (ulong) uint2korr(fileinfo+6),MYF_RW))
  115.     goto err;
  116.   VOID(my_seek(file,
  117.            (ulong) uint2korr(fileinfo+6)+ (ulong) key_buff_length,
  118.            MY_SEEK_SET,MYF(0)));
  119.   if (make_empty_rec(file,create_info->db_type,create_info->table_options,
  120.              create_fields,reclength,null_fields))
  121.     goto err;
  122.  
  123.   VOID(my_seek(file,filepos,MY_SEEK_SET,MYF(0)));
  124.   if (my_write(file,(byte*) forminfo,288,MYF_RW) ||
  125.       my_write(file,(byte*) screen_buff,info_length,MYF_RW) ||
  126.       pack_fields(file,create_fields))
  127.     goto err;
  128.  
  129. #ifdef HAVE_CRYPTED_FRM
  130.   if (create_info->password)
  131.   {
  132.     char tmp=2,*disk_buff=0;
  133.     SQL_CRYPT *crypted=new SQL_CRYPT(create_info->password);
  134.     if (!crypted || my_pwrite(file,&tmp,1,26,MYF_RW))    // Mark crypted
  135.       goto err;
  136.     uint read_length=uint2korr(forminfo)-256;
  137.     VOID(my_seek(file,filepos+256,MY_SEEK_SET,MYF(0)));
  138.     if (read_string(file,(gptr*) &disk_buff,read_length))
  139.       goto err;
  140.     crypted->encode(disk_buff,read_length);
  141.     delete crypted;
  142.     if (my_pwrite(file,disk_buff,read_length,filepos+256,MYF_RW))
  143.     {
  144.       my_free(disk_buff,MYF(0));
  145.       goto err;
  146.     }
  147.     my_free(disk_buff,MYF(0));
  148.   }
  149. #endif
  150.  
  151.   my_free((gptr) screen_buff,MYF(0));
  152.   my_afree((gptr) keybuff);
  153.   VOID(my_close(file,MYF(MY_WME)));
  154.   if (ha_create_table(file_name,create_info,0))
  155.     goto err2;
  156.   DBUG_RETURN(0);
  157.  
  158. err:
  159.   my_free((gptr) screen_buff,MYF(0));
  160.   my_afree((gptr) keybuff);
  161.   VOID(my_close(file,MYF(MY_WME)));
  162.  err2:
  163.   my_delete(file_name,MYF(0));
  164.   DBUG_RETURN(1);
  165. } /* rea_create_table */
  166.  
  167.  
  168.     /* Pack screens to a screen for save in a form-file */
  169.  
  170. static uchar * pack_screens(List<create_field> &create_fields,
  171.                 uint *info_length, uint *screens,
  172.                 bool small_file)
  173. {
  174.   reg1 uint i;
  175.   uint row,start_row,end_row,fields_on_screen;
  176.   uint length,cols;
  177.   uchar *info,*pos,*start_screen;
  178.   uint fields=create_fields.elements;
  179.   List_iterator<create_field> it(create_fields);
  180.   DBUG_ENTER("pack_screens");
  181.  
  182.   start_row=4; end_row=22; cols=80; fields_on_screen=end_row+1-start_row;
  183.  
  184.   *screens=(fields-1)/fields_on_screen+1;
  185.   length= (*screens) * (SC_INFO_LENGTH+ (cols>> 1)+4);
  186.  
  187.   create_field *field;
  188.   while ((field=it++))
  189.     length+=(uint) strlen(field->field_name)+1+TE_INFO_LENGTH+cols/2;
  190.  
  191.   if (!(info=(uchar*) my_malloc(length,MYF(MY_WME))))
  192.     DBUG_RETURN(0);
  193.  
  194.   start_screen=0;
  195.   row=end_row;
  196.   pos=info;
  197.   it.rewind();
  198.   for (i=0 ; i < fields ; i++)
  199.   {
  200.     create_field *cfield=it++;
  201.     if (row++ == end_row)
  202.     {
  203.       if (i)
  204.       {
  205.     length=(uint) (pos-start_screen);
  206.     int2store(start_screen,length);
  207.     start_screen[2]=(uchar) (fields_on_screen+1);
  208.     start_screen[3]=(uchar) (fields_on_screen);
  209.       }
  210.       row=start_row;
  211.       start_screen=pos;
  212.       pos+=4;
  213.       pos[0]= (uchar) start_row-2;    /* Header string */
  214.       pos[1]= (uchar) (cols >> 2);
  215.       pos[2]= (uchar) (cols >> 1) +1;
  216.       strfill((my_string) pos+3,(uint) (cols >> 1),' ');
  217.       pos+=(cols >> 1)+4;
  218.     }
  219.     length=(uint) strlen(cfield->field_name);
  220.     if (length > cols-3)
  221.       length=cols-3;
  222.  
  223.     if (!small_file)
  224.     {
  225.       pos[0]=(uchar) row;
  226.       pos[1]=0;
  227.       pos[2]=(uchar) (length+1);
  228.       pos=(uchar*) strmake((char*) pos+3,cfield->field_name,length)+1;
  229.     }
  230.     cfield->row=(uint8) row;
  231.     cfield->col=(uint8) (length+1);
  232.     cfield->sc_length=(uint8) min(cfield->length,cols-(length+2));
  233.   }
  234.   length=(uint) (pos-start_screen);
  235.   int2store(start_screen,length);
  236.   start_screen[2]=(uchar) (row-start_row+2);
  237.   start_screen[3]=(uchar) (row-start_row+1);
  238.  
  239.   *info_length=(uint) (pos-info);
  240.   DBUG_RETURN(info);
  241. } /* pack_screens */
  242.  
  243.  
  244.     /* Pack keyinfo and keynames to keybuff for save in form-file. */
  245.  
  246. static uint pack_keys(uchar *keybuff,uint key_count,KEY *keyinfo)
  247. {
  248.   uint key_parts,length;
  249.   uchar *pos,*keyname_pos;
  250.   KEY *key,*end;
  251.   KEY_PART_INFO *key_part,*key_part_end;
  252.   DBUG_ENTER("pack_keys");
  253.  
  254.   pos=keybuff+6;
  255.   key_parts=0;
  256.   for (key=keyinfo,end=keyinfo+key_count ; key != end ; key++)
  257.   {
  258.     pos[0]=(uchar) (key->flags ^ HA_NOSAME);
  259.     int2store(pos+1,key->key_length);
  260.     pos[3]=key->key_parts;
  261.     pos+=4;
  262.     key_parts+=key->key_parts;
  263.     DBUG_PRINT("loop",("flags: %d  key_parts: %d at %lx",
  264.                key->flags,key->key_parts,
  265.                key->key_part));
  266.     for (key_part=key->key_part,key_part_end=key_part+key->key_parts ;
  267.      key_part != key_part_end ;
  268.      key_part++)
  269.  
  270.     {
  271.       DBUG_PRINT("loop",("field: %d  startpos: %ld  length: %ld",
  272.              key_part->fieldnr,key_part->offset,key_part->length));
  273.       int2store(pos,key_part->fieldnr+1+FIELD_NAME_USED);
  274.       int2store(pos+2,key_part->offset+1);
  275.       pos[4]=0;                    // Sort order
  276.       int2store(pos+5,key_part->key_type);
  277.       int2store(pos+7,key_part->length);
  278.       pos+=9;
  279.     }
  280.   }
  281.     /* Save keynames */
  282.   keyname_pos=pos;
  283.   *pos++=(uchar) NAMES_SEP_CHAR;
  284.   for (key=keyinfo ; key != end ; key++)
  285.   {
  286.     uchar *tmp=(uchar*) strmov((char*) pos,key->name);
  287.     *tmp++= (uchar) NAMES_SEP_CHAR;
  288.     *tmp=0;
  289.     pos=tmp;
  290.   }
  291.   *(pos++)=0;
  292.  
  293.   keybuff[0]=(uchar) key_count;
  294.   keybuff[1]=(uchar) key_parts;
  295.   length=(uint) (keyname_pos-keybuff);
  296.   int2store(keybuff+2,length);
  297.   length=(uint) (pos-keyname_pos);
  298.   int2store(keybuff+4,length);
  299.   DBUG_RETURN((uint) (pos-keybuff));
  300. } /* pack_keys */
  301.  
  302.  
  303.     /* Make formheader */
  304.  
  305. static bool pack_header(uchar *forminfo, enum db_type table_type,
  306.             List<create_field> &create_fields,
  307.             uint info_length, uint screens,uint table_options,
  308.             handler *file)
  309. {
  310.   uint length,int_count,int_length,no_empty, int_parts,
  311.     time_stamp_pos,null_fields;
  312.   ulong reclength,totlength,n_length;
  313.   DBUG_ENTER("pack_header");
  314.  
  315.   if (create_fields.elements > MAX_FIELDS)
  316.   {
  317.     my_error(ER_TOO_MANY_FIELDS,MYF(0));
  318.     DBUG_RETURN(1);
  319.   }
  320.  
  321.   totlength=reclength=0L;
  322.   no_empty=int_count=int_parts=int_length=time_stamp_pos=null_fields=0;
  323.   n_length=2L;
  324.  
  325.     /* Check fields */
  326.  
  327.   List_iterator<create_field> it(create_fields);
  328.   create_field *field;
  329.   while ((field=it++))
  330.   {
  331.     totlength+= field->length;
  332.     if (MTYP_TYPENR(field->unireg_check) == Field::NOEMPTY ||
  333.     field->unireg_check & MTYP_NOEMPTY_BIT)
  334.     {
  335.       field->unireg_check= (Field::utype) ((uint) field->unireg_check |
  336.                        MTYP_NOEMPTY_BIT);
  337.       no_empty++;
  338.     }
  339.     if ((MTYP_TYPENR(field->unireg_check) == Field::TIMESTAMP_FIELD ||
  340.      f_packtype(field->pack_flag) == (int) FIELD_TYPE_TIMESTAMP) &&
  341.     !time_stamp_pos)
  342.       time_stamp_pos=(int) field->offset+1;
  343.     length=field->pack_length;
  344.     if ((int) field->offset+length > reclength)
  345.       reclength=(int) field->offset+length;
  346.     n_length+= (ulong) strlen(field->field_name)+1;
  347.     field->interval_id=0;
  348.     if (field->interval)
  349.     {
  350.       uint old_int_count=int_count;
  351.       field->interval_id=get_interval_id(&int_count,create_fields,field);
  352.       if (old_int_count != int_count)
  353.       {
  354.     for (const char **pos=field->interval->type_names ; *pos ; pos++)
  355.       int_length+=(uint) strlen(*pos)+1;    // field + suffix prefix
  356.     int_parts+=field->interval->count+1;
  357.       }
  358.     }
  359.     if (f_maybe_null(field->pack_flag))
  360.       null_fields++;
  361.   }
  362.   int_length+=int_count*2;            // 255 prefix + 0 suffix
  363.  
  364.     /* Save values in forminfo */
  365.  
  366.   if (reclength > (ulong) file->max_record_length())
  367.   {
  368.     my_error(ER_TOO_BIG_ROWSIZE, MYF(0), (uint) file->max_record_length());
  369.     DBUG_RETURN(1);
  370.   }
  371.   /* Hack to avoid bugs with small static rows in MySQL */
  372.   reclength=max(file->min_record_length(table_options),reclength);
  373.   if (info_length+(ulong) create_fields.elements*FCOMP+288+
  374.       n_length+int_length > 65535L || int_count > 255)
  375.   {
  376.     my_error(ER_TOO_MANY_FIELDS,MYF(0));
  377.     DBUG_RETURN(1);
  378.   }
  379.  
  380.   bzero((char*)forminfo,288);
  381.   length=info_length+create_fields.elements*FCOMP+288+n_length+int_length;
  382.   int2store(forminfo,length);
  383.   forminfo[256] = (uint8) screens;
  384.   int2store(forminfo+258,create_fields.elements);
  385.   int2store(forminfo+260,info_length);
  386.   int2store(forminfo+262,totlength);
  387.   int2store(forminfo+264,no_empty);
  388.   int2store(forminfo+266,reclength);
  389.   int2store(forminfo+268,n_length);
  390.   int2store(forminfo+270,int_count);
  391.   int2store(forminfo+272,int_parts);
  392.   int2store(forminfo+274,int_length);
  393.   int2store(forminfo+276,time_stamp_pos);
  394.   int2store(forminfo+278,80);            /* Columns neaded */
  395.   int2store(forminfo+280,22);            /* Rows neaded */
  396.   int2store(forminfo+282,null_fields);
  397.   DBUG_RETURN(0);
  398. } /* pack_header */
  399.  
  400.  
  401.     /* get each unique interval each own id */
  402.  
  403. static uint get_interval_id(uint *int_count,List<create_field> &create_fields,
  404.                 create_field *last_field)
  405. {
  406.   List_iterator<create_field> it(create_fields);
  407.   create_field *field;
  408.   TYPELIB *interval=last_field->interval;
  409.  
  410.   while ((field=it++) != last_field)
  411.   {
  412.     if (field->interval_id && field->interval->count == interval->count)
  413.     {
  414.       const char **a,**b;
  415.       for (a=field->interval->type_names, b=interval->type_names ;
  416.        *a && !strcmp(*a,*b);
  417.        a++,b++) ;
  418.  
  419.       if (! *a)
  420.       {
  421.     return field->interval_id;        // Re-use last interval
  422.       }
  423.     }
  424.   }
  425.   return ++*int_count;                // New unique interval
  426. }
  427.  
  428.  
  429.     /* Save fields, fieldnames and intervals */
  430.  
  431. static bool pack_fields(File file,List<create_field> &create_fields)
  432. {
  433.   reg2 uint i;
  434.   uint int_count;
  435.   uchar buff[MAX_FIELD_WIDTH];
  436.   create_field *field;
  437.   DBUG_ENTER("pack_fields");
  438.  
  439.     /* Write field info */
  440.  
  441.   List_iterator<create_field> it(create_fields);
  442.  
  443.   int_count=0;
  444.   while ((field=it++))
  445.   {
  446.     buff[0]= (uchar) field->row;
  447.     buff[1]= (uchar) field->col;
  448.     buff[2]= (uchar) field->sc_length;
  449.     buff[3]= (uchar) field->length;
  450.     uint recpos=(uint) field->offset+1;
  451.     int2store(buff+4,recpos);
  452.     int2store(buff+6,field->pack_flag);
  453.     int2store(buff+8,field->unireg_check);
  454.     buff[10]= (uchar) field->interval_id;
  455.     set_if_bigger(int_count,field->interval_id);
  456.     if (my_write(file,(byte*) buff,FCOMP,MYF_RW))
  457.       DBUG_RETURN(1);
  458.   }
  459.  
  460.     /* Write fieldnames */
  461.   buff[0]=(uchar) NAMES_SEP_CHAR;
  462.   if (my_write(file,(byte*) buff,1,MYF_RW))
  463.     DBUG_RETURN(1);
  464.   i=0;
  465.   it.rewind();
  466.   while ((field=it++))
  467.   {
  468.     char *pos= strmov((char*) buff,field->field_name);
  469.     *pos++=NAMES_SEP_CHAR;
  470.     if (i == create_fields.elements-1)
  471.       *pos++=0;
  472.     if (my_write(file,(byte*) buff,(uint) (pos-(char*) buff),MYF_RW))
  473.       DBUG_RETURN(1);
  474.     i++;
  475.   }
  476.  
  477.     /* Write intervals */
  478.   if (int_count)
  479.   {
  480.     String tmp((char*) buff,sizeof(buff));
  481.     tmp.length(0);
  482.     it.rewind();
  483.     int_count=0;
  484.     while ((field=it++))
  485.     {
  486.       if (field->interval_id > int_count)
  487.       {
  488.     int_count=field->interval_id;
  489.     tmp.append('\377');
  490.     for (const char **pos=field->interval->type_names ; *pos ; pos++)
  491.     {
  492.       tmp.append(*pos);
  493.       tmp.append('\377');
  494.     }
  495.     tmp.append('\0');            // End of intervall
  496.       }
  497.     }
  498.     if (my_write(file,(byte*) tmp.ptr(),tmp.length(),MYF_RW))
  499.       DBUG_RETURN(1);
  500.   }
  501.   DBUG_RETURN(0);
  502. }
  503.  
  504.  
  505.     /* save a empty record on start of formfile */
  506.  
  507. static bool make_empty_rec(File file,enum db_type table_type,
  508.                uint table_options,
  509.                List<create_field> &create_fields,
  510.                uint reclength, uint null_fields)
  511. {
  512.   int error;
  513.   Field::utype type;
  514.   uint firstpos,null_count,null_length;
  515.   uchar *buff,*null_pos;
  516.   TABLE table;
  517.   create_field *field;
  518.   DBUG_ENTER("make_empty_rec");
  519.  
  520.   /* We need a table to generate columns for default values */
  521.   bzero((char*) &table,sizeof(table));
  522.   table.db_low_byte_first=test(table_type == DB_TYPE_MYISAM ||
  523.                    table_type == DB_TYPE_HEAP);
  524.   table.blob_ptr_size=portable_sizeof_char_ptr;
  525.  
  526.   if (!(buff=(uchar*) my_malloc((uint) reclength,MYF(MY_WME | MY_ZEROFILL))))
  527.     DBUG_RETURN(1);
  528.   firstpos=reclength;
  529.   null_count=0;
  530.   if (!(table_options & HA_OPTION_PACK_RECORD))
  531.   {
  532.     null_fields++;                // Need one bit for delete mark
  533.     null_count++;
  534.   }
  535.   bfill(buff,(null_length=(null_fields+7)/8),255);
  536.   null_pos=buff;
  537.  
  538.   List_iterator<create_field> it(create_fields);
  539.   while ((field=it++))
  540.   {
  541.     Field *regfield=make_field((char*) buff+field->offset,field->length,
  542.                    field->flags & NOT_NULL_FLAG ? 0:
  543.                    null_pos+null_count/8,
  544.                    1 << (null_count & 7),
  545.                    field->pack_flag,
  546.                    field->unireg_check,
  547.                    field->interval,
  548.                    field->field_name,
  549.                    &table);
  550.     if (!(field->flags & NOT_NULL_FLAG))
  551.       null_count++;
  552.  
  553.     if ((uint) field->offset < firstpos &&
  554.     regfield->type() != FIELD_TYPE_NULL)
  555.       firstpos= field->offset;
  556.  
  557.     type= (Field::utype) MTYP_TYPENR(field->unireg_check);
  558.  
  559.     if (field->def &&
  560.     (regfield->real_type() != FIELD_TYPE_YEAR ||
  561.      field->def->val_int() != 0))
  562.       field->def->save_in_field(regfield);
  563.     else if (regfield->real_type() == FIELD_TYPE_ENUM &&
  564.          (field->flags & NOT_NULL_FLAG))
  565.     {
  566.       regfield->set_notnull();
  567.       regfield->store((longlong) 1);
  568.     }
  569.     else if (type == Field::YES)        // Old unireg type
  570.       regfield->store(ER(ER_YES),(uint) strlen(ER(ER_YES)));
  571.     else if (type == Field::NO)            // Old unireg type
  572.       regfield->store(ER(ER_NO), (uint) strlen(ER(ER_NO)));
  573.     else
  574.       regfield->reset();
  575.     delete regfield;
  576.   }
  577.   bfill((byte*) buff+null_length,firstpos-null_length,255);/* Fill not used startpos */
  578.   error=(int) my_write(file,(byte*) buff,(uint) reclength,MYF_RW);
  579.   my_free((gptr) buff,MYF(MY_FAE));
  580.   DBUG_RETURN(error);
  581. } /* make_empty_rec */
  582.