~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/unireg.cc

  • Committer: Monty Taylor
  • Date: 2008-10-16 06:32:30 UTC
  • mto: (511.1.5 codestyle)
  • mto: This revision was merged to the branch mainline in revision 521.
  • Revision ID: monty@inaugust.com-20081016063230-4brxsra0qsmsg84q
Added -Wunused-macros.

Show diffs side-by-side

added added

removed removed

Lines of Context:
23
23
    str is a (long) to record position where 0 is the first position.
24
24
*/
25
25
 
26
 
#include "mysql_priv.h"
27
 
#include <m_ctype.h>
28
 
#include <assert.h>
 
26
#include <drizzled/server_includes.h>
 
27
#include <drizzled/drizzled_error_messages.h>
29
28
 
30
29
#define FCOMP                   17              /* Bytes for a packed field */
31
30
 
32
 
static uchar * pack_screens(List<Create_field> &create_fields,
33
 
                            uint *info_length, uint *screens, bool small_file);
34
 
static uint pack_keys(uchar *keybuff,uint key_count, KEY *key_info,
 
31
static unsigned char * pack_screens(List<Create_field> &create_fields,
 
32
                            uint32_t *info_length, uint32_t *screens, bool small_file);
 
33
static uint32_t pack_keys(unsigned char *keybuff,uint32_t key_count, KEY *key_info,
35
34
                      ulong data_offset);
36
 
static bool pack_header(uchar *forminfo,enum legacy_db_type table_type,
 
35
static bool pack_header(unsigned char *forminfo,
37
36
                        List<Create_field> &create_fields,
38
 
                        uint info_length, uint screens, uint table_options,
 
37
                        uint32_t info_length, uint32_t screens, uint32_t table_options,
39
38
                        ulong data_offset, handler *file);
40
 
static uint get_interval_id(uint *int_count,List<Create_field> &create_fields,
 
39
static uint32_t get_interval_id(uint32_t *int_count,List<Create_field> &create_fields,
41
40
                            Create_field *last_field);
42
41
static bool pack_fields(File file, List<Create_field> &create_fields,
43
42
                        ulong data_offset);
44
43
static bool make_empty_rec(THD *thd, int file, enum legacy_db_type table_type,
45
 
                           uint table_options,
 
44
                           uint32_t table_options,
46
45
                           List<Create_field> &create_fields,
47
 
                           uint reclength, ulong data_offset,
 
46
                           uint32_t reclength, ulong data_offset,
48
47
                           handler *handler);
49
48
 
50
49
/**
56
55
 
57
56
struct Pack_header_error_handler: public Internal_error_handler
58
57
{
59
 
  virtual bool handle_error(uint sql_errno,
 
58
  virtual bool handle_error(uint32_t sql_errno,
60
59
                            const char *message,
61
 
                            MYSQL_ERROR::enum_warning_level level,
 
60
                            DRIZZLE_ERROR::enum_warning_level level,
62
61
                            THD *thd);
63
62
  bool is_handled;
64
63
  Pack_header_error_handler() :is_handled(false) {}
67
66
 
68
67
bool
69
68
Pack_header_error_handler::
70
 
handle_error(uint sql_errno,
 
69
handle_error(uint32_t sql_errno,
71
70
             const char * /* message */,
72
 
             MYSQL_ERROR::enum_warning_level /* level */,
 
71
             DRIZZLE_ERROR::enum_warning_level /* level */,
73
72
             THD * /* thd */)
74
73
{
75
74
  is_handled= (sql_errno == ER_TOO_MANY_FIELDS);
100
99
                      const char *db, const char *table,
101
100
                      HA_CREATE_INFO *create_info,
102
101
                      List<Create_field> &create_fields,
103
 
                      uint keys, KEY *key_info,
 
102
                      uint32_t keys, KEY *key_info,
104
103
                      handler *db_file)
105
104
{
106
105
  LEX_STRING str_db_type;
107
 
  uint reclength, info_length, screens, key_info_length, maxlength, tmp_len;
 
106
  uint32_t reclength, info_length, screens, key_info_length, maxlength, tmp_len;
108
107
  ulong key_buff_length;
109
108
  File file;
110
109
  ulong filepos, data_offset;
111
 
  uchar fileinfo[64],forminfo[288],*keybuff;
 
110
  unsigned char fileinfo[64],forminfo[288],*keybuff;
112
111
  TYPELIB formnames;
113
 
  uchar *screen_buff;
 
112
  unsigned char *screen_buff;
114
113
  char buff[128];
115
 
  const uint format_section_header_size= 8;
116
 
  uint format_section_len;
 
114
  const uint32_t format_section_header_size= 8;
 
115
  uint32_t format_section_len;
117
116
  Pack_header_error_handler pack_header_error_handler;
118
117
  int error;
119
118
 
130
129
 
131
130
  thd->push_internal_handler(&pack_header_error_handler);
132
131
 
133
 
  error= pack_header(forminfo, ha_legacy_type(create_info->db_type),
 
132
  error= pack_header(forminfo,
134
133
                     create_fields,info_length,
135
134
                     screens, create_info->table_options,
136
135
                     data_offset, db_file);
139
138
 
140
139
  if (error)
141
140
  {
142
 
    my_free(screen_buff, MYF(0));
 
141
    free(screen_buff);
143
142
    if (! pack_header_error_handler.is_handled)
144
143
      return(1);
145
144
 
146
145
    // Try again without UNIREG screens (to get more columns)
147
146
    if (!(screen_buff=pack_screens(create_fields,&info_length,&screens,1)))
148
147
      return(1);
149
 
    if (pack_header(forminfo, ha_legacy_type(create_info->db_type),
 
148
    if (pack_header(forminfo,
150
149
                    create_fields,info_length,
151
150
                    screens, create_info->table_options, data_offset, db_file))
152
151
    {
153
 
      my_free(screen_buff, MYF(0));
 
152
      free(screen_buff);
154
153
      return(1);
155
154
    }
156
155
  }
185
184
  if (tmp_len < create_info->comment.length)
186
185
  {
187
186
    my_error(ER_WRONG_STRING_LENGTH, MYF(0),
188
 
             create_info->comment.str,"TABLE COMMENT",
 
187
             create_info->comment.str,"Table COMMENT",
189
188
             (uint) TABLE_COMMENT_MAXLEN);
190
 
    my_free(screen_buff,MYF(0));
 
189
    free(screen_buff);
191
190
    return(1);
192
191
  }
193
192
 
200
199
  else{
201
200
    strmake((char*) forminfo+47, create_info->comment.str ?
202
201
            create_info->comment.str : "", create_info->comment.length);
203
 
    forminfo[46]=(uchar) create_info->comment.length;
 
202
    forminfo[46]=(unsigned char) create_info->comment.length;
204
203
#ifdef EXTRA_DEBUG
205
204
    /*
206
205
      EXTRA_DEBUG causes strmake() to initialize its buffer behind the
207
206
      payload with a magic value to detect wrong buffer-sizes. We
208
207
      explicitly zero that segment again.
209
208
    */
210
 
    memset((char*) forminfo+47 + forminfo[46], 0, 61 - forminfo[46]);
 
209
    memset(forminfo+47 + forminfo[46], 0, 61 - forminfo[46]);
211
210
#endif
212
211
  }
213
212
 
214
213
  if ((file=create_frm(thd, file_name, db, table, reclength, fileinfo,
215
214
                       create_info, keys, key_info)) < 0)
216
215
  {
217
 
    my_free(screen_buff, MYF(0));
 
216
    free(screen_buff);
218
217
    return(1);
219
218
  }
220
219
 
221
220
  key_buff_length= uint4korr(fileinfo+47);
222
 
  keybuff=(uchar*) my_malloc(key_buff_length, MYF(0));
 
221
  keybuff=(unsigned char*) my_malloc(key_buff_length, MYF(0));
223
222
  key_info_length= pack_keys(keybuff, keys, key_info, data_offset);
224
 
  VOID(get_form_pos(file,fileinfo,&formnames));
 
223
  get_form_pos(file,fileinfo,&formnames);
225
224
  if (!(filepos=make_new_entry(file,fileinfo,&formnames,"")))
226
225
    goto err;
227
226
  maxlength=(uint) next_io_size((ulong) (uint2korr(forminfo)+1000));
228
227
  int2store(forminfo+2,maxlength);
229
228
  int4store(fileinfo+10,(ulong) (filepos+maxlength));
230
 
  fileinfo[26]= (uchar) test((create_info->max_rows == 1) &&
 
229
  fileinfo[26]= (unsigned char) test((create_info->max_rows == 1) &&
231
230
                             (create_info->min_rows == 1) && (keys == 0));
232
231
  int2store(fileinfo+28,key_info_length);
233
232
 
237
236
  if (pwrite(file, fileinfo, 64, 0L) == 0 ||
238
237
      pwrite(file, keybuff, key_info_length, (ulong) uint2korr(fileinfo+6)) == 0)
239
238
    goto err;
240
 
  VOID(my_seek(file,
 
239
  my_seek(file,
241
240
               (ulong) uint2korr(fileinfo+6)+ (ulong) key_buff_length,
242
 
               MY_SEEK_SET,MYF(0)));
 
241
               MY_SEEK_SET,MYF(0));
243
242
  if (make_empty_rec(thd,file,ha_legacy_type(create_info->db_type),
244
243
                     create_info->table_options,
245
244
                     create_fields,reclength, data_offset, db_file))
246
245
    goto err;
247
246
 
248
247
  int2store(buff, create_info->connect_string.length);
249
 
  if (my_write(file, (const uchar*)buff, 2, MYF(MY_NABP)) ||
250
 
      my_write(file, (const uchar*)create_info->connect_string.str,
 
248
  if (my_write(file, (const unsigned char*)buff, 2, MYF(MY_NABP)) ||
 
249
      my_write(file, (const unsigned char*)create_info->connect_string.str,
251
250
               create_info->connect_string.length, MYF(MY_NABP)))
252
251
      goto err;
253
252
 
254
253
  int2store(buff, str_db_type.length);
255
 
  if (my_write(file, (const uchar*)buff, 2, MYF(MY_NABP)) ||
256
 
      my_write(file, (const uchar*)str_db_type.str,
 
254
  if (my_write(file, (const unsigned char*)buff, 2, MYF(MY_NABP)) ||
 
255
      my_write(file, (const unsigned char*)str_db_type.str,
257
256
               str_db_type.length, MYF(MY_NABP)))
258
257
    goto err;
259
258
 
260
259
  {
261
 
    bzero((uchar*) buff, 6);
262
 
    if (my_write(file, (uchar*) buff, 6, MYF_RW))
 
260
    memset(buff, 0, 6);
 
261
    if (my_write(file, (unsigned char*) buff, 6, MYF_RW))
263
262
      goto err;
264
263
  }
265
264
 
266
 
  if (forminfo[46] == (uchar)255)
 
265
  if (forminfo[46] == (unsigned char)255)
267
266
  {
268
 
    uchar comment_length_buff[2];
 
267
    unsigned char comment_length_buff[2];
269
268
    int2store(comment_length_buff,create_info->comment.length);
270
269
    if (my_write(file, comment_length_buff, 2, MYF(MY_NABP)) ||
271
 
        my_write(file, (uchar*)create_info->comment.str,
 
270
        my_write(file, (unsigned char*)create_info->comment.str,
272
271
                  create_info->comment.length, MYF(MY_NABP)))
273
272
      goto err;
274
273
  }
277
276
  {
278
277
    /* prepare header */
279
278
    {
280
 
      uint flags= 0;
 
279
      uint32_t flags= 0;
281
280
 
282
 
      bzero(buff, format_section_header_size);
 
281
      memset(buff, 0, format_section_header_size);
283
282
      /* length of section 2 bytes*/
284
283
      int2store(buff+0, format_section_len);
285
284
      /* flags of section 4 bytes*/
287
286
      /* 2 bytes left for future use */
288
287
    }
289
288
    /* write header */
290
 
    if (my_write(file, (const uchar*)buff, format_section_header_size, MYF_RW))
 
289
    if (my_write(file, (const unsigned char*)buff, format_section_header_size, MYF_RW))
291
290
      goto err;
292
291
    buff[0]= 0;
293
 
    if (my_write(file, (const uchar*)buff, 1, MYF_RW))
 
292
    if (my_write(file, (const unsigned char*)buff, 1, MYF_RW))
294
293
      goto err;
295
294
    /* write column info, 1 byte per column */
296
295
    {
297
296
      List_iterator<Create_field> it(create_fields);
298
297
      Create_field *field;
299
 
      uchar column_format, write_byte;
 
298
      unsigned char column_format, write_byte;
300
299
      while ((field=it++))
301
300
      {
302
 
        column_format= (uchar)field->column_format();
 
301
        column_format= (unsigned char)field->column_format();
303
302
        write_byte= (column_format << COLUMN_FORMAT_SHIFT);
304
303
        if (my_write(file, &write_byte, 1, MYF_RW))
305
304
          goto err;
306
305
      }
307
306
    }
308
307
  }
309
 
  VOID(my_seek(file,filepos,MY_SEEK_SET,MYF(0)));
 
308
  my_seek(file,filepos,MY_SEEK_SET,MYF(0));
310
309
  if (my_write(file, forminfo, 288, MYF_RW) ||
311
310
      my_write(file, screen_buff, info_length, MYF_RW) ||
312
311
      pack_fields(file, create_fields, data_offset))
313
312
    goto err;
314
313
 
315
 
  my_free(screen_buff,MYF(0));
316
 
  my_free(keybuff, MYF(0));
 
314
  free(screen_buff);
 
315
  free(keybuff);
317
316
 
318
 
  if (opt_sync_frm && !(create_info->options & HA_LEX_CREATE_TMP_TABLE) &&
 
317
  if (!(create_info->options & HA_LEX_CREATE_TMP_TABLE) &&
319
318
      (my_sync(file, MYF(MY_WME)) ||
320
319
       my_sync_dir_by_file(file_name, MYF(MY_WME))))
321
320
      goto err2;
342
341
  return(0);
343
342
 
344
343
err:
345
 
  my_free(screen_buff, MYF(0));
346
 
  my_free(keybuff, MYF(0));
 
344
  free(screen_buff);
 
345
  free(keybuff);
347
346
err2:
348
 
  VOID(my_close(file,MYF(MY_WME)));
 
347
  my_close(file,MYF(MY_WME));
349
348
err3:
350
349
  my_delete(file_name,MYF(0));
351
350
  return(1);
376
375
                     const char *db, const char *table_name,
377
376
                     HA_CREATE_INFO *create_info,
378
377
                     List<Create_field> &create_fields,
379
 
                     uint keys, KEY *key_info, handler *file)
 
378
                     uint32_t keys, KEY *key_info, handler *file)
380
379
{
381
380
  
382
381
 
383
382
  char frm_name[FN_REFLEN];
384
 
  strxmov(frm_name, path, reg_ext, NullS);
 
383
  strxmov(frm_name, path, reg_ext, NULL);
385
384
  if (mysql_create_frm(thd, frm_name, db, table_name, create_info,
386
385
                       create_fields, keys, key_info, file))
387
386
 
399
398
  return(0);
400
399
 
401
400
err_handler:
402
 
  VOID(file->ha_create_handler_files(path, NULL, CHF_DELETE_FLAG, create_info));
 
401
  file->ha_create_handler_files(path, NULL, CHF_DELETE_FLAG, create_info);
403
402
  my_delete(frm_name, MYF(0));
404
403
  return(1);
405
404
} /* rea_create_table */
407
406
 
408
407
        /* Pack screens to a screen for save in a form-file */
409
408
 
410
 
static uchar *pack_screens(List<Create_field> &create_fields,
411
 
                           uint *info_length, uint *screens,
 
409
static unsigned char *pack_screens(List<Create_field> &create_fields,
 
410
                           uint32_t *info_length, uint32_t *screens,
412
411
                           bool small_file)
413
412
{
414
 
  register uint i;
415
 
  uint row,start_row,end_row,fields_on_screen;
416
 
  uint length,cols;
417
 
  uchar *info,*pos,*start_screen;
418
 
  uint fields=create_fields.elements;
 
413
  register uint32_t i;
 
414
  uint32_t row,start_row,end_row,fields_on_screen;
 
415
  uint32_t length,cols;
 
416
  unsigned char *info,*pos,*start_screen;
 
417
  uint32_t fields=create_fields.elements;
419
418
  List_iterator<Create_field> it(create_fields);
420
419
  
421
420
 
428
427
  while ((field=it++))
429
428
    length+=(uint) strlen(field->field_name)+1+TE_INFO_LENGTH+cols/2;
430
429
 
431
 
  if (!(info=(uchar*) my_malloc(length,MYF(MY_WME))))
 
430
  if (!(info=(unsigned char*) my_malloc(length,MYF(MY_WME))))
432
431
    return(0);
433
432
 
434
433
  start_screen=0;
444
443
      {
445
444
        length=(uint) (pos-start_screen);
446
445
        int2store(start_screen,length);
447
 
        start_screen[2]=(uchar) (fields_on_screen+1);
448
 
        start_screen[3]=(uchar) (fields_on_screen);
 
446
        start_screen[2]=(unsigned char) (fields_on_screen+1);
 
447
        start_screen[3]=(unsigned char) (fields_on_screen);
449
448
      }
450
449
      row=start_row;
451
450
      start_screen=pos;
452
451
      pos+=4;
453
 
      pos[0]= (uchar) start_row-2;      /* Header string */
454
 
      pos[1]= (uchar) (cols >> 2);
455
 
      pos[2]= (uchar) (cols >> 1) +1;
 
452
      pos[0]= (unsigned char) start_row-2;      /* Header string */
 
453
      pos[1]= (unsigned char) (cols >> 2);
 
454
      pos[2]= (unsigned char) (cols >> 1) +1;
456
455
      strfill((char *) pos+3,(uint) (cols >> 1),' ');
457
456
      pos+=(cols >> 1)+4;
458
457
    }
462
461
 
463
462
    if (!small_file)
464
463
    {
465
 
      pos[0]=(uchar) row;
 
464
      pos[0]=(unsigned char) row;
466
465
      pos[1]=0;
467
 
      pos[2]=(uchar) (length+1);
468
 
      pos=(uchar*) strmake((char*) pos+3,cfield->field_name,length)+1;
 
466
      pos[2]=(unsigned char) (length+1);
 
467
      pos=(unsigned char*) strmake((char*) pos+3,cfield->field_name,length)+1;
469
468
    }
470
 
    cfield->row=(uint8) row;
471
 
    cfield->col=(uint8) (length+1);
472
 
    cfield->sc_length=(uint8) min(cfield->length,cols-(length+2));
 
469
    cfield->row=(uint8_t) row;
 
470
    cfield->col=(uint8_t) (length+1);
 
471
    cfield->sc_length=(uint8_t) cmin(cfield->length,(uint32_t)cols-(length+2));
473
472
  }
474
473
  length=(uint) (pos-start_screen);
475
474
  int2store(start_screen,length);
476
 
  start_screen[2]=(uchar) (row-start_row+2);
477
 
  start_screen[3]=(uchar) (row-start_row+1);
 
475
  start_screen[2]=(unsigned char) (row-start_row+2);
 
476
  start_screen[3]=(unsigned char) (row-start_row+1);
478
477
 
479
478
  *info_length=(uint) (pos-info);
480
479
  return(info);
483
482
 
484
483
        /* Pack keyinfo and keynames to keybuff for save in form-file. */
485
484
 
486
 
static uint pack_keys(uchar *keybuff, uint key_count, KEY *keyinfo,
 
485
static uint32_t pack_keys(unsigned char *keybuff, uint32_t key_count, KEY *keyinfo,
487
486
                      ulong data_offset)
488
487
{
489
 
  uint key_parts,length;
490
 
  uchar *pos, *keyname_pos;
 
488
  uint32_t key_parts,length;
 
489
  unsigned char *pos, *keyname_pos;
491
490
  KEY *key,*end;
492
491
  KEY_PART_INFO *key_part,*key_part_end;
493
492
  
498
497
  {
499
498
    int2store(pos, (key->flags ^ HA_NOSAME));
500
499
    int2store(pos+2,key->key_length);
501
 
    pos[4]= (uchar) key->key_parts;
502
 
    pos[5]= (uchar) key->algorithm;
 
500
    pos[4]= (unsigned char) key->key_parts;
 
501
    pos[5]= (unsigned char) key->algorithm;
503
502
    int2store(pos+6, key->block_size);
504
503
    pos+=8;
505
504
    key_parts+=key->key_parts;
508
507
         key_part++)
509
508
 
510
509
    {
511
 
      uint offset;
 
510
      uint32_t offset;
512
511
      int2store(pos,key_part->fieldnr+1+FIELD_NAME_USED);
513
512
      offset= (uint) (key_part->offset+data_offset+1);
514
513
      int2store(pos+2, offset);
520
519
  }
521
520
        /* Save keynames */
522
521
  keyname_pos=pos;
523
 
  *pos++=(uchar) NAMES_SEP_CHAR;
 
522
  *pos++=(unsigned char) NAMES_SEP_CHAR;
524
523
  for (key=keyinfo ; key != end ; key++)
525
524
  {
526
 
    uchar *tmp=(uchar*) strmov((char*) pos,key->name);
527
 
    *tmp++= (uchar) NAMES_SEP_CHAR;
 
525
    unsigned char *tmp=(unsigned char*) my_stpcpy((char*) pos,key->name);
 
526
    *tmp++= (unsigned char) NAMES_SEP_CHAR;
528
527
    *tmp=0;
529
528
    pos=tmp;
530
529
  }
535
534
    if (key->flags & HA_USES_COMMENT)
536
535
    {
537
536
      int2store(pos, key->comment.length);
538
 
      uchar *tmp= (uchar*)strnmov((char*) pos+2,key->comment.str,key->comment.length);
 
537
      unsigned char *tmp= (unsigned char*)my_stpncpy((char*) pos+2,key->comment.str,key->comment.length);
539
538
      pos= tmp;
540
539
    }
541
540
  }
548
547
  }
549
548
  else
550
549
  {
551
 
    keybuff[0]=(uchar) key_count;
552
 
    keybuff[1]=(uchar) key_parts;
 
550
    keybuff[0]=(unsigned char) key_count;
 
551
    keybuff[1]=(unsigned char) key_parts;
553
552
    keybuff[2]= keybuff[3]= 0;
554
553
  }
555
554
  length=(uint) (pos-keyname_pos);
560
559
 
561
560
/* Make formheader */
562
561
 
563
 
static bool pack_header(uchar *forminfo,
564
 
                        enum legacy_db_type table_type __attribute__((__unused__)),
 
562
static bool pack_header(unsigned char *forminfo,
565
563
                        List<Create_field> &create_fields,
566
 
                        uint info_length, uint screens, uint table_options,
 
564
                        uint32_t info_length, uint32_t screens, uint32_t table_options,
567
565
                        ulong data_offset, handler *file)
568
566
{
569
 
  uint length,int_count,int_length,no_empty, int_parts;
570
 
  uint time_stamp_pos,null_fields;
571
 
  ulong reclength, totlength, n_length, com_length;
 
567
  uint32_t length,int_count,int_length,no_empty, int_parts;
 
568
  uint32_t time_stamp_pos,null_fields;
 
569
  ulong reclength, totlength, n_length, com_length, vcol_info_length;
572
570
 
573
571
 
574
572
  if (create_fields.elements > MAX_FIELDS)
580
578
  totlength= 0L;
581
579
  reclength= data_offset;
582
580
  no_empty=int_count=int_parts=int_length=time_stamp_pos=null_fields=
583
 
    com_length=0;
 
581
    com_length=vcol_info_length=0;
584
582
  n_length=2L;
585
583
 
586
584
        /* Check fields */
589
587
  Create_field *field;
590
588
  while ((field=it++))
591
589
  {
592
 
    uint tmp_len= system_charset_info->cset->charpos(system_charset_info,
 
590
    uint32_t tmp_len= system_charset_info->cset->charpos(system_charset_info,
593
591
                                                     field->comment.str,
594
592
                                                     field->comment.str +
595
593
                                                     field->comment.length,
602
600
               (uint) COLUMN_COMMENT_MAXLEN);
603
601
      return(1);
604
602
    }
 
603
    if (field->vcol_info)
 
604
    {
 
605
      tmp_len= system_charset_info->cset->charpos(system_charset_info,
 
606
                                                  field->vcol_info->expr_str.str,
 
607
                                                  field->vcol_info->expr_str.str +
 
608
                                                  field->vcol_info->expr_str.length,
 
609
                                                  VIRTUAL_COLUMN_EXPRESSION_MAXLEN);
 
610
 
 
611
      if (tmp_len < field->vcol_info->expr_str.length)
 
612
      {
 
613
        my_error(ER_WRONG_STRING_LENGTH, MYF(0),
 
614
                 field->vcol_info->expr_str.str,"VIRTUAL COLUMN EXPRESSION",
 
615
                 (uint) VIRTUAL_COLUMN_EXPRESSION_MAXLEN);
 
616
        return(1);
 
617
      }
 
618
      /*
 
619
        Sum up the length of the expression string and mandatory header bytes
 
620
        to the total length.
 
621
      */
 
622
      vcol_info_length+= field->vcol_info->expr_str.length+(uint)FRM_VCOL_HEADER_SIZE;
 
623
    }
605
624
 
606
625
    totlength+= field->length;
607
626
    com_length+= field->comment.length;
616
635
      We mark first TIMESTAMP field with NOW() in DEFAULT or ON UPDATE 
617
636
      as auto-update field.
618
637
    */
619
 
    if (field->sql_type == MYSQL_TYPE_TIMESTAMP &&
 
638
    if (field->sql_type == DRIZZLE_TYPE_TIMESTAMP &&
620
639
        MTYP_TYPENR(field->unireg_check) != Field::NONE &&
621
640
        !time_stamp_pos)
622
641
      time_stamp_pos= (uint) field->offset+ (uint) data_offset + 1;
623
642
    length=field->pack_length;
624
 
    /* Ensure we don't have any bugs when generating offsets */
625
 
    assert(reclength == field->offset + data_offset);
626
643
    if ((uint) field->offset+ (uint) data_offset+ length > reclength)
627
644
      reclength=(uint) (field->offset+ data_offset + length);
628
645
    n_length+= (ulong) strlen(field->field_name)+1;
630
647
    field->save_interval= 0;
631
648
    if (field->interval)
632
649
    {
633
 
      uint old_int_count=int_count;
 
650
      uint32_t old_int_count=int_count;
634
651
 
635
652
      if (field->charset->mbminlen > 1)
636
653
      {
650
667
                                    (field->interval->count+1));
651
668
        field->interval->type_names[field->interval->count]= 0;
652
669
        field->interval->type_lengths=
653
 
          (uint *) sql_alloc(sizeof(uint) * field->interval->count);
 
670
          (uint32_t *) sql_alloc(sizeof(uint) * field->interval->count);
654
671
 
655
 
        for (uint pos= 0; pos < field->interval->count; pos++)
 
672
        for (uint32_t pos= 0; pos < field->interval->count; pos++)
656
673
        {
657
674
          char *dst;
658
675
          const char *src= field->save_interval->type_names[pos];
659
 
          uint hex_length;
 
676
          uint32_t hex_length;
660
677
          length= field->save_interval->type_lengths[pos];
661
678
          hex_length= length * 2;
662
679
          field->interval->type_lengths[pos]= hex_length;
687
704
    return(1);
688
705
  }
689
706
  /* Hack to avoid bugs with small static rows in MySQL */
690
 
  reclength=max(file->min_record_length(table_options),reclength);
 
707
  reclength=cmax((ulong)file->min_record_length(table_options),reclength);
691
708
  if (info_length+(ulong) create_fields.elements*FCOMP+288+
692
 
      n_length+int_length+com_length > 65535L || int_count > 255)
 
709
      n_length+int_length+com_length+vcol_info_length > 65535L || 
 
710
      int_count > 255)
693
711
  {
694
712
    my_message(ER_TOO_MANY_FIELDS, ER(ER_TOO_MANY_FIELDS), MYF(0));
695
713
    return(1);
696
714
  }
697
715
 
698
 
  bzero((char*)forminfo,288);
 
716
  memset(forminfo, 0, 288);
699
717
  length=(info_length+create_fields.elements*FCOMP+288+n_length+int_length+
700
 
          com_length);
 
718
          com_length+vcol_info_length);
701
719
  int2store(forminfo,length);
702
 
  forminfo[256] = (uint8) screens;
 
720
  forminfo[256] = (uint8_t) screens;
703
721
  int2store(forminfo+258,create_fields.elements);
704
722
  int2store(forminfo+260,info_length);
705
723
  int2store(forminfo+262,totlength);
714
732
  int2store(forminfo+280,22);                   /* Rows needed */
715
733
  int2store(forminfo+282,null_fields);
716
734
  int2store(forminfo+284,com_length);
717
 
  /* Up to forminfo+288 is free to use for additional information */
 
735
  int2store(forminfo+286,vcol_info_length);
 
736
  /* forminfo+288 is free to use for additional information */
718
737
  return(0);
719
738
} /* pack_header */
720
739
 
721
740
 
722
741
        /* get each unique interval each own id */
723
742
 
724
 
static uint get_interval_id(uint *int_count,List<Create_field> &create_fields,
 
743
static uint32_t get_interval_id(uint32_t *int_count,List<Create_field> &create_fields,
725
744
                            Create_field *last_field)
726
745
{
727
746
  List_iterator<Create_field> it(create_fields);
752
771
static bool pack_fields(File file, List<Create_field> &create_fields,
753
772
                        ulong data_offset)
754
773
{
755
 
  register uint i;
756
 
  uint int_count, comment_length=0;
757
 
  uchar buff[MAX_FIELD_WIDTH];
 
774
  register uint32_t i;
 
775
  uint32_t int_count, comment_length=0, vcol_info_length=0;
 
776
  unsigned char buff[MAX_FIELD_WIDTH];
758
777
  Create_field *field;
759
778
  
760
779
 
765
784
  int_count=0;
766
785
  while ((field=it++))
767
786
  {
768
 
    uint recpos;
769
 
    buff[0]= (uchar) field->row;
770
 
    buff[1]= (uchar) field->col;
771
 
    buff[2]= (uchar) field->sc_length;
 
787
    uint32_t recpos;
 
788
    uint32_t cur_vcol_expr_len= 0;
 
789
    buff[0]= (unsigned char) field->row;
 
790
    buff[1]= (unsigned char) field->col;
 
791
    buff[2]= (unsigned char) field->sc_length;
772
792
    int2store(buff+3, field->length);
773
793
    /* The +1 is here becasue the col offset in .frm file have offset 1 */
774
794
    recpos= field->offset+1 + (uint) data_offset;
775
795
    int3store(buff+5,recpos);
776
796
    int2store(buff+8,field->pack_flag);
777
797
    int2store(buff+10,field->unireg_check);
778
 
    buff[12]= (uchar) field->interval_id;
779
 
    buff[13]= (uchar) field->sql_type; 
 
798
    buff[12]= (unsigned char) field->interval_id;
 
799
    buff[13]= (unsigned char) field->sql_type; 
780
800
    if (field->charset) 
781
 
      buff[14]= (uchar) field->charset->number;
 
801
      buff[14]= (unsigned char) field->charset->number;
782
802
    else
783
803
      buff[14]= 0;                              // Numerical
 
804
    if (field->vcol_info)
 
805
    {
 
806
      /* 
 
807
        Use the interval_id place in the .frm file to store the length of
 
808
        virtual field's data.
 
809
      */
 
810
      buff[12]= cur_vcol_expr_len= field->vcol_info->expr_str.length +
 
811
                (uint)FRM_VCOL_HEADER_SIZE;
 
812
      vcol_info_length+= cur_vcol_expr_len+(uint)FRM_VCOL_HEADER_SIZE;
 
813
      buff[13]= (unsigned char) DRIZZLE_TYPE_VIRTUAL;
 
814
    }
784
815
    int2store(buff+15, field->comment.length);
785
816
    comment_length+= field->comment.length;
786
817
    set_if_bigger(int_count,field->interval_id);
789
820
  }
790
821
 
791
822
        /* Write fieldnames */
792
 
  buff[0]=(uchar) NAMES_SEP_CHAR;
 
823
  buff[0]=(unsigned char) NAMES_SEP_CHAR;
793
824
  if (my_write(file, buff, 1, MYF_RW))
794
825
    return(1);
795
826
  i=0;
796
827
  it.rewind();
797
828
  while ((field=it++))
798
829
  {
799
 
    char *pos= strmov((char*) buff,field->field_name);
 
830
    char *pos= my_stpcpy((char*) buff,field->field_name);
800
831
    *pos++=NAMES_SEP_CHAR;
801
832
    if (i == create_fields.elements-1)
802
833
      *pos++=0;
818
849
      {
819
850
        unsigned char  sep= 0;
820
851
        unsigned char  occ[256];
821
 
        uint           i;
 
852
        uint32_t           i;
822
853
        unsigned char *val= NULL;
823
854
 
824
 
        bzero(occ, sizeof(occ));
 
855
        memset(occ, 0, sizeof(occ));
825
856
 
826
857
        for (i=0; (val= (unsigned char*) field->interval->type_names[i]); i++)
827
 
          for (uint j = 0; j < field->interval->type_lengths[i]; j++)
 
858
          for (uint32_t j = 0; j < field->interval->type_lengths[i]; j++)
828
859
            occ[(unsigned int) (val[j])]= 1;
829
860
 
830
861
        if (!occ[(unsigned char)NAMES_SEP_CHAR])
833
864
          sep= ',';
834
865
        else
835
866
        {
836
 
          for (uint i=1; i<256; i++)
 
867
          for (uint32_t i=1; i<256; i++)
837
868
          {
838
869
            if(!occ[i])
839
870
            {
860
891
        tmp.append('\0');                      // End of intervall
861
892
      }
862
893
    }
863
 
    if (my_write(file,(uchar*) tmp.ptr(),tmp.length(),MYF_RW))
 
894
    if (my_write(file,(unsigned char*) tmp.ptr(),tmp.length(),MYF_RW))
864
895
      return(1);
865
896
  }
866
897
  if (comment_length)
870
901
    while ((field=it++))
871
902
    {
872
903
      if (field->comment.length)
873
 
        if (my_write(file, (uchar*) field->comment.str, field->comment.length,
 
904
        if (my_write(file, (unsigned char*) field->comment.str, field->comment.length,
874
905
                     MYF_RW))
875
906
          return(1);
876
907
    }
877
908
  }
 
909
  if (vcol_info_length)
 
910
  {
 
911
    it.rewind();
 
912
    int_count=0;
 
913
    while ((field=it++))
 
914
    {
 
915
      /*
 
916
        Pack each virtual field as follows:
 
917
        byte 1      = 1 (always 1 to allow for future extensions)
 
918
        byte 2      = sql_type
 
919
        byte 3      = flags (as of now, 0 - no flags, 1 - field is physically stored)
 
920
        byte 4-...  = virtual column expression (text data)
 
921
      */
 
922
      if (field->vcol_info && field->vcol_info->expr_str.length)
 
923
      {
 
924
        buff[0]= (unsigned char)1;
 
925
        buff[1]= (unsigned char) field->sql_type;
 
926
        buff[2]= (unsigned char) field->is_stored;
 
927
        if (my_write(file, buff, 3, MYF_RW))
 
928
          return(1);
 
929
        if (my_write(file, 
 
930
                     (unsigned char*) field->vcol_info->expr_str.str, 
 
931
                     field->vcol_info->expr_str.length,
 
932
                     MYF_RW))
 
933
          return(1);
 
934
      }
 
935
    }
 
936
  }
878
937
  return(0);
879
938
}
880
939
 
882
941
/* save an empty record on start of formfile */
883
942
 
884
943
static bool make_empty_rec(THD *thd, File file,
885
 
                           enum legacy_db_type table_type __attribute__((__unused__)),
886
 
                           uint table_options,
 
944
                           enum legacy_db_type table_type __attribute__((unused)),
 
945
                           uint32_t table_options,
887
946
                           List<Create_field> &create_fields,
888
 
                           uint reclength,
 
947
                           uint32_t reclength,
889
948
                           ulong data_offset,
890
949
                           handler *handler)
891
950
{
892
951
  int error= 0;
893
952
  Field::utype type;
894
 
  uint null_count;
895
 
  uchar *buff,*null_pos;
896
 
  TABLE table;
 
953
  uint32_t null_count;
 
954
  unsigned char *buff,*null_pos;
 
955
  Table table;
897
956
  TABLE_SHARE share;
898
957
  Create_field *field;
899
958
  enum_check_fields old_count_cuted_fields= thd->count_cuted_fields;
900
959
  
901
960
 
902
961
  /* We need a table to generate columns for default values */
903
 
  bzero((char*) &table, sizeof(table));
904
 
  bzero((char*) &share, sizeof(share));
 
962
  memset(&table, 0, sizeof(table));
 
963
  memset(&share, 0, sizeof(share));
905
964
  table.s= &share;
906
965
 
907
 
  if (!(buff=(uchar*) my_malloc((size_t) reclength,MYF(MY_WME | MY_ZEROFILL))))
 
966
  if (!(buff=(unsigned char*) my_malloc((size_t) reclength,MYF(MY_WME | MY_ZEROFILL))))
908
967
  {
909
968
    return(1);
910
969
  }
969
1028
        goto err;
970
1029
      }
971
1030
    }
972
 
    else if (regfield->real_type() == MYSQL_TYPE_ENUM &&
 
1031
    else if (regfield->real_type() == DRIZZLE_TYPE_ENUM &&
973
1032
             (field->flags & NOT_NULL_FLAG))
974
1033
    {
975
1034
      regfield->set_notnull();
989
1048
    of 8 there are no unused bits.
990
1049
  */
991
1050
  if (null_count & 7)
992
 
    *(null_pos + null_count / 8)|= ~(((uchar) 1 << (null_count & 7)) - 1);
 
1051
    *(null_pos + null_count / 8)|= ~(((unsigned char) 1 << (null_count & 7)) - 1);
993
1052
 
994
1053
  error= my_write(file, buff, (size_t) reclength,MYF_RW) != 0;
995
1054
 
996
1055
err:
997
 
  my_free(buff, MYF(MY_FAE));
 
1056
  free(buff);
998
1057
  thd->count_cuted_fields= old_count_cuted_fields;
999
1058
  return(error);
1000
1059
} /* make_empty_rec */