~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to storage/myisam/mi_dynrec.c

  • 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:
25
25
 
26
26
#include "myisamdef.h"
27
27
 
 
28
#ifdef HAVE_SYS_TYPES
 
29
#include <sys/types.h>
 
30
#endif
 
31
#ifdef HAVE_SYS_MMAN_H
 
32
#include <sys/mman.h>
 
33
#endif
 
34
#include <drizzled/util/test.h>
 
35
 
28
36
/* Enough for comparing if number is zero */
29
37
static char zero_string[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
30
38
 
31
 
static int write_dynamic_record(MI_INFO *info,const uchar *record,
 
39
static int write_dynamic_record(MI_INFO *info,const unsigned char *record,
32
40
                                ulong reclength);
33
41
static int _mi_find_writepos(MI_INFO *info,ulong reclength,my_off_t *filepos,
34
42
                             ulong *length);
35
 
static int update_dynamic_record(MI_INFO *info,my_off_t filepos,uchar *record,
 
43
static int update_dynamic_record(MI_INFO *info,my_off_t filepos,unsigned char *record,
36
44
                                 ulong reclength);
37
45
static int delete_dynamic_record(MI_INFO *info,my_off_t filepos,
38
 
                                 uint second_read);
39
 
static int _mi_cmp_buffer(File file, const uchar *buff, my_off_t filepos,
40
 
                          uint length);
 
46
                                 uint32_t second_read);
 
47
static int _mi_cmp_buffer(File file, const unsigned char *buff, my_off_t filepos,
 
48
                          uint32_t length);
41
49
 
42
50
/* Play it safe; We have a small stack when using threads */
43
51
#undef my_alloca
44
52
#undef my_afree
45
 
#define my_alloca(A) my_malloc((A),MYF(0))
46
 
#define my_afree(A) my_free((A),MYF(0))
 
53
#define my_alloca(A) malloc((A))
 
54
#define my_afree(A) free((A))
47
55
 
48
56
        /* Interface function from MI_INFO */
49
57
 
61
69
    1  error.
62
70
*/
63
71
 
64
 
my_bool mi_dynmap_file(MI_INFO *info, my_off_t size)
 
72
bool mi_dynmap_file(MI_INFO *info, my_off_t size)
65
73
{
66
 
  DBUG_ENTER("mi_dynmap_file");
67
74
  if (size > (my_off_t) (~((size_t) 0)) - MEMMAP_EXTRA_MARGIN)
68
75
  {
69
 
    DBUG_PRINT("warning", ("File is too large for mmap"));
70
 
    DBUG_RETURN(1);
 
76
    return(1);
71
77
  }
72
78
  /*
73
79
    I wonder if it is good to use MAP_NORESERVE. From the Linux man page:
77
83
      mapping. When swap space is not reserved one might get SIGSEGV
78
84
      upon a write if no physical memory is available.
79
85
  */
80
 
  info->s->file_map= (uchar*)
 
86
  info->s->file_map= (unsigned char*)
81
87
                  my_mmap(0, (size_t)(size + MEMMAP_EXTRA_MARGIN),
82
88
                          info->s->mode==O_RDONLY ? PROT_READ :
83
89
                          PROT_READ | PROT_WRITE,
84
90
                          MAP_SHARED | MAP_NORESERVE,
85
91
                          info->dfile, 0L);
86
 
  if (info->s->file_map == (uchar*) MAP_FAILED)
 
92
  if (info->s->file_map == (unsigned char*) MAP_FAILED)
87
93
  {
88
94
    info->s->file_map= NULL;
89
 
    DBUG_RETURN(1);
 
95
    return(1);
90
96
  }
91
97
#if defined(HAVE_MADVISE)
92
98
  madvise((char*) info->s->file_map, size, MADV_RANDOM);
93
99
#endif
94
100
  info->s->mmaped_length= size;
95
 
  DBUG_RETURN(0);
 
101
  return(0);
96
102
}
97
103
 
98
104
 
110
116
{
111
117
  if (info->s->file_map)
112
118
  {
113
 
    VOID(my_munmap((char*) info->s->file_map,
114
 
                   (size_t) info->s->mmaped_length + MEMMAP_EXTRA_MARGIN));
 
119
    my_munmap((char*) info->s->file_map,
 
120
              (size_t) info->s->mmaped_length + MEMMAP_EXTRA_MARGIN);
115
121
    mi_dynmap_file(info, size);
116
122
  }
117
123
}
133
139
    0  ok
134
140
*/
135
141
 
136
 
size_t mi_mmap_pread(MI_INFO *info, uchar *Buffer,
 
142
size_t mi_mmap_pread(MI_INFO *info, unsigned char *Buffer,
137
143
                    size_t Count, my_off_t offset, myf MyFlags)
138
144
{
139
 
  DBUG_PRINT("info", ("mi_read with mmap %d\n", info->dfile));
140
145
  if (info->s->concurrent_insert)
141
146
    rw_rdlock(&info->s->mmap_lock);
142
147
 
165
170
 
166
171
        /* wrapper for my_pread in case if mmap isn't used */
167
172
 
168
 
size_t mi_nommap_pread(MI_INFO *info, uchar *Buffer,
 
173
size_t mi_nommap_pread(MI_INFO *info, unsigned char *Buffer,
169
174
                       size_t Count, my_off_t offset, myf MyFlags)
170
175
{
171
176
  return my_pread(info->dfile, Buffer, Count, offset, MyFlags);
188
193
    !=0  error.  In this case return error from pwrite
189
194
*/
190
195
 
191
 
size_t mi_mmap_pwrite(MI_INFO *info, const uchar *Buffer,
 
196
size_t mi_mmap_pwrite(MI_INFO *info, const unsigned char *Buffer,
192
197
                      size_t Count, my_off_t offset, myf MyFlags)
193
198
{
194
 
  DBUG_PRINT("info", ("mi_write with mmap %d\n", info->dfile));
195
199
  if (info->s->concurrent_insert)
196
200
    rw_rdlock(&info->s->mmap_lock);
197
201
 
222
226
 
223
227
        /* wrapper for my_pwrite in case if mmap isn't used */
224
228
 
225
 
size_t mi_nommap_pwrite(MI_INFO *info, const uchar *Buffer,
 
229
size_t mi_nommap_pwrite(MI_INFO *info, const unsigned char *Buffer,
226
230
                      size_t Count, my_off_t offset, myf MyFlags)
227
231
{
228
232
  return my_pwrite(info->dfile, Buffer, Count, offset, MyFlags);
229
233
}
230
234
 
231
235
 
232
 
int _mi_write_dynamic_record(MI_INFO *info, const uchar *record)
 
236
int _mi_write_dynamic_record(MI_INFO *info, const unsigned char *record)
233
237
{
234
238
  ulong reclength=_mi_rec_pack(info,info->rec_buff,record);
235
239
  return (write_dynamic_record(info,info->rec_buff,reclength));
236
240
}
237
241
 
238
 
int _mi_update_dynamic_record(MI_INFO *info, my_off_t pos, const uchar *record)
 
242
int _mi_update_dynamic_record(MI_INFO *info, my_off_t pos, const unsigned char *record)
239
243
{
240
 
  uint length=_mi_rec_pack(info,info->rec_buff,record);
 
244
  uint32_t length=_mi_rec_pack(info,info->rec_buff,record);
241
245
  return (update_dynamic_record(info,pos,info->rec_buff,length));
242
246
}
243
247
 
244
 
int _mi_write_blob_record(MI_INFO *info, const uchar *record)
 
248
int _mi_write_blob_record(MI_INFO *info, const unsigned char *record)
245
249
{
246
 
  uchar *rec_buff;
 
250
  unsigned char *rec_buff;
247
251
  int error;
248
252
  ulong reclength,reclength2,extra;
249
253
 
258
262
    return -1;
259
263
  }
260
264
#endif
261
 
  if (!(rec_buff=(uchar*) my_alloca(reclength)))
 
265
  if (!(rec_buff=(unsigned char*) my_alloca(reclength)))
262
266
  {
263
267
    my_errno= HA_ERR_OUT_OF_MEM; /* purecov: inspected */
264
268
    return(-1);
265
269
  }
266
270
  reclength2= _mi_rec_pack(info,rec_buff+ALIGN_SIZE(MI_MAX_DYN_BLOCK_HEADER),
267
271
                           record);
268
 
  DBUG_PRINT("info",("reclength: %lu  reclength2: %lu",
269
 
                     reclength, reclength2));
270
 
  DBUG_ASSERT(reclength2 <= reclength);
 
272
  assert(reclength2 <= reclength);
271
273
  error=write_dynamic_record(info,rec_buff+ALIGN_SIZE(MI_MAX_DYN_BLOCK_HEADER),
272
274
                             reclength2);
273
275
  my_afree(rec_buff);
275
277
}
276
278
 
277
279
 
278
 
int _mi_update_blob_record(MI_INFO *info, my_off_t pos, const uchar *record)
 
280
int _mi_update_blob_record(MI_INFO *info, my_off_t pos, const unsigned char *record)
279
281
{
280
 
  uchar *rec_buff;
 
282
  unsigned char *rec_buff;
281
283
  int error;
282
284
  ulong reclength,extra;
283
285
 
292
294
    return -1;
293
295
  }
294
296
#endif
295
 
  if (!(rec_buff=(uchar*) my_alloca(reclength)))
 
297
  if (!(rec_buff=(unsigned char*) my_alloca(reclength)))
296
298
  {
297
299
    my_errno= HA_ERR_OUT_OF_MEM; /* purecov: inspected */
298
300
    return(-1);
315
317
 
316
318
        /* Write record to data-file */
317
319
 
318
 
static int write_dynamic_record(MI_INFO *info, const uchar *record,
 
320
static int write_dynamic_record(MI_INFO *info, const unsigned char *record,
319
321
                                ulong reclength)
320
322
{
321
323
  int flag;
322
324
  ulong length;
323
325
  my_off_t filepos;
324
 
  DBUG_ENTER("write_dynamic_record");
325
326
 
326
327
  flag=0;
327
328
 
343
344
        reclength + MI_MAX_DYN_BLOCK_HEADER)
344
345
    {
345
346
      my_errno=HA_ERR_RECORD_FILE_FULL;
346
 
      DBUG_RETURN(1);
 
347
      return(1);
347
348
    }
348
349
  }
349
350
 
354
355
    if (_mi_write_part_record(info,filepos,length,
355
356
                              (info->append_insert_at_end ?
356
357
                               HA_OFFSET_ERROR : info->s->state.dellink),
357
 
                              (uchar**) &record,&reclength,&flag))
 
358
                              (unsigned char**) &record,&reclength,&flag))
358
359
      goto err;
359
360
  } while (reclength);
360
361
 
361
 
  DBUG_RETURN(0);
 
362
  return(0);
362
363
err:
363
 
  DBUG_RETURN(1);
 
364
  return(1);
364
365
}
365
366
 
366
367
 
373
374
{
374
375
  MI_BLOCK_INFO block_info;
375
376
  ulong tmp;
376
 
  DBUG_ENTER("_mi_find_writepos");
377
377
 
378
378
  if (info->s->state.dellink != HA_OFFSET_ERROR &&
379
379
      !info->append_insert_at_end)
385
385
    if (!(_mi_get_block_info(&block_info,info->dfile,info->s->state.dellink) &
386
386
           BLOCK_DELETED))
387
387
    {
388
 
      DBUG_PRINT("error",("Delete link crashed"));
389
388
      my_errno=HA_ERR_WRONG_IN_RECORD;
390
 
      DBUG_RETURN(-1);
 
389
      return(-1);
391
390
    }
392
391
    info->s->state.dellink=block_info.next_filepos;
393
392
    info->state->del--;
408
407
        (info->s->base.max_data_file_length - tmp))
409
408
    {
410
409
      my_errno=HA_ERR_RECORD_FILE_FULL;
411
 
      DBUG_RETURN(-1);
 
410
      return(-1);
412
411
    }
413
412
    if (tmp > MI_MAX_BLOCK_LENGTH)
414
413
      tmp=MI_MAX_BLOCK_LENGTH;
417
416
    info->s->state.split++;
418
417
    info->update|=HA_STATE_WRITE_AT_END;
419
418
  }
420
 
  DBUG_RETURN(0);
 
419
  return(0);
421
420
} /* _mi_find_writepos */
422
421
 
423
422
 
428
427
  a big block.
429
428
*/
430
429
 
431
 
static my_bool unlink_deleted_block(MI_INFO *info, MI_BLOCK_INFO *block_info)
 
430
static bool unlink_deleted_block(MI_INFO *info, MI_BLOCK_INFO *block_info)
432
431
{
433
 
  DBUG_ENTER("unlink_deleted_block");
434
432
  if (block_info->filepos == info->s->state.dellink)
435
433
  {
436
434
    /* First deleted block;  We can just use this ! */
443
441
    /* Unlink block from the previous block */
444
442
    if (!(_mi_get_block_info(&tmp,info->dfile,block_info->prev_filepos)
445
443
          & BLOCK_DELETED))
446
 
      DBUG_RETURN(1);                           /* Something is wrong */
 
444
      return(1);                                /* Something is wrong */
447
445
    mi_sizestore(tmp.header+4,block_info->next_filepos);
448
446
    if (info->s->file_write(info, tmp.header+4,8,
449
447
                  block_info->prev_filepos+4, MYF(MY_NABP)))
450
 
      DBUG_RETURN(1);
 
448
      return(1);
451
449
    /* Unlink block from next block */
452
450
    if (block_info->next_filepos != HA_OFFSET_ERROR)
453
451
    {
454
452
      if (!(_mi_get_block_info(&tmp,info->dfile,block_info->next_filepos)
455
453
            & BLOCK_DELETED))
456
 
        DBUG_RETURN(1);                         /* Something is wrong */
 
454
        return(1);                              /* Something is wrong */
457
455
      mi_sizestore(tmp.header+12,block_info->prev_filepos);
458
456
      if (info->s->file_write(info, tmp.header+12,8,
459
457
                    block_info->next_filepos+12,
460
458
                    MYF(MY_NABP)))
461
 
        DBUG_RETURN(1);
 
459
        return(1);
462
460
    }
463
461
  }
464
462
  /* We now have one less deleted block */
473
471
  */
474
472
  if (info->nextpos == block_info->filepos)
475
473
    info->nextpos+=block_info->block_len;
476
 
  DBUG_RETURN(0);
 
474
  return(0);
477
475
}
478
476
 
479
477
 
496
494
                                       my_off_t filepos)
497
495
{
498
496
  MI_BLOCK_INFO block_info;
499
 
  DBUG_ENTER("update_backward_delete_link");
500
497
 
501
498
  if (delete_block != HA_OFFSET_ERROR)
502
499
  {
504
501
    if (_mi_get_block_info(&block_info,info->dfile,delete_block)
505
502
        & BLOCK_DELETED)
506
503
    {
507
 
      uchar buff[8];
 
504
      unsigned char buff[8];
508
505
      mi_sizestore(buff,filepos);
509
506
      if (info->s->file_write(info,buff, 8, delete_block+12, MYF(MY_NABP)))
510
 
        DBUG_RETURN(1);                         /* Error on write */
 
507
        return(1);                              /* Error on write */
511
508
    }
512
509
    else
513
510
    {
514
511
      my_errno=HA_ERR_WRONG_IN_RECORD;
515
 
      DBUG_RETURN(1);                           /* Wrong delete link */
 
512
      return(1);                                /* Wrong delete link */
516
513
    }
517
514
  }
518
 
  DBUG_RETURN(0);
 
515
  return(0);
519
516
}
520
517
 
521
518
        /* Delete datarecord from database */
522
519
        /* info->rec_cache.seek_not_done is updated in cmp_record */
523
520
 
524
521
static int delete_dynamic_record(MI_INFO *info, my_off_t filepos,
525
 
                                 uint second_read)
 
522
                                 uint32_t second_read)
526
523
{
527
 
  uint length,b_type;
 
524
  uint32_t length,b_type;
528
525
  MI_BLOCK_INFO block_info,del_block;
529
526
  int error;
530
 
  my_bool remove_next_block;
531
 
  DBUG_ENTER("delete_dynamic_record");
 
527
  bool remove_next_block;
532
528
 
533
529
  /* First add a link from the last block to the new one */
534
530
  error= update_backward_delete_link(info, info->s->state.dellink, filepos);
544
540
        MI_MIN_BLOCK_LENGTH)
545
541
    {
546
542
      my_errno=HA_ERR_WRONG_IN_RECORD;
547
 
      DBUG_RETURN(1);
 
543
      return(1);
548
544
    }
549
545
    /* Check if next block is a delete block */
550
546
    del_block.second_read=0;
561
557
    mi_int3store(block_info.header+1,length);
562
558
    mi_sizestore(block_info.header+4,info->s->state.dellink);
563
559
    if (b_type & BLOCK_LAST)
564
 
      bfill(block_info.header+12,8,255);
 
560
      memset(block_info.header+12, 255, 8);
565
561
    else
566
562
      mi_sizestore(block_info.header+12,block_info.next_filepos);
567
 
    if (info->s->file_write(info,(uchar*) block_info.header,20,filepos,
 
563
    if (info->s->file_write(info,(unsigned char*) block_info.header,20,filepos,
568
564
                  MYF(MY_NABP)))
569
 
      DBUG_RETURN(1);
 
565
      return(1);
570
566
    info->s->state.dellink = filepos;
571
567
    info->state->del++;
572
568
    info->state->empty+=length;
577
573
      error=1;
578
574
  } while (!(b_type & BLOCK_LAST));
579
575
 
580
 
  DBUG_RETURN(error);
 
576
  return(error);
581
577
}
582
578
 
583
579
 
587
583
                          my_off_t filepos,     /* points at empty block */
588
584
                          ulong length,         /* length of block */
589
585
                          my_off_t next_filepos,/* Next empty block */
590
 
                          uchar **record,       /* pointer to record ptr */
 
586
                          unsigned char **record,       /* pointer to record ptr */
591
587
                          ulong *reclength,     /* length of *record */
592
588
                          int *flag)            /* *flag == 0 if header */
593
589
{
594
590
  ulong head_length,res_length,extra_length,long_block,del_length;
595
 
  uchar *pos,*record_end;
 
591
  unsigned char *pos,*record_end;
596
592
  my_off_t  next_delete_block;
597
 
  uchar temp[MI_SPLIT_LENGTH+MI_DYN_DELETE_BLOCK_HEADER];
598
 
  DBUG_ENTER("_mi_write_part_record");
 
593
  unsigned char temp[MI_SPLIT_LENGTH+MI_DYN_DELETE_BLOCK_HEADER];
599
594
 
600
595
  next_delete_block=HA_OFFSET_ERROR;
601
596
 
610
605
  if (length == *reclength+ 3 + long_block)
611
606
  {
612
607
    /* Block is exactly of the right length */
613
 
    temp[0]=(uchar) (1+ *flag)+(uchar) long_block;      /* Flag is 0 or 6 */
 
608
    temp[0]=(unsigned char) (1+ *flag)+(unsigned char) long_block;      /* Flag is 0 or 6 */
614
609
    if (long_block)
615
610
    {
616
611
      mi_int3store(temp+1,*reclength);
636
631
        temp[0]=13;
637
632
        mi_int4store(temp+1,*reclength);
638
633
        mi_int3store(temp+5,length-head_length);
639
 
        mi_sizestore((uchar*) temp+8,next_filepos);
 
634
        mi_sizestore((unsigned char*) temp+8,next_filepos);
640
635
      }
641
636
      else
642
637
      {
643
638
        head_length=5+8+long_block*2;
644
 
        temp[0]=5+(uchar) long_block;
 
639
        temp[0]=5+(unsigned char) long_block;
645
640
        if (long_block)
646
641
        {
647
642
          mi_int3store(temp+1,*reclength);
648
643
          mi_int3store(temp+4,length-head_length);
649
 
          mi_sizestore((uchar*) temp+7,next_filepos);
 
644
          mi_sizestore((unsigned char*) temp+7,next_filepos);
650
645
        }
651
646
        else
652
647
        {
653
648
          mi_int2store(temp+1,*reclength);
654
649
          mi_int2store(temp+3,length-head_length);
655
 
          mi_sizestore((uchar*) temp+5,next_filepos);
 
650
          mi_sizestore((unsigned char*) temp+5,next_filepos);
656
651
        }
657
652
      }
658
653
    }
659
654
    else
660
655
    {
661
656
      head_length=3+8+long_block;
662
 
      temp[0]=11+(uchar) long_block;
 
657
      temp[0]=11+(unsigned char) long_block;
663
658
      if (long_block)
664
659
      {
665
660
        mi_int3store(temp+1,length-head_length);
666
 
        mi_sizestore((uchar*) temp+4,next_filepos);
 
661
        mi_sizestore((unsigned char*) temp+4,next_filepos);
667
662
      }
668
663
      else
669
664
      {
670
665
        mi_int2store(temp+1,length-head_length);
671
 
        mi_sizestore((uchar*) temp+3,next_filepos);
 
666
        mi_sizestore((unsigned char*) temp+3,next_filepos);
672
667
      }
673
668
    }
674
669
  }
676
671
  {                                     /* Block with empty info last */
677
672
    head_length=4+long_block;
678
673
    extra_length= length- *reclength-head_length;
679
 
    temp[0]= (uchar) (3+ *flag)+(uchar) long_block; /* 3,4 or 9,10 */
 
674
    temp[0]= (unsigned char) (3+ *flag)+(unsigned char) long_block; /* 3,4 or 9,10 */
680
675
    if (long_block)
681
676
    {
682
677
      mi_int3store(temp+1,*reclength);
683
 
      temp[4]= (uchar) (extra_length);
 
678
      temp[4]= (unsigned char) (extra_length);
684
679
    }
685
680
    else
686
681
    {
687
682
      mi_int2store(temp+1,*reclength);
688
 
      temp[3]= (uchar) (extra_length);
 
683
      temp[3]= (unsigned char) (extra_length);
689
684
    }
690
685
    length=       *reclength+head_length;       /* Write only what is needed */
691
686
  }
692
 
  DBUG_DUMP("header",(uchar*) temp,head_length);
693
687
 
694
688
        /* Make a long block for one write */
695
689
  record_end= *record+length-head_length;
696
690
  del_length=(res_length ? MI_DYN_DELETE_BLOCK_HEADER : 0);
697
 
  bmove((uchar*) (*record-head_length),(uchar*) temp,head_length);
 
691
  memcpy(*record - head_length, temp, head_length);
698
692
  memcpy(temp,record_end,(size_t) (extra_length+del_length));
699
 
  bzero((uchar*) record_end,extra_length);
 
693
  memset(record_end, 0, extra_length);
700
694
 
701
695
  if (res_length)
702
696
  {
723
717
    pos[0]= '\0';
724
718
    mi_int3store(pos+1,res_length);
725
719
    mi_sizestore(pos+4,info->s->state.dellink);
726
 
    bfill(pos+12,8,255);                        /* End link */
 
720
    memset(pos+12, 255, 8);                     /* End link */
727
721
    next_delete_block=info->s->state.dellink;
728
722
    info->s->state.dellink= filepos+length+extra_length;
729
723
    info->state->del++;
736
730
    if (info->update & HA_STATE_EXTEND_BLOCK)
737
731
    {
738
732
      info->update&= ~HA_STATE_EXTEND_BLOCK;
739
 
      if (my_block_write(&info->rec_cache,(uchar*) *record-head_length,
 
733
      if (my_block_write(&info->rec_cache,(unsigned char*) *record-head_length,
740
734
                         length+extra_length+del_length,filepos))
741
735
      goto err;
742
736
    }
743
 
    else if (my_b_write(&info->rec_cache,(uchar*) *record-head_length,
 
737
    else if (my_b_write(&info->rec_cache,(unsigned char*) *record-head_length,
744
738
                        length+extra_length+del_length))
745
739
      goto err;
746
740
  }
747
741
  else
748
742
  {
749
743
    info->rec_cache.seek_not_done=1;
750
 
    if (info->s->file_write(info,(uchar*) *record-head_length,length+extra_length+
 
744
    if (info->s->file_write(info,(unsigned char*) *record-head_length,length+extra_length+
751
745
                  del_length,filepos,info->s->write_flag))
752
746
      goto err;
753
747
  }
754
 
  memcpy(record_end,temp,(size_t) (extra_length+del_length));
 
748
  memcpy(record_end, temp, extra_length + del_length);
755
749
  *record=record_end;
756
750
  *reclength-=(length-head_length);
757
751
  *flag=6;
764
758
      goto err;
765
759
  }
766
760
 
767
 
  DBUG_RETURN(0);
 
761
  return(0);
768
762
err:
769
 
  DBUG_PRINT("exit",("errno: %d",my_errno));
770
 
  DBUG_RETURN(1);
 
763
  return(1);
771
764
} /*_mi_write_part_record */
772
765
 
773
766
 
774
767
        /* update record from datafile */
775
768
 
776
 
static int update_dynamic_record(MI_INFO *info, my_off_t filepos, uchar *record,
 
769
static int update_dynamic_record(MI_INFO *info, my_off_t filepos, unsigned char *record,
777
770
                                 ulong reclength)
778
771
{
779
772
  int flag;
780
 
  uint error;
 
773
  uint32_t error;
781
774
  ulong length;
782
775
  MI_BLOCK_INFO block_info;
783
 
  DBUG_ENTER("update_dynamic_record");
784
776
 
785
777
  flag=block_info.second_read=0;
786
778
  /*
806
798
    if ((error=_mi_get_block_info(&block_info,info->dfile,filepos))
807
799
        & (BLOCK_DELETED | BLOCK_ERROR | BLOCK_SYNC_ERROR | BLOCK_FATAL_ERROR))
808
800
    {
809
 
      DBUG_PRINT("error",("Got wrong block info"));
810
801
      if (!(error & BLOCK_FATAL_ERROR))
811
802
        my_errno=HA_ERR_WRONG_IN_RECORD;
812
803
      goto err;
837
828
          & (BLOCK_DELETED | BLOCK_ERROR | BLOCK_SYNC_ERROR |
838
829
             BLOCK_FATAL_ERROR))
839
830
      {
840
 
        DBUG_PRINT("error",("Got wrong block info"));
841
831
        if (!(error & BLOCK_FATAL_ERROR))
842
832
          my_errno=HA_ERR_WRONG_IN_RECORD;
843
833
        goto err;
845
835
      length=(ulong) (block_info.filepos-filepos) + block_info.block_len;
846
836
      if (length < reclength)
847
837
      {
848
 
        uint tmp=MY_ALIGN(reclength - length + 3 +
 
838
        uint32_t tmp=MY_ALIGN(reclength - length + 3 +
849
839
                          test(reclength >= 65520L),MI_DYN_ALIGN_SIZE);
850
840
        /* Don't create a block bigger than MI_MAX_BLOCK_LENGTH */
851
 
        tmp= min(length+tmp, MI_MAX_BLOCK_LENGTH)-length;
 
841
        tmp= cmin(length+tmp, MI_MAX_BLOCK_LENGTH)-length;
852
842
        /* Check if we can extend this block */
853
843
        if (block_info.filepos + block_info.block_len ==
854
844
            info->state->data_file_length &&
856
846
            info->s->base.max_data_file_length-tmp)
857
847
        {
858
848
          /* extend file */
859
 
          DBUG_PRINT("info",("Extending file with %d bytes",tmp));
860
849
          if (info->nextpos == info->state->data_file_length)
861
850
            info->nextpos+= tmp;
862
851
          info->state->data_file_length+= tmp;
879
868
              BLOCK_DELETED)
880
869
          {
881
870
            /* Use; Unlink it and extend the current block */
882
 
            DBUG_PRINT("info",("Extending current block"));
883
871
            if (unlink_deleted_block(info,&del_block))
884
872
              goto err;
885
873
            if ((length+=del_block.block_len) > MI_MAX_BLOCK_LENGTH)
895
883
 
896
884
              if (update_backward_delete_link(info, info->s->state.dellink,
897
885
                                              next_pos))
898
 
                DBUG_RETURN(1);
 
886
                return(1);
899
887
 
900
888
              /* create delete link for data that didn't fit into the page */
901
889
              del_block.header[0]=0;
902
890
              mi_int3store(del_block.header+1, rest_length);
903
891
              mi_sizestore(del_block.header+4,info->s->state.dellink);
904
 
              bfill(del_block.header+12,8,255);
905
 
              if (info->s->file_write(info,(uchar*) del_block.header,20, next_pos,
 
892
              memset(del_block.header+12, 255, 8);
 
893
              if (info->s->file_write(info,(unsigned char*) del_block.header,20, next_pos,
906
894
                            MYF(MY_NABP)))
907
 
                DBUG_RETURN(1);
 
895
                return(1);
908
896
              info->s->state.dellink= next_pos;
909
897
              info->s->state.split++;
910
898
              info->state->del++;
933
921
  if (block_info.next_filepos != HA_OFFSET_ERROR)
934
922
    if (delete_dynamic_record(info,block_info.next_filepos,1))
935
923
      goto err;
936
 
  DBUG_RETURN(0);
 
924
  return(0);
937
925
err:
938
 
  DBUG_RETURN(1);
 
926
  return(1);
939
927
}
940
928
 
941
929
 
942
930
        /* Pack a record. Return new reclength */
943
931
 
944
 
uint _mi_rec_pack(MI_INFO *info, register uchar *to,
945
 
                  register const uchar *from)
 
932
uint32_t _mi_rec_pack(MI_INFO *info, register unsigned char *to,
 
933
                  register const unsigned char *from)
946
934
{
947
935
  uint          length,new_length,flag,bit,i;
948
 
  uchar         *pos,*end,*startpos,*packpos;
 
936
  unsigned char         *pos,*end,*startpos,*packpos;
949
937
  enum en_fieldtype type;
950
938
  register MI_COLUMNDEF *rec;
951
939
  MI_BLOB       *blob;
952
 
  DBUG_ENTER("_mi_rec_pack");
953
940
 
954
941
  flag=0 ; bit=1;
955
942
  startpos=packpos=to; to+= info->s->base.pack_bits; blob=info->blobs;
968
955
        {
969
956
          char *temp_pos;
970
957
          size_t tmp_length=length-portable_sizeof_char_ptr;
971
 
          memcpy((uchar*) to,from,tmp_length);
972
 
          memcpy_fixed(&temp_pos,from+tmp_length,sizeof(char*));
973
 
          memcpy(to+tmp_length,temp_pos,(size_t) blob->length);
 
958
          memcpy(to,from,tmp_length);
 
959
          memcpy(&temp_pos,from+tmp_length,sizeof(char*));
 
960
          memcpy(to + tmp_length, temp_pos, blob->length);
974
961
          to+=tmp_length+blob->length;
975
962
        }
976
963
        blob++;
977
964
      }
978
965
      else if (type == FIELD_SKIP_ZERO)
979
966
      {
980
 
        if (memcmp((uchar*) from,zero_string,length) == 0)
 
967
        if (memcmp(from,zero_string,length) == 0)
981
968
          flag|=bit;
982
969
        else
983
970
        {
984
 
          memcpy((uchar*) to,from,(size_t) length); to+=length;
 
971
          memcpy(to, from, length);
 
972
          to+=length;
985
973
        }
986
974
      }
987
975
      else if (type == FIELD_SKIP_ENDSPACE ||
988
976
               type == FIELD_SKIP_PRESPACE)
989
977
      {
990
 
        pos= (uchar*) from; end= (uchar*) from + length;
 
978
        pos= (unsigned char*) from; end= (unsigned char*) from + length;
991
979
        if (type == FIELD_SKIP_ENDSPACE)
992
980
        {                                       /* Pack trailing spaces */
993
981
          while (end > from && *(end-1) == ' ')
1004
992
        {
1005
993
          if (rec->length > 255 && new_length > 127)
1006
994
          {
1007
 
            to[0]= (uchar) ((new_length & 127) + 128);
1008
 
            to[1]= (uchar) (new_length >> 7);
 
995
            to[0]= (unsigned char) ((new_length & 127) + 128);
 
996
            to[1]= (unsigned char) (new_length >> 7);
1009
997
            to+=2;
1010
998
          }
1011
999
          else
1012
 
            *to++= (uchar) new_length;
1013
 
          memcpy((uchar*) to,pos,(size_t) new_length); to+=new_length;
 
1000
            *to++= (unsigned char) new_length;
 
1001
          memcpy(to, pos, new_length);
 
1002
          to+=new_length;
1014
1003
          flag|=bit;
1015
1004
        }
1016
1005
        else
1017
1006
        {
1018
 
          memcpy(to,from,(size_t) length); to+=length;
 
1007
          memcpy(to, from, length);
 
1008
          to+=length;
1019
1009
        }
1020
1010
      }
1021
1011
      else if (type == FIELD_VARCHAR)
1022
1012
      {
1023
 
        uint pack_length= HA_VARCHAR_PACKLENGTH(rec->length -1);
1024
 
        uint tmp_length;
 
1013
        uint32_t pack_length= HA_VARCHAR_PACKLENGTH(rec->length -1);
 
1014
        uint32_t tmp_length;
1025
1015
        if (pack_length == 1)
1026
1016
        {
1027
 
          tmp_length= (uint) *(uchar*) from;
 
1017
          tmp_length= (uint) *(unsigned char*) from;
1028
1018
          *to++= *from;
1029
1019
        }
1030
1020
        else
1032
1022
          tmp_length= uint2korr(from);
1033
1023
          store_key_length_inc(to,tmp_length);
1034
1024
        }
1035
 
        memcpy(to, from+pack_length,tmp_length);
 
1025
        memcpy(to, from+pack_length, tmp_length);
1036
1026
        to+= tmp_length;
1037
1027
        continue;
1038
1028
      }
1039
1029
      else
1040
1030
      {
1041
 
        memcpy(to,from,(size_t) length); to+=length;
 
1031
        memcpy(to, from, length);
 
1032
        to+=length;
1042
1033
        continue;                               /* Normal field */
1043
1034
      }
1044
1035
      if ((bit= bit << 1) >= 256)
1045
1036
      {
1046
 
        *packpos++= (uchar) flag;
 
1037
        *packpos++= (unsigned char) flag;
1047
1038
        bit=1; flag=0;
1048
1039
      }
1049
1040
    }
1050
1041
    else
1051
1042
    {
1052
 
      memcpy(to,from,(size_t) length); to+=length;
 
1043
      memcpy(to, from, length);
 
1044
      to+=length;
1053
1045
    }
1054
1046
  }
1055
1047
  if (bit != 1)
1056
 
    *packpos= (uchar) flag;
 
1048
    *packpos= (unsigned char) flag;
1057
1049
  if (info->s->calc_checksum)
1058
 
    *to++= (uchar) info->checksum;
1059
 
  DBUG_PRINT("exit",("packed length: %d",(int) (to-startpos)));
1060
 
  DBUG_RETURN((uint) (to-startpos));
 
1050
    *to++= (unsigned char) info->checksum;
 
1051
  return((uint) (to-startpos));
1061
1052
} /* _mi_rec_pack */
1062
1053
 
1063
1054
 
1067
1058
  Returns 0 if record is ok.
1068
1059
*/
1069
1060
 
1070
 
my_bool _mi_rec_check(MI_INFO *info,const uchar *record, uchar *rec_buff,
1071
 
                      ulong packed_length, my_bool with_checksum)
 
1061
bool _mi_rec_check(MI_INFO *info,const unsigned char *record, unsigned char *rec_buff,
 
1062
                      ulong packed_length, bool with_checksum)
1072
1063
{
1073
1064
  uint          length,new_length,flag,bit,i;
1074
 
  uchar         *pos,*end,*packpos,*to;
 
1065
  unsigned char         *pos,*end,*packpos,*to;
1075
1066
  enum en_fieldtype type;
1076
1067
  register MI_COLUMNDEF *rec;
1077
 
  DBUG_ENTER("_mi_rec_check");
1078
1068
 
1079
1069
  packpos=rec_buff; to= rec_buff+info->s->base.pack_bits;
1080
1070
  rec=info->s->rec;
1087
1077
    {
1088
1078
      if (type == FIELD_BLOB)
1089
1079
      {
1090
 
        uint blob_length=
 
1080
        uint32_t blob_length=
1091
1081
          _mi_calc_blob_length(length-portable_sizeof_char_ptr,record);
1092
1082
        if (!blob_length && !(flag & bit))
1093
1083
          goto err;
1096
1086
      }
1097
1087
      else if (type == FIELD_SKIP_ZERO)
1098
1088
      {
1099
 
        if (memcmp((uchar*) record,zero_string,length) == 0)
 
1089
        if (memcmp(record,zero_string,length) == 0)
1100
1090
        {
1101
1091
          if (!(flag & bit))
1102
1092
            goto err;
1107
1097
      else if (type == FIELD_SKIP_ENDSPACE ||
1108
1098
               type == FIELD_SKIP_PRESPACE)
1109
1099
      {
1110
 
        pos= (uchar*) record; end= (uchar*) record + length;
 
1100
        pos= (unsigned char*) record; end= (unsigned char*) record + length;
1111
1101
        if (type == FIELD_SKIP_ENDSPACE)
1112
1102
        {                                       /* Pack trailing spaces */
1113
1103
          while (end > record && *(end-1) == ' ')
1127
1117
          if (rec->length > 255 && new_length > 127)
1128
1118
          {
1129
1119
            /* purecov: begin inspected */
1130
 
            if (to[0] != (uchar) ((new_length & 127) + 128) ||
1131
 
                to[1] != (uchar) (new_length >> 7))
 
1120
            if (to[0] != (unsigned char) ((new_length & 127) + 128) ||
 
1121
                to[1] != (unsigned char) (new_length >> 7))
1132
1122
              goto err;
1133
1123
            to+=2;
1134
1124
            /* purecov: end */
1135
1125
          }
1136
 
          else if (*to++ != (uchar) new_length)
 
1126
          else if (*to++ != (unsigned char) new_length)
1137
1127
            goto err;
1138
1128
          to+=new_length;
1139
1129
        }
1142
1132
      }
1143
1133
      else if (type == FIELD_VARCHAR)
1144
1134
      {
1145
 
        uint pack_length= HA_VARCHAR_PACKLENGTH(rec->length -1);
1146
 
        uint tmp_length;
 
1135
        uint32_t pack_length= HA_VARCHAR_PACKLENGTH(rec->length -1);
 
1136
        uint32_t tmp_length;
1147
1137
        if (pack_length == 1)
1148
1138
        {
1149
 
          tmp_length= (uint) *(uchar*) record;
 
1139
          tmp_length= (uint) *(unsigned char*) record;
1150
1140
          to+= 1+ tmp_length;
1151
1141
          continue;
1152
1142
        }
1174
1164
  if (packed_length != (uint) (to - rec_buff) + test(info->s->calc_checksum) ||
1175
1165
      (bit != 1 && (flag & ~(bit - 1))))
1176
1166
    goto err;
1177
 
  if (with_checksum && ((uchar) info->checksum != (uchar) *to))
 
1167
  if (with_checksum && ((unsigned char) info->checksum != (unsigned char) *to))
1178
1168
  {
1179
 
    DBUG_PRINT("error",("wrong checksum for row"));
1180
1169
    goto err;
1181
1170
  }
1182
 
  DBUG_RETURN(0);
 
1171
  return(0);
1183
1172
 
1184
1173
err:
1185
 
  DBUG_RETURN(1);
 
1174
  return(1);
1186
1175
}
1187
1176
 
1188
1177
 
1191
1180
        /* Returns -1 and my_errno =HA_ERR_RECORD_DELETED if reclength isn't */
1192
1181
        /* right. Returns reclength (>0) if ok */
1193
1182
 
1194
 
ulong _mi_rec_unpack(register MI_INFO *info, register uchar *to, uchar *from,
 
1183
ulong _mi_rec_unpack(register MI_INFO *info, register unsigned char *to, unsigned char *from,
1195
1184
                     ulong found_length)
1196
1185
{
1197
 
  uint flag,bit,length,rec_length,min_pack_length;
 
1186
  uint32_t flag,bit,length,rec_length,min_pack_length;
1198
1187
  enum en_fieldtype type;
1199
 
  uchar *from_end,*to_end,*packpos;
 
1188
  unsigned char *from_end,*to_end,*packpos;
1200
1189
  register MI_COLUMNDEF *rec,*end_field;
1201
 
  DBUG_ENTER("_mi_rec_unpack");
1202
1190
 
1203
1191
  to_end=to + info->s->base.reclength;
1204
1192
  from_end=from+found_length;
1205
 
  flag= (uchar) *from; bit=1; packpos=from;
 
1193
  flag= (unsigned char) *from; bit=1; packpos=from;
1206
1194
  if (found_length < info->s->base.min_pack_length)
1207
1195
    goto err;
1208
1196
  from+= info->s->base.pack_bits;
1217
1205
    {
1218
1206
      if (type == FIELD_VARCHAR)
1219
1207
      {
1220
 
        uint pack_length= HA_VARCHAR_PACKLENGTH(rec_length-1);
 
1208
        uint32_t pack_length= HA_VARCHAR_PACKLENGTH(rec_length-1);
1221
1209
        if (pack_length == 1)
1222
1210
        {
1223
 
          length= (uint) *(uchar*) from;
 
1211
          length= (uint) *(unsigned char*) from;
1224
1212
          if (length > rec_length-1)
1225
1213
            goto err;
1226
1214
          *to= *from++;
1242
1230
      if (flag & bit)
1243
1231
      {
1244
1232
        if (type == FIELD_BLOB || type == FIELD_SKIP_ZERO)
1245
 
          bzero((uchar*) to,rec_length);
 
1233
          memset(to, 0, rec_length);
1246
1234
        else if (type == FIELD_SKIP_ENDSPACE ||
1247
1235
                 type == FIELD_SKIP_PRESPACE)
1248
1236
        {
1250
1238
          {
1251
1239
            if (from + 1 >= from_end)
1252
1240
              goto err;
1253
 
            length= (*from & 127)+ ((uint) (uchar) *(from+1) << 7); from+=2;
 
1241
            length= (*from & 127)+ ((uint) (unsigned char) *(from+1) << 7); from+=2;
1254
1242
          }
1255
1243
          else
1256
1244
          {
1257
1245
            if (from == from_end)
1258
1246
              goto err;
1259
 
            length= (uchar) *from++;
 
1247
            length= (unsigned char) *from++;
1260
1248
          }
1261
1249
          min_pack_length--;
1262
1250
          if (length >= rec_length ||
1264
1252
            goto err;
1265
1253
          if (type == FIELD_SKIP_ENDSPACE)
1266
1254
          {
1267
 
            memcpy(to,(uchar*) from,(size_t) length);
1268
 
            bfill((uchar*) to+length,rec_length-length,' ');
 
1255
            memcpy(to, from, length);
 
1256
            memset(to+length, ' ', rec_length-length);
1269
1257
          }
1270
1258
          else
1271
1259
          {
1272
 
            bfill((uchar*) to,rec_length-length,' ');
1273
 
            memcpy(to+rec_length-length,(uchar*) from,(size_t) length);
 
1260
            memset(to, ' ', rec_length-length);
 
1261
            memcpy(to + rec_length - length, from, length);
1274
1262
          }
1275
1263
          from+=length;
1276
1264
        }
1277
1265
      }
1278
1266
      else if (type == FIELD_BLOB)
1279
1267
      {
1280
 
        uint size_length=rec_length- portable_sizeof_char_ptr;
 
1268
        uint32_t size_length=rec_length- portable_sizeof_char_ptr;
1281
1269
        ulong blob_length=_mi_calc_blob_length(size_length,from);
1282
1270
        ulong from_left= (ulong) (from_end - from);
1283
1271
        if (from_left < size_length ||
1284
1272
            from_left - size_length < blob_length ||
1285
1273
            from_left - size_length - blob_length < min_pack_length)
1286
1274
          goto err;
1287
 
        memcpy((uchar*) to,(uchar*) from,(size_t) size_length);
 
1275
        memcpy(to, from, size_length);
1288
1276
        from+=size_length;
1289
 
        memcpy_fixed((uchar*) to+size_length,(uchar*) &from,sizeof(char*));
 
1277
        memcpy(to+size_length, &from, sizeof(char*));
1290
1278
        from+=blob_length;
1291
1279
      }
1292
1280
      else
1295
1283
          min_pack_length--;
1296
1284
        if (min_pack_length + rec_length > (uint) (from_end - from))
1297
1285
          goto err;
1298
 
        memcpy(to,(uchar*) from,(size_t) rec_length); from+=rec_length;
 
1286
        memcpy(to, from, rec_length);
 
1287
        from+=rec_length;
1299
1288
      }
1300
1289
      if ((bit= bit << 1) >= 256)
1301
1290
      {
1302
 
        flag= (uchar) *++packpos; bit=1;
 
1291
        flag= (unsigned char) *++packpos; bit=1;
1303
1292
      }
1304
1293
    }
1305
1294
    else
1307
1296
      if (min_pack_length > (uint) (from_end - from))
1308
1297
        goto err;
1309
1298
      min_pack_length-=rec_length;
1310
 
      memcpy(to, (uchar*) from, (size_t) rec_length);
 
1299
      memcpy(to, from, rec_length);
1311
1300
      from+=rec_length;
1312
1301
    }
1313
1302
  }
1314
1303
  if (info->s->calc_checksum)
1315
1304
    from++;
1316
1305
  if (to == to_end && from == from_end && (bit == 1 || !(flag & ~(bit-1))))
1317
 
    DBUG_RETURN(found_length);
 
1306
    return(found_length);
1318
1307
 
1319
1308
err:
1320
1309
  my_errno= HA_ERR_WRONG_IN_RECORD;
1321
 
  DBUG_PRINT("error",("to_end: 0x%lx -> 0x%lx  from_end: 0x%lx -> 0x%lx",
1322
 
                      (long) to, (long) to_end, (long) from, (long) from_end));
1323
 
  DBUG_DUMP("from",(uchar*) info->rec_buff,info->s->base.min_pack_length);
1324
 
  DBUG_RETURN(MY_FILE_ERROR);
 
1310
  return(MY_FILE_ERROR);
1325
1311
} /* _mi_rec_unpack */
1326
1312
 
1327
1313
 
1328
1314
        /* Calc length of blob. Update info in blobs->length */
1329
1315
 
1330
 
ulong _my_calc_total_blob_length(MI_INFO *info, const uchar *record)
 
1316
ulong _my_calc_total_blob_length(MI_INFO *info, const unsigned char *record)
1331
1317
{
1332
1318
  ulong length;
1333
1319
  MI_BLOB *blob,*end;
1343
1329
}
1344
1330
 
1345
1331
 
1346
 
ulong _mi_calc_blob_length(uint length, const uchar *pos)
 
1332
ulong _mi_calc_blob_length(uint32_t length, const unsigned char *pos)
1347
1333
{
1348
1334
  switch (length) {
1349
1335
  case 1:
1350
 
    return (uint) (uchar) *pos;
 
1336
    return (uint) (unsigned char) *pos;
1351
1337
  case 2:
1352
1338
    return (uint) uint2korr(pos);
1353
1339
  case 3:
1361
1347
}
1362
1348
 
1363
1349
 
1364
 
void _my_store_blob_length(uchar *pos,uint pack_length,uint length)
 
1350
void _my_store_blob_length(unsigned char *pos,uint32_t pack_length,uint32_t length)
1365
1351
{
1366
1352
  switch (pack_length) {
1367
1353
  case 1:
1368
 
    *pos= (uchar) length;
 
1354
    *pos= (unsigned char) length;
1369
1355
    break;
1370
1356
  case 2:
1371
1357
    int2store(pos,length);
1414
1400
    -1          Error
1415
1401
*/
1416
1402
 
1417
 
int _mi_read_dynamic_record(MI_INFO *info, my_off_t filepos, uchar *buf)
 
1403
int _mi_read_dynamic_record(MI_INFO *info, my_off_t filepos, unsigned char *buf)
1418
1404
{
1419
1405
  int block_of_record;
1420
 
  uint b_type, left_length= 0;
1421
 
  uchar *to= NULL;
 
1406
  uint32_t b_type, left_length= 0;
 
1407
  unsigned char *to= NULL;
1422
1408
  MI_BLOCK_INFO block_info;
1423
1409
  File file;
1424
 
  DBUG_ENTER("mi_read_dynamic_record");
1425
1410
 
1426
1411
  if (filepos != HA_OFFSET_ERROR)
1427
1412
  {
1464
1449
        goto panic;                     /* Wrong linked record */
1465
1450
      /* copy information that is already read */
1466
1451
      {
1467
 
        uint offset= (uint) (block_info.filepos - filepos);
1468
 
        uint prefetch_len= (sizeof(block_info.header) - offset);
 
1452
        uint32_t offset= (uint) (block_info.filepos - filepos);
 
1453
        uint32_t prefetch_len= (sizeof(block_info.header) - offset);
1469
1454
        filepos+= sizeof(block_info.header);
1470
1455
 
1471
1456
        if (prefetch_len > block_info.data_len)
1472
1457
          prefetch_len= block_info.data_len;
1473
1458
        if (prefetch_len)
1474
1459
        {
1475
 
          memcpy((uchar*) to, block_info.header + offset, prefetch_len);
 
1460
          memcpy(to, block_info.header + offset, prefetch_len);
1476
1461
          block_info.data_len-= prefetch_len;
1477
1462
          left_length-= prefetch_len;
1478
1463
          to+= prefetch_len;
1490
1475
          there is no equivalent without seeking. We are at the right
1491
1476
          position already. :(
1492
1477
        */
1493
 
        if (info->s->file_read(info, (uchar*) to, block_info.data_len,
 
1478
        if (info->s->file_read(info, (unsigned char*) to, block_info.data_len,
1494
1479
                               filepos, MYF(MY_NABP)))
1495
1480
          goto panic;
1496
1481
        left_length-=block_info.data_len;
1501
1486
 
1502
1487
    info->update|= HA_STATE_AKTIV;      /* We have a aktive record */
1503
1488
    fast_mi_writeinfo(info);
1504
 
    DBUG_RETURN(_mi_rec_unpack(info,buf,info->rec_buff,block_info.rec_len) !=
 
1489
    return(_mi_rec_unpack(info,buf,info->rec_buff,block_info.rec_len) !=
1505
1490
                MY_FILE_ERROR ? 0 : -1);
1506
1491
  }
1507
1492
  fast_mi_writeinfo(info);
1508
 
  DBUG_RETURN(-1);                      /* Wrong data to read */
 
1493
  return(-1);                   /* Wrong data to read */
1509
1494
 
1510
1495
panic:
1511
1496
  my_errno=HA_ERR_WRONG_IN_RECORD;
1512
1497
err:
1513
 
  VOID(_mi_writeinfo(info,0));
1514
 
  DBUG_RETURN(-1);
 
1498
  _mi_writeinfo(info,0);
 
1499
  return(-1);
1515
1500
}
1516
1501
 
1517
1502
        /* compare unique constraint between stored rows */
1518
1503
 
1519
1504
int _mi_cmp_dynamic_unique(MI_INFO *info, MI_UNIQUEDEF *def,
1520
 
                           const uchar *record, my_off_t pos)
 
1505
                           const unsigned char *record, my_off_t pos)
1521
1506
{
1522
 
  uchar *rec_buff,*old_record;
 
1507
  unsigned char *rec_buff,*old_record;
1523
1508
  int error;
1524
 
  DBUG_ENTER("_mi_cmp_dynamic_unique");
1525
1509
 
1526
1510
  if (!(old_record=my_alloca(info->s->base.reclength)))
1527
 
    DBUG_RETURN(1);
 
1511
    return(1);
1528
1512
 
1529
1513
  /* Don't let the compare destroy blobs that may be in use */
1530
1514
  rec_buff=info->rec_buff;
1535
1519
    error=mi_unique_comp(def, record, old_record, def->null_are_equal);
1536
1520
  if (info->s->base.blobs)
1537
1521
  {
1538
 
    my_free(mi_get_rec_buff_ptr(info, info->rec_buff), MYF(MY_ALLOW_ZERO_PTR));
 
1522
    void * rec_buff_ptr= mi_get_rec_buff_ptr(info, info->rec_buff);
 
1523
    if (rec_buff_ptr != NULL)
 
1524
      free(rec_buff_ptr);
1539
1525
    info->rec_buff=rec_buff;
1540
1526
  }
1541
1527
  my_afree(old_record);
1542
 
  DBUG_RETURN(error);
 
1528
  return(error);
1543
1529
}
1544
1530
 
1545
1531
 
1546
1532
        /* Compare of record one disk with packed record in memory */
1547
1533
 
1548
 
int _mi_cmp_dynamic_record(register MI_INFO *info, register const uchar *record)
 
1534
int _mi_cmp_dynamic_record(register MI_INFO *info, register const unsigned char *record)
1549
1535
{
1550
 
  uint flag,reclength,b_type;
 
1536
  uint32_t flag,reclength,b_type;
1551
1537
  my_off_t filepos;
1552
 
  uchar *buffer;
 
1538
  unsigned char *buffer;
1553
1539
  MI_BLOCK_INFO block_info;
1554
 
  DBUG_ENTER("_mi_cmp_dynamic_record");
1555
1540
 
1556
1541
  if (info->opt_flag & WRITE_CACHE_USED)
1557
1542
  {
1558
1543
    info->update&= ~(HA_STATE_WRITE_AT_END | HA_STATE_EXTEND_BLOCK);
1559
1544
    if (flush_io_cache(&info->rec_cache))
1560
 
      DBUG_RETURN(-1);
 
1545
      return(-1);
1561
1546
  }
1562
1547
  info->rec_cache.seek_not_done=1;
1563
1548
 
1568
1553
  {                                             /* If check isn't disabled  */
1569
1554
    if (info->s->base.blobs)
1570
1555
    {
1571
 
      if (!(buffer=(uchar*) my_alloca(info->s->base.pack_reclength+
 
1556
      if (!(buffer=(unsigned char*) my_alloca(info->s->base.pack_reclength+
1572
1557
                                     _my_calc_total_blob_length(info,record))))
1573
 
        DBUG_RETURN(-1);
 
1558
        return(-1);
1574
1559
    }
1575
1560
    reclength=_mi_rec_pack(info,buffer,record);
1576
1561
    record= buffer;
1616
1601
  my_errno=0;
1617
1602
err:
1618
1603
  if (buffer != info->rec_buff)
1619
 
    my_afree((uchar*) buffer);
1620
 
  DBUG_RETURN(my_errno);
 
1604
    my_afree((unsigned char*) buffer);
 
1605
  return(my_errno);
1621
1606
}
1622
1607
 
1623
1608
 
1624
1609
        /* Compare file to buffert */
1625
1610
 
1626
 
static int _mi_cmp_buffer(File file, const uchar *buff, my_off_t filepos,
1627
 
                          uint length)
 
1611
static int _mi_cmp_buffer(File file, const unsigned char *buff, my_off_t filepos,
 
1612
                          uint32_t length)
1628
1613
{
1629
 
  uint next_length;
1630
 
  uchar temp_buff[IO_SIZE*2];
1631
 
  DBUG_ENTER("_mi_cmp_buffer");
 
1614
  uint32_t next_length;
 
1615
  unsigned char temp_buff[IO_SIZE*2];
1632
1616
 
1633
1617
  next_length= IO_SIZE*2 - (uint) (filepos & (IO_SIZE-1));
1634
1618
 
1644
1628
  }
1645
1629
  if (my_pread(file,temp_buff,length,filepos,MYF(MY_NABP)))
1646
1630
    goto err;
1647
 
  DBUG_RETURN(memcmp(buff,temp_buff,length));
 
1631
  return(memcmp(buff,temp_buff,length));
1648
1632
err:
1649
 
  DBUG_RETURN(1);
 
1633
  return(1);
1650
1634
}
1651
1635
 
1652
1636
 
1684
1668
    != 0        Error
1685
1669
*/
1686
1670
 
1687
 
int _mi_read_rnd_dynamic_record(MI_INFO *info, uchar *buf,
 
1671
int _mi_read_rnd_dynamic_record(MI_INFO *info, unsigned char *buf,
1688
1672
                                register my_off_t filepos,
1689
 
                                my_bool skip_deleted_blocks)
 
1673
                                bool skip_deleted_blocks)
1690
1674
{
1691
1675
  int block_of_record, info_read, save_errno;
1692
 
  uint left_len,b_type;
1693
 
  uchar *to= NULL;
 
1676
  uint32_t left_len,b_type;
 
1677
  unsigned char *to= NULL;
1694
1678
  MI_BLOCK_INFO block_info;
1695
1679
  MYISAM_SHARE *share=info->s;
1696
 
  DBUG_ENTER("_mi_read_rnd_dynamic_record");
1697
1680
 
1698
1681
  info_read=0;
1699
1682
 
1726
1709
    }
1727
1710
    if (info->opt_flag & READ_CACHE_USED)
1728
1711
    {
1729
 
      if (_mi_read_cache(&info->rec_cache,(uchar*) block_info.header,filepos,
 
1712
      if (_mi_read_cache(&info->rec_cache,(unsigned char*) block_info.header,filepos,
1730
1713
                         sizeof(block_info.header),
1731
1714
                         (!block_of_record && skip_deleted_blocks ?
1732
1715
                          READING_NEXT : 0) | READING_HEADER))
1738
1721
      if (info->opt_flag & WRITE_CACHE_USED &&
1739
1722
          info->rec_cache.pos_in_file < filepos + MI_BLOCK_INFO_HEADER_LENGTH &&
1740
1723
          flush_io_cache(&info->rec_cache))
1741
 
        DBUG_RETURN(my_errno);
 
1724
        return(my_errno);
1742
1725
      info->rec_cache.seek_not_done=1;
1743
1726
      b_type=_mi_get_block_info(&block_info,info->dfile,filepos);
1744
1727
    }
1781
1764
 
1782
1765
    /* copy information that is already read */
1783
1766
    {
1784
 
      uint offset=(uint) (block_info.filepos - filepos);
1785
 
      uint tmp_length= (sizeof(block_info.header) - offset);
 
1767
      uint32_t offset=(uint) (block_info.filepos - filepos);
 
1768
      uint32_t tmp_length= (sizeof(block_info.header) - offset);
1786
1769
      filepos=block_info.filepos;
1787
1770
 
1788
1771
      if (tmp_length > block_info.data_len)
1789
1772
        tmp_length= block_info.data_len;
1790
1773
      if (tmp_length)
1791
1774
      {
1792
 
        memcpy((uchar*) to, block_info.header+offset,tmp_length);
 
1775
        memcpy(to, block_info.header+offset,tmp_length);
1793
1776
        block_info.data_len-=tmp_length;
1794
1777
        left_len-=tmp_length;
1795
1778
        to+=tmp_length;
1801
1784
    {
1802
1785
      if (info->opt_flag & READ_CACHE_USED)
1803
1786
      {
1804
 
        if (_mi_read_cache(&info->rec_cache,(uchar*) to,filepos,
 
1787
        if (_mi_read_cache(&info->rec_cache,(unsigned char*) to,filepos,
1805
1788
                           block_info.data_len,
1806
1789
                           (!block_of_record && skip_deleted_blocks) ?
1807
1790
                           READING_NEXT : 0))
1814
1797
            block_info.filepos + block_info.data_len &&
1815
1798
            flush_io_cache(&info->rec_cache))
1816
1799
          goto err;
1817
 
        /* VOID(my_seek(info->dfile,filepos,MY_SEEK_SET,MYF(0))); */
1818
 
        if (my_read(info->dfile,(uchar*) to,block_info.data_len,MYF(MY_NABP)))
 
1800
        /* my_seek(info->dfile,filepos,MY_SEEK_SET,MYF(0)); */
 
1801
        if (my_read(info->dfile,(unsigned char*) to,block_info.data_len,MYF(MY_NABP)))
1819
1802
        {
1820
1803
          if (my_errno == -1)
1821
1804
            my_errno= HA_ERR_WRONG_IN_RECORD;   /* Unexpected end of file */
1841
1824
  fast_mi_writeinfo(info);
1842
1825
  if (_mi_rec_unpack(info,buf,info->rec_buff,block_info.rec_len) !=
1843
1826
      MY_FILE_ERROR)
1844
 
    DBUG_RETURN(0);
1845
 
  DBUG_RETURN(my_errno);                        /* Wrong record */
 
1827
    return(0);
 
1828
  return(my_errno);                     /* Wrong record */
1846
1829
 
1847
1830
panic:
1848
1831
  my_errno=HA_ERR_WRONG_IN_RECORD;              /* Something is fatal wrong */
1849
1832
err:
1850
1833
  save_errno=my_errno;
1851
 
  VOID(_mi_writeinfo(info,0));
1852
 
  DBUG_RETURN(my_errno=save_errno);
 
1834
  _mi_writeinfo(info,0);
 
1835
  return(my_errno=save_errno);
1853
1836
}
1854
1837
 
1855
1838
 
1856
1839
        /* Read and process header from a dynamic-record-file */
1857
1840
 
1858
 
uint _mi_get_block_info(MI_BLOCK_INFO *info, File file, my_off_t filepos)
 
1841
uint32_t _mi_get_block_info(MI_BLOCK_INFO *info, File file, my_off_t filepos)
1859
1842
{
1860
 
  uint return_val=0;
1861
 
  uchar *header=info->header;
 
1843
  uint32_t return_val=0;
 
1844
  unsigned char *header=info->header;
1862
1845
 
1863
1846
  if (file >= 0)
1864
1847
  {
1867
1850
      pointer set to the end of the header after this function.
1868
1851
      my_pread() may leave the file pointer untouched.
1869
1852
    */
1870
 
    VOID(my_seek(file,filepos,MY_SEEK_SET,MYF(0)));
 
1853
    my_seek(file,filepos,MY_SEEK_SET,MYF(0));
1871
1854
    if (my_read(file, header, sizeof(info->header),MYF(0)) !=
1872
1855
        sizeof(info->header))
1873
1856
      goto err;
1874
1857
  }
1875
 
  DBUG_DUMP("header",header,MI_BLOCK_INFO_HEADER_LENGTH);
1876
1858
  if (info->second_read)
1877
1859
  {
1878
1860
    if (info->header[0] <= 6 || info->header[0] == 13)
1896
1878
    info->prev_filepos=mi_sizekorr(header+12);
1897
1879
#if SIZEOF_OFF_T == 4
1898
1880
    if ((mi_uint4korr(header+4) != 0 &&
1899
 
         (mi_uint4korr(header+4) != (ulong) ~0 ||
1900
 
          info->next_filepos != (ulong) ~0)) ||
 
1881
         (mi_uint4korr(header+4) != UINT32_MAX ||
 
1882
          info->next_filepos != UINT32_MAX) ||
1901
1883
        (mi_uint4korr(header+12) != 0 &&
1902
 
         (mi_uint4korr(header+12) != (ulong) ~0 ||
1903
 
          info->prev_filepos != (ulong) ~0)))
 
1884
         (mi_uint4korr(header+12) != UINT32_MAX ||
 
1885
          info->prev_filepos != UINT32_MAX))
1904
1886
      goto err;
1905
1887
#endif
1906
1888
    return return_val | BLOCK_DELETED;          /* Deleted block */