~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to storage/archive/ha_archive.cc

  • Committer: Brian Aker
  • Date: 2008-11-04 15:39:09 UTC
  • mfrom: (575.1.2 devel)
  • Revision ID: brian@tangent.org-20081104153909-c72hn65udxs1ccal
Merge of Monty's work

Show diffs side-by-side

added added

removed removed

Lines of Context:
13
13
  along with this program; if not, write to the Free Software
14
14
  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
15
15
 
16
 
#ifdef USE_PRAGMA_IMPLEMENTATION
17
 
#pragma implementation        // gcc: Class implementation
18
 
#endif
19
16
 
20
17
#include <drizzled/common_includes.h>
21
18
#include <storage/myisam/myisam.h>
98
95
/* The file extension */
99
96
#define ARZ ".ARZ"               // The data file
100
97
#define ARN ".ARN"               // Files used during an optimize call
101
 
#define ARM ".ARM"               // Meta file (deprecated)
102
98
 
103
 
/*
104
 
  uchar + uchar
105
 
*/
106
 
#define DATA_BUFFER_SIZE 2       // Size of the data used in the data file
107
 
#define ARCHIVE_CHECK_HEADER 254 // The number we use to determine corruption
108
99
 
109
100
/* Static declarations for handerton */
110
101
static handler *archive_create_handler(handlerton *hton, 
111
102
                                       TABLE_SHARE *table, 
112
103
                                       MEM_ROOT *mem_root);
113
 
int archive_discover(handlerton *hton, THD* thd, const char *db, 
 
104
int archive_discover(handlerton *hton, Session* session, const char *db, 
114
105
                     const char *name,
115
 
                     uchar **frmblob, 
 
106
                     unsigned char **frmblob, 
116
107
                     size_t *frmlen);
117
108
 
118
109
static bool archive_use_aio= false;
137
128
/*
138
129
  Used for hash table that tracks open tables.
139
130
*/
140
 
static uchar* archive_get_key(ARCHIVE_SHARE *share, size_t *length,
 
131
static unsigned char* archive_get_key(ARCHIVE_SHARE *share, size_t *length,
141
132
                             bool not_used __attribute__((unused)))
142
133
{
143
134
  *length=share->table_name_length;
144
 
  return (uchar*) share->table_name;
 
135
  return (unsigned char*) share->table_name;
145
136
}
146
137
 
147
138
 
163
154
 
164
155
  archive_hton= (handlerton *)p;
165
156
  archive_hton->state= SHOW_OPTION_YES;
166
 
  archive_hton->db_type= DB_TYPE_ARCHIVE_DB;
167
157
  archive_hton->create= archive_create_handler;
168
158
  archive_hton->flags= HTON_NO_FLAGS;
169
159
  archive_hton->discover= archive_discover;
176
166
  if (hash_init(&archive_open_tables, system_charset_info, 32, 0, 0,
177
167
                (hash_get_key) archive_get_key, 0, 0))
178
168
  {
179
 
    VOID(pthread_mutex_destroy(&archive_mutex));
 
169
    pthread_mutex_destroy(&archive_mutex);
180
170
  }
181
171
  else
182
172
  {
200
190
int archive_db_done(void *p __attribute__((unused)))
201
191
{
202
192
  hash_free(&archive_open_tables);
203
 
  VOID(pthread_mutex_destroy(&archive_mutex));
 
193
  pthread_mutex_destroy(&archive_mutex);
204
194
 
205
195
  return 0;
206
196
}
218
208
}
219
209
 
220
210
int archive_discover(handlerton *hton __attribute__((unused)),
221
 
                     THD* thd __attribute__((unused)),
 
211
                     Session* session __attribute__((unused)),
222
212
                     const char *db,
223
213
                     const char *name,
224
 
                     uchar **frmblob,
 
214
                     unsigned char **frmblob,
225
215
                     size_t *frmlen)
226
216
{
227
217
  azio_stream frm_stream;
234
224
  if (stat(az_file, &file_stat))
235
225
    goto err;
236
226
 
237
 
  if (!(azopen(&frm_stream, az_file, O_RDONLY|O_BINARY, AZ_METHOD_BLOCK)))
 
227
  if (!(azopen(&frm_stream, az_file, O_RDONLY, AZ_METHOD_BLOCK)))
238
228
  {
239
229
    if (errno == EROFS || errno == EACCES)
240
230
      return(my_errno= errno);
249
239
  azclose(&frm_stream);
250
240
 
251
241
  *frmlen= frm_stream.frm_length;
252
 
  *frmblob= (uchar*) frm_ptr;
 
242
  *frmblob= (unsigned char*) frm_ptr;
253
243
 
254
244
  return(0);
255
245
err:
281
271
*/
282
272
ARCHIVE_SHARE *ha_archive::get_share(const char *table_name, int *rc)
283
273
{
284
 
  uint length;
 
274
  uint32_t length;
285
275
 
286
276
  pthread_mutex_lock(&archive_mutex);
287
277
  length=(uint) strlen(table_name);
288
278
 
289
279
  if (!(share=(ARCHIVE_SHARE*) hash_search(&archive_open_tables,
290
 
                                           (uchar*) table_name,
 
280
                                           (unsigned char*) table_name,
291
281
                                           length)))
292
282
  {
293
283
    char *tmp_name;
296
286
    if (!my_multi_malloc(MYF(MY_WME | MY_ZEROFILL),
297
287
                          &share, sizeof(*share),
298
288
                          &tmp_name, length+1,
299
 
                          NullS)) 
 
289
                          NULL)) 
300
290
    {
301
291
      pthread_mutex_unlock(&archive_mutex);
302
292
      *rc= HA_ERR_OUT_OF_MEM;
310
300
    share->archive_write_open= false;
311
301
    fn_format(share->data_file_name, table_name, "",
312
302
              ARZ, MY_REPLACE_EXT | MY_UNPACK_FILENAME);
313
 
    stpcpy(share->table_name, table_name);
 
303
    my_stpcpy(share->table_name, table_name);
314
304
    /*
315
305
      We will use this lock for rows.
316
306
    */
317
 
    VOID(pthread_mutex_init(&share->mutex,MY_MUTEX_INIT_FAST));
 
307
    pthread_mutex_init(&share->mutex,MY_MUTEX_INIT_FAST);
318
308
    
319
309
    /*
320
310
      We read the meta file, but do not mark it dirty. Since we are not
322
312
      anything but reading... open it for write and we will generate null
323
313
      compression writes).
324
314
    */
325
 
    if (!(azopen(&archive_tmp, share->data_file_name, O_RDONLY|O_BINARY,
 
315
    if (!(azopen(&archive_tmp, share->data_file_name, O_RDONLY,
326
316
                 AZ_METHOD_BLOCK)))
327
317
    {
328
 
      VOID(pthread_mutex_destroy(&share->mutex));
 
318
      pthread_mutex_destroy(&share->mutex);
329
319
      free(share);
330
320
      pthread_mutex_unlock(&archive_mutex);
331
321
      *rc= HA_ERR_CRASHED_ON_REPAIR;
341
331
    }
342
332
    azclose(&archive_tmp);
343
333
 
344
 
    VOID(my_hash_insert(&archive_open_tables, (uchar*) share));
 
334
    my_hash_insert(&archive_open_tables, (unsigned char*) share);
345
335
    thr_lock_init(&share->lock);
346
336
  }
347
337
  share->use_count++;
364
354
  pthread_mutex_lock(&archive_mutex);
365
355
  if (!--share->use_count)
366
356
  {
367
 
    hash_delete(&archive_open_tables, (uchar*) share);
 
357
    hash_delete(&archive_open_tables, (unsigned char*) share);
368
358
    thr_lock_delete(&share->lock);
369
 
    VOID(pthread_mutex_destroy(&share->mutex));
 
359
    pthread_mutex_destroy(&share->mutex);
370
360
    /* 
371
361
      We need to make sure we don't reset the crashed state.
372
362
      If we open a crashed file, wee need to close it as crashed unless
379
369
      if (azclose(&(share->archive_write)))
380
370
        rc= 1;
381
371
    }
382
 
    my_free((uchar*) share, MYF(0));
 
372
    free((unsigned char*) share);
383
373
  }
384
374
  pthread_mutex_unlock(&archive_mutex);
385
375
 
394
384
    that is shared amoung all open tables.
395
385
  */
396
386
  if (!(azopen(&(share->archive_write), share->data_file_name, 
397
 
               O_RDWR|O_BINARY, AZ_METHOD_BLOCK)))
 
387
               O_RDWR, AZ_METHOD_BLOCK)))
398
388
  {
399
389
    share->crashed= true;
400
390
    return(1);
430
420
    default:
431
421
      method= AZ_METHOD_BLOCK;
432
422
    }
433
 
    if (!(azopen(&archive, share->data_file_name, O_RDONLY|O_BINARY, 
 
423
    if (!(azopen(&archive, share->data_file_name, O_RDONLY, 
434
424
                 method)))
435
425
    {
436
426
      share->crashed= true;
448
438
*/
449
439
static const char *ha_archive_exts[] = {
450
440
  ARZ,
451
 
  NullS
 
441
  NULL
452
442
};
453
443
 
454
444
const char **ha_archive::bas_ext() const
465
455
*/
466
456
int ha_archive::open(const char *name,
467
457
                     int mode __attribute__((unused)),
468
 
                     uint open_options)
 
458
                     uint32_t open_options)
469
459
{
470
460
  int rc= 0;
471
461
  share= get_share(name, &rc);
558
548
  azio_stream create_stream;            /* Archive file we are working with */
559
549
  File frm_file;                   /* File handler for readers */
560
550
  struct stat file_stat;
561
 
  uchar *frm_ptr;
 
551
  unsigned char *frm_ptr;
562
552
 
563
553
  stats.auto_increment_value= create_info->auto_increment_value;
564
554
 
565
 
  for (uint key= 0; key < table_arg->sizeKeys(); key++)
 
555
  for (uint32_t key= 0; key < table_arg->sizeKeys(); key++)
566
556
  {
567
557
    KEY *pos= table_arg->key_info+key;
568
558
    KEY_PART_INFO *key_part=     pos->key_part;
604
594
  if (!stat(name_buff, &file_stat))
605
595
  {
606
596
    my_errno= 0;
607
 
    if (!(azopen(&create_stream, name_buff, O_CREAT|O_RDWR|O_BINARY,
 
597
    if (!(azopen(&create_stream, name_buff, O_CREAT|O_RDWR,
608
598
                 AZ_METHOD_BLOCK)))
609
599
    {
610
600
      error= errno;
623
613
    {
624
614
      if (fstat(frm_file, &file_stat))
625
615
      {
626
 
        frm_ptr= (uchar *)my_malloc(sizeof(uchar) * file_stat.st_size, MYF(0));
 
616
        frm_ptr= (unsigned char *)my_malloc(sizeof(unsigned char) * file_stat.st_size, MYF(0));
627
617
        if (frm_ptr)
628
618
        {
629
619
          my_read(frm_file, frm_ptr, file_stat.st_size, MYF(0));
630
620
          azwrite_frm(&create_stream, (char *)frm_ptr, file_stat.st_size);
631
 
          my_free((uchar*)frm_ptr, MYF(0));
 
621
          free((unsigned char*)frm_ptr);
632
622
        }
633
623
      }
634
624
      my_close(frm_file, MYF(0));
665
655
/*
666
656
  This is where the actual row is written out.
667
657
*/
668
 
int ha_archive::real_write_row(uchar *buf, azio_stream *writer)
 
658
int ha_archive::real_write_row(unsigned char *buf, azio_stream *writer)
669
659
{
670
660
  my_off_t written;
671
661
  unsigned int r_pack_length;
691
681
  the bytes required for the length in the header.
692
682
*/
693
683
 
694
 
uint32_t ha_archive::max_row_length(const uchar *buf __attribute__((unused)))
 
684
uint32_t ha_archive::max_row_length(const unsigned char *buf __attribute__((unused)))
695
685
{
696
686
  uint32_t length= (uint32_t)(table->getRecordLength() + table->sizeFields()*2);
697
687
  length+= ARCHIVE_ROW_HEADER_SIZE;
698
688
 
699
 
  uint *ptr, *end;
 
689
  uint32_t *ptr, *end;
700
690
  for (ptr= table->getBlobField(), end=ptr + table->sizeBlobFields();
701
691
       ptr != end ;
702
692
       ptr++)
708
698
}
709
699
 
710
700
 
711
 
unsigned int ha_archive::pack_row(uchar *record)
 
701
unsigned int ha_archive::pack_row(unsigned char *record)
712
702
{
713
 
  uchar *ptr;
 
703
  unsigned char *ptr;
714
704
 
715
705
  if (fix_rec_buff(max_row_length(record)))
716
706
    return(HA_ERR_OUT_OF_MEM); /* purecov: inspected */
738
728
  for implementing start_bulk_insert() is that we could skip 
739
729
  setting dirty to true each time.
740
730
*/
741
 
int ha_archive::write_row(uchar *buf)
 
731
int ha_archive::write_row(unsigned char *buf)
742
732
{
743
733
  int rc;
744
 
  uchar *read_buf= NULL;
 
734
  unsigned char *read_buf= NULL;
745
735
  uint64_t temp_auto;
746
 
  uchar *record=  table->record[0];
 
736
  unsigned char *record=  table->record[0];
747
737
 
748
738
  if (share->crashed)
749
739
    return(HA_ERR_CRASHED_ON_USAGE);
786
776
        First we create a buffer that we can use for reading rows, and can pass
787
777
        to get_row().
788
778
      */
789
 
      if (!(read_buf= (uchar*) my_malloc(table->s->reclength, MYF(MY_WME))))
 
779
      if (!(read_buf= (unsigned char*) my_malloc(table->s->reclength, MYF(MY_WME))))
790
780
      {
791
781
        rc= HA_ERR_OUT_OF_MEM;
792
782
        goto error;
836
826
error:
837
827
  pthread_mutex_unlock(&share->mutex);
838
828
  if (read_buf)
839
 
    my_free((uchar*) read_buf, MYF(0));
 
829
    free((unsigned char*) read_buf);
840
830
 
841
831
  return(rc);
842
832
}
853
843
}
854
844
 
855
845
/* Initialized at each key walk (called multiple times unlike rnd_init()) */
856
 
int ha_archive::index_init(uint keynr, bool sorted __attribute__((unused)))
 
846
int ha_archive::index_init(uint32_t keynr, bool sorted __attribute__((unused)))
857
847
{
858
848
  active_index= keynr;
859
849
  return(0);
864
854
  No indexes, so if we get a request for an index search since we tell
865
855
  the optimizer that we have unique indexes, we scan
866
856
*/
867
 
int ha_archive::index_read(uchar *buf, const uchar *key,
868
 
                             uint key_len, enum ha_rkey_function find_flag)
 
857
int ha_archive::index_read(unsigned char *buf, const unsigned char *key,
 
858
                             uint32_t key_len, enum ha_rkey_function find_flag)
869
859
{
870
860
  int rc;
871
861
  rc= index_read_idx(buf, active_index, key, key_len, find_flag);
873
863
}
874
864
 
875
865
 
876
 
int ha_archive::index_read_idx(uchar *buf, uint index, const uchar *key,
877
 
                               uint key_len,
 
866
int ha_archive::index_read_idx(unsigned char *buf, uint32_t index, const unsigned char *key,
 
867
                               uint32_t key_len,
878
868
                               enum ha_rkey_function find_flag __attribute__((unused)))
879
869
{
880
870
  int rc;
906
896
}
907
897
 
908
898
 
909
 
int ha_archive::index_next(uchar * buf) 
 
899
int ha_archive::index_next(unsigned char * buf) 
910
900
911
901
  bool found= 0;
912
902
 
950
940
  This is the method that is used to read a row. It assumes that the row is 
951
941
  positioned where you want it.
952
942
*/
953
 
int ha_archive::get_row(azio_stream *file_to_read, uchar *buf)
 
943
int ha_archive::get_row(azio_stream *file_to_read, unsigned char *buf)
954
944
{
955
945
  int rc;
956
946
 
969
959
 
970
960
  if (length > record_buffer->length)
971
961
  {
972
 
    uchar *newptr;
973
 
    if (!(newptr=(uchar*) my_realloc((uchar*) record_buffer->buffer, 
 
962
    unsigned char *newptr;
 
963
    if (!(newptr=(unsigned char*) my_realloc((unsigned char*) record_buffer->buffer, 
974
964
                                    length,
975
965
                                    MYF(MY_ALLOW_ZERO_PTR))))
976
966
      return(1);
983
973
  return(0);
984
974
}
985
975
 
986
 
int ha_archive::unpack_row(azio_stream *file_to_read, uchar *record)
 
976
int ha_archive::unpack_row(azio_stream *file_to_read, unsigned char *record)
987
977
{
988
978
  unsigned int read;
989
979
  int error;
990
 
  const uchar *ptr;
 
980
  const unsigned char *ptr;
991
981
 
992
982
  read= azread_row(file_to_read, &error);
993
 
  ptr= (const uchar *)file_to_read->row_ptr;
 
983
  ptr= (const unsigned char *)file_to_read->row_ptr;
994
984
 
995
985
  if (error || read == 0)
996
986
  {
1011
1001
}
1012
1002
 
1013
1003
 
1014
 
int ha_archive::get_row_version3(azio_stream *file_to_read, uchar *buf)
 
1004
int ha_archive::get_row_version3(azio_stream *file_to_read, unsigned char *buf)
1015
1005
{
1016
1006
  int returnable= unpack_row(file_to_read, buf);
1017
1007
 
1024
1014
  or by having had ha_archive::rnd_pos() called before it is called.
1025
1015
*/
1026
1016
 
1027
 
int ha_archive::rnd_next(uchar *buf)
 
1017
int ha_archive::rnd_next(unsigned char *buf)
1028
1018
{
1029
1019
  int rc;
1030
1020
 
1051
1041
  needed.
1052
1042
*/
1053
1043
 
1054
 
void ha_archive::position(const uchar *record __attribute__((unused)))
 
1044
void ha_archive::position(const unsigned char *record __attribute__((unused)))
1055
1045
{
1056
1046
  my_store_ptr(ref, ref_length, current_position);
1057
1047
  return;
1065
1055
  correctly ordered row.
1066
1056
*/
1067
1057
 
1068
 
int ha_archive::rnd_pos(uchar * buf, uchar *pos)
 
1058
int ha_archive::rnd_pos(unsigned char * buf, unsigned char *pos)
1069
1059
{
1070
1060
  ha_statistic_increment(&SSV::ha_read_rnd_next_count);
1071
1061
  current_position= (my_off_t)my_get_ptr(pos, ref_length);
1079
1069
  rewriting the meta file. Currently it does this by calling optimize with
1080
1070
  the extended flag.
1081
1071
*/
1082
 
int ha_archive::repair(THD* thd, HA_CHECK_OPT* check_opt)
 
1072
int ha_archive::repair(Session* session, HA_CHECK_OPT* check_opt)
1083
1073
{
1084
1074
  check_opt->flags= T_EXTEND;
1085
 
  int rc= optimize(thd, check_opt);
 
1075
  int rc= optimize(session, check_opt);
1086
1076
 
1087
1077
  if (rc)
1088
1078
    return(HA_ERR_CRASHED_ON_REPAIR);
1095
1085
  The table can become fragmented if data was inserted, read, and then
1096
1086
  inserted again. What we do is open up the file and recompress it completely. 
1097
1087
*/
1098
 
int ha_archive::optimize(THD* thd __attribute__((unused)),
 
1088
int ha_archive::optimize(Session* session __attribute__((unused)),
1099
1089
                         HA_CHECK_OPT* check_opt __attribute__((unused)))
1100
1090
{
1101
1091
  int rc= 0;
1115
1105
  fn_format(writer_filename, share->table_name, "", ARN, 
1116
1106
            MY_REPLACE_EXT | MY_UNPACK_FILENAME);
1117
1107
 
1118
 
  if (!(azopen(&writer, writer_filename, O_CREAT|O_RDWR|O_BINARY, AZ_METHOD_BLOCK)))
 
1108
  if (!(azopen(&writer, writer_filename, O_CREAT|O_RDWR, AZ_METHOD_BLOCK)))
1119
1109
    return(HA_ERR_CRASHED_ON_USAGE); 
1120
1110
 
1121
1111
  /* 
1199
1189
/* 
1200
1190
  Below is an example of how to setup row level locking.
1201
1191
*/
1202
 
THR_LOCK_DATA **ha_archive::store_lock(THD *thd,
 
1192
THR_LOCK_DATA **ha_archive::store_lock(Session *session,
1203
1193
                                       THR_LOCK_DATA **to,
1204
1194
                                       enum thr_lock_type lock_type)
1205
1195
{
1218
1208
    */
1219
1209
 
1220
1210
    if ((lock_type >= TL_WRITE_CONCURRENT_INSERT &&
1221
 
         lock_type <= TL_WRITE) && !thd_in_lock_tables(thd)
1222
 
        && !thd_tablespace_op(thd))
 
1211
         lock_type <= TL_WRITE) && !session_in_lock_tables(session)
 
1212
        && !session_tablespace_op(session))
1223
1213
      lock_type = TL_WRITE_ALLOW_WRITE;
1224
1214
 
1225
1215
    /* 
1230
1220
      concurrent inserts to t2. 
1231
1221
    */
1232
1222
 
1233
 
    if (lock_type == TL_READ_NO_INSERT && !thd_in_lock_tables(thd)) 
 
1223
    if (lock_type == TL_READ_NO_INSERT && !session_in_lock_tables(session)) 
1234
1224
      lock_type = TL_READ;
1235
1225
 
1236
1226
    lock.type=lock_type;
1259
1249
/*
1260
1250
  Hints for optimizer, see ha_tina for more information
1261
1251
*/
1262
 
int ha_archive::info(uint flag)
 
1252
int ha_archive::info(uint32_t flag)
1263
1253
{
1264
1254
  /* 
1265
1255
    If dirty, we lock, and then reset/flush the data.
1294
1284
  {
1295
1285
    struct stat file_stat;  // Stat information for the data file
1296
1286
 
1297
 
    VOID(stat(share->data_file_name, &file_stat));
 
1287
    stat(share->data_file_name, &file_stat);
1298
1288
 
1299
1289
    stats.mean_rec_length= table->getRecordLength()+ buffer.alloced_length();
1300
1290
    stats.data_file_length= file_stat.st_size;
1365
1355
  Simple scan of the tables to make sure everything is ok.
1366
1356
*/
1367
1357
 
1368
 
int ha_archive::check(THD* thd,
 
1358
int ha_archive::check(Session* session,
1369
1359
                      HA_CHECK_OPT* check_opt __attribute__((unused)))
1370
1360
{
1371
1361
  int rc= 0;
1372
1362
  const char *old_proc_info;
1373
1363
  uint64_t x;
1374
1364
 
1375
 
  old_proc_info= thd_proc_info(thd, "Checking table");
 
1365
  old_proc_info= get_session_proc_info(session);
 
1366
  set_session_proc_info(session, "Checking table");
1376
1367
  /* Flush any waiting data */
1377
1368
  pthread_mutex_lock(&share->mutex);
1378
1369
  azflush(&(share->archive_write), Z_SYNC_FLUSH);
1393
1384
      break;
1394
1385
  }
1395
1386
 
1396
 
  thd_proc_info(thd, old_proc_info);
 
1387
  set_session_proc_info(session, old_proc_info);
1397
1388
 
1398
1389
  if ((rc && rc != HA_ERR_END_OF_FILE))  
1399
1390
  {
1409
1400
/*
1410
1401
  Check and repair the table if needed.
1411
1402
*/
1412
 
bool ha_archive::check_and_repair(THD *thd) 
 
1403
bool ha_archive::check_and_repair(Session *session) 
1413
1404
{
1414
1405
  HA_CHECK_OPT check_opt;
1415
1406
 
1416
1407
  check_opt.init();
1417
1408
 
1418
 
  return(repair(thd, &check_opt));
 
1409
  return(repair(session, &check_opt));
1419
1410
}
1420
1411
 
1421
1412
archive_record_buffer *ha_archive::create_record_buffer(unsigned int length) 
1429
1420
  }
1430
1421
  r->length= (int)length;
1431
1422
 
1432
 
  if (!(r->buffer= (uchar*) my_malloc(r->length,
 
1423
  if (!(r->buffer= (unsigned char*) my_malloc(r->length,
1433
1424
                                    MYF(MY_WME))))
1434
1425
  {
1435
 
    my_free((char*) r, MYF(MY_ALLOW_ZERO_PTR));
 
1426
    free((char*) r);
1436
1427
    return(NULL); /* purecov: inspected */
1437
1428
  }
1438
1429
 
1441
1432
 
1442
1433
void ha_archive::destroy_record_buffer(archive_record_buffer *r) 
1443
1434
{
1444
 
  my_free((char*) r->buffer, MYF(MY_ALLOW_ZERO_PTR));
1445
 
  my_free((char*) r, MYF(MY_ALLOW_ZERO_PTR));
 
1435
  free((char*) r->buffer);
 
1436
  free((char*) r);
1446
1437
  return;
1447
1438
}
1448
1439