~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to storage/csv/ha_tina.cc

  • Committer: Jay Pipes
  • Date: 2008-07-17 18:48:58 UTC
  • mto: This revision was merged to the branch mainline in revision 182.
  • Revision ID: jay@mysql.com-20080717184858-2mbouxl8xi41gcge
Removed DBUG from CSV and Blackhole storage engines

Show diffs side-by-side

added added

removed removed

Lines of Context:
239
239
  uchar meta_buffer[META_BUFFER_SIZE];
240
240
  uchar *ptr= meta_buffer;
241
241
 
242
 
  DBUG_ENTER("ha_tina::read_meta_file");
243
 
 
244
242
  VOID(my_seek(meta_file, 0, MY_SEEK_SET, MYF(0)));
245
243
  if (my_read(meta_file, (uchar*)meta_buffer, META_BUFFER_SIZE, 0)
246
244
      != META_BUFFER_SIZE)
247
 
    DBUG_RETURN(HA_ERR_CRASHED_ON_USAGE);
 
245
    return(HA_ERR_CRASHED_ON_USAGE);
248
246
 
249
247
  /*
250
248
    Parse out the meta data, we ignore version at the moment
262
260
  /* check crashed bit and magic number */
263
261
  if ((meta_buffer[0] != (uchar)TINA_CHECK_HEADER) ||
264
262
      ((bool)(*ptr)== true))
265
 
    DBUG_RETURN(HA_ERR_CRASHED_ON_USAGE);
 
263
    return(HA_ERR_CRASHED_ON_USAGE);
266
264
 
267
265
  my_sync(meta_file, MYF(MY_WME));
268
266
 
269
 
  DBUG_RETURN(0);
 
267
  return(0);
270
268
}
271
269
 
272
270
 
294
292
  uchar meta_buffer[META_BUFFER_SIZE];
295
293
  uchar *ptr= meta_buffer;
296
294
 
297
 
  DBUG_ENTER("ha_tina::write_meta_file");
298
 
 
299
295
  *ptr= (uchar)TINA_CHECK_HEADER;
300
296
  ptr+= sizeof(uchar);
301
297
  *ptr= (uchar)TINA_VERSION;
313
309
  VOID(my_seek(meta_file, 0, MY_SEEK_SET, MYF(0)));
314
310
  if (my_write(meta_file, (uchar *)meta_buffer, META_BUFFER_SIZE, 0)
315
311
      != META_BUFFER_SIZE)
316
 
    DBUG_RETURN(-1);
 
312
    return(-1);
317
313
 
318
314
  my_sync(meta_file, MYF(MY_WME));
319
315
 
320
 
  DBUG_RETURN(0);
 
316
  return(0);
321
317
}
322
318
 
323
319
bool ha_tina::check_and_repair(THD *thd)
324
320
{
325
321
  HA_CHECK_OPT check_opt;
326
 
  DBUG_ENTER("ha_tina::check_and_repair");
327
322
 
328
323
  check_opt.init();
329
324
 
330
 
  DBUG_RETURN(repair(thd, &check_opt));
 
325
  return(repair(thd, &check_opt));
331
326
}
332
327
 
333
328
 
334
329
int ha_tina::init_tina_writer()
335
330
{
336
 
  DBUG_ENTER("ha_tina::init_tina_writer");
337
 
 
338
331
  /*
339
332
    Mark the file as crashed. We will set the flag back when we close
340
333
    the file. In the case of the crash it will remain marked crashed,
345
338
  if ((share->tina_write_filedes=
346
339
        my_open(share->data_file_name, O_RDWR|O_APPEND, MYF(0))) == -1)
347
340
  {
348
 
    DBUG_PRINT("info", ("Could not open tina file writes"));
349
341
    share->crashed= true;
350
 
    DBUG_RETURN(1);
 
342
    return(1);
351
343
  }
352
344
  share->tina_write_opened= true;
353
345
 
354
 
  DBUG_RETURN(0);
 
346
  return(0);
355
347
}
356
348
 
357
349
 
358
350
bool ha_tina::is_crashed() const
359
351
{
360
 
  DBUG_ENTER("ha_tina::is_crashed");
361
 
  DBUG_RETURN(share->crashed);
 
352
  return(share->crashed);
362
353
}
363
354
 
364
355
/*
366
357
*/
367
358
static int free_share(TINA_SHARE *share)
368
359
{
369
 
  DBUG_ENTER("ha_tina::free_share");
370
360
  pthread_mutex_lock(&tina_mutex);
371
361
  int result_code= 0;
372
362
  if (!--share->use_count){
389
379
  }
390
380
  pthread_mutex_unlock(&tina_mutex);
391
381
 
392
 
  DBUG_RETURN(result_code);
 
382
  return(result_code);
393
383
}
394
384
 
395
385
 
597
587
  my_bitmap_map *org_bitmap;
598
588
  int error;
599
589
  bool read_all;
600
 
  DBUG_ENTER("ha_tina::find_current_row");
601
590
 
602
591
  free_root(&blobroot, MYF(MY_MARK_BLOCKS_FREE));
603
592
 
608
597
  if ((end_offset=
609
598
        find_eoln_buff(file_buff, current_position,
610
599
                       local_saved_data_file_length, &eoln_len)) == 0)
611
 
    DBUG_RETURN(HA_ERR_END_OF_FILE);
 
600
    return(HA_ERR_END_OF_FILE);
612
601
 
613
602
  /* We must read all columns in case a table is opened for update */
614
603
  read_all= !bitmap_is_clear_all(table->write_set);
712
701
err:
713
702
  dbug_tmp_restore_column_map(table->write_set, org_bitmap);
714
703
 
715
 
  DBUG_RETURN(error);
 
704
  return(error);
716
705
}
717
706
 
718
707
/*
819
808
int ha_tina::open(const char *name, int mode __attribute__((__unused__)),
820
809
                  uint open_options)
821
810
{
822
 
  DBUG_ENTER("ha_tina::open");
823
 
 
824
811
  if (!(share= get_share(name, table)))
825
 
    DBUG_RETURN(HA_ERR_OUT_OF_MEM);
 
812
    return(HA_ERR_OUT_OF_MEM);
826
813
 
827
814
  if (share->crashed && !(open_options & HA_OPEN_FOR_REPAIR))
828
815
  {
829
816
    free_share(share);
830
 
    DBUG_RETURN(HA_ERR_CRASHED_ON_USAGE);
 
817
    return(HA_ERR_CRASHED_ON_USAGE);
831
818
  }
832
819
 
833
820
  local_data_file_version= share->data_file_version;
834
821
  if ((data_file= my_open(share->data_file_name, O_RDONLY, MYF(0))) == -1)
835
 
    DBUG_RETURN(0);
 
822
    return(0);
836
823
 
837
824
  /*
838
825
    Init locking. Pass handler object to the locking routines,
846
833
  share->lock.update_status= tina_update_status;
847
834
  share->lock.check_status= tina_check_status;
848
835
 
849
 
  DBUG_RETURN(0);
 
836
  return(0);
850
837
}
851
838
 
852
839
 
857
844
int ha_tina::close(void)
858
845
{
859
846
  int rc= 0;
860
 
  DBUG_ENTER("ha_tina::close");
861
847
  rc= my_close(data_file, MYF(0));
862
 
  DBUG_RETURN(free_share(share) || rc);
 
848
  return(free_share(share) || rc);
863
849
}
864
850
 
865
851
/*
870
856
int ha_tina::write_row(uchar * buf)
871
857
{
872
858
  int size;
873
 
  DBUG_ENTER("ha_tina::write_row");
874
859
 
875
860
  if (share->crashed)
876
 
      DBUG_RETURN(HA_ERR_CRASHED_ON_USAGE);
 
861
      return(HA_ERR_CRASHED_ON_USAGE);
877
862
 
878
863
  ha_statistic_increment(&SSV::ha_write_count);
879
864
 
884
869
 
885
870
  if (!share->tina_write_opened)
886
871
    if (init_tina_writer())
887
 
      DBUG_RETURN(-1);
 
872
      return(-1);
888
873
 
889
874
   /* use pwrite, as concurrent reader could have changed the position */
890
875
  if (my_write(share->tina_write_filedes, (uchar*)buffer.ptr(), size,
891
876
               MYF(MY_WME | MY_NABP)))
892
 
    DBUG_RETURN(-1);
 
877
    return(-1);
893
878
 
894
879
  /* update local copy of the max position to see our own changes */
895
880
  local_saved_data_file_length+= size;
903
888
  pthread_mutex_unlock(&share->mutex);
904
889
 
905
890
  stats.records++;
906
 
  DBUG_RETURN(0);
 
891
  return(0);
907
892
}
908
893
 
909
894
 
938
923
{
939
924
  int size;
940
925
  int rc= -1;
941
 
  DBUG_ENTER("ha_tina::update_row");
942
926
 
943
927
  ha_statistic_increment(&SSV::ha_update_count);
944
928
 
967
951
  rc= 0;
968
952
 
969
953
  /* UPDATE should never happen on the log tables */
970
 
  DBUG_ASSERT(!share->is_log_table);
 
954
  assert(!share->is_log_table);
971
955
 
972
956
err:
973
 
  DBUG_PRINT("info",("rc = %d", rc));
974
 
  DBUG_RETURN(rc);
 
957
  return(rc);
975
958
}
976
959
 
977
960
 
986
969
*/
987
970
int ha_tina::delete_row(const uchar * buf __attribute__((__unused__)))
988
971
{
989
 
  DBUG_ENTER("ha_tina::delete_row");
990
972
  ha_statistic_increment(&SSV::ha_delete_count);
991
973
 
992
974
  if (chain_append())
993
 
    DBUG_RETURN(-1);
 
975
    return(-1);
994
976
 
995
977
  stats.records--;
996
978
  /* Update shared info */
997
 
  DBUG_ASSERT(share->rows_recorded);
 
979
  assert(share->rows_recorded);
998
980
  pthread_mutex_lock(&share->mutex);
999
981
  share->rows_recorded--;
1000
982
  pthread_mutex_unlock(&share->mutex);
1001
983
 
1002
984
  /* DELETE should never happen on the log table */
1003
 
  DBUG_ASSERT(!share->is_log_table);
 
985
  assert(!share->is_log_table);
1004
986
 
1005
 
  DBUG_RETURN(0);
 
987
  return(0);
1006
988
}
1007
989
 
1008
990
 
1066
1048
 
1067
1049
int ha_tina::rnd_init(bool scan __attribute__((__unused__)))
1068
1050
{
1069
 
  DBUG_ENTER("ha_tina::rnd_init");
1070
 
 
1071
1051
  /* set buffer to the beginning of the file */
1072
1052
  if (share->crashed || init_data_file())
1073
 
    DBUG_RETURN(HA_ERR_CRASHED_ON_USAGE);
 
1053
    return(HA_ERR_CRASHED_ON_USAGE);
1074
1054
 
1075
1055
  current_position= next_position= 0;
1076
1056
  stats.records= 0;
1079
1059
 
1080
1060
  init_alloc_root(&blobroot, BLOB_MEMROOT_ALLOC_SIZE, 0);
1081
1061
 
1082
 
  DBUG_RETURN(0);
 
1062
  return(0);
1083
1063
}
1084
1064
 
1085
1065
/*
1099
1079
int ha_tina::rnd_next(uchar *buf)
1100
1080
{
1101
1081
  int rc;
1102
 
  DBUG_ENTER("ha_tina::rnd_next");
1103
1082
 
1104
1083
  if (share->crashed)
1105
 
      DBUG_RETURN(HA_ERR_CRASHED_ON_USAGE);
 
1084
      return(HA_ERR_CRASHED_ON_USAGE);
1106
1085
 
1107
1086
  ha_statistic_increment(&SSV::ha_read_rnd_next_count);
1108
1087
 
1110
1089
 
1111
1090
  /* don't scan an empty file */
1112
1091
  if (!local_saved_data_file_length)
1113
 
    DBUG_RETURN(HA_ERR_END_OF_FILE);
 
1092
    return(HA_ERR_END_OF_FILE);
1114
1093
 
1115
1094
  if ((rc= find_current_row(buf)))
1116
 
    DBUG_RETURN(rc);
 
1095
    return(rc);
1117
1096
 
1118
1097
  stats.records++;
1119
 
  DBUG_RETURN(0);
 
1098
  return(0);
1120
1099
}
1121
1100
 
1122
1101
/*
1130
1109
*/
1131
1110
void ha_tina::position(const uchar *record __attribute__((__unused__)))
1132
1111
{
1133
 
  DBUG_ENTER("ha_tina::position");
1134
1112
  my_store_ptr(ref, ref_length, current_position);
1135
 
  DBUG_VOID_RETURN;
 
1113
  return;
1136
1114
}
1137
1115
 
1138
1116
 
1143
1121
 
1144
1122
int ha_tina::rnd_pos(uchar * buf, uchar *pos)
1145
1123
{
1146
 
  DBUG_ENTER("ha_tina::rnd_pos");
1147
1124
  ha_statistic_increment(&SSV::ha_read_rnd_count);
1148
1125
  current_position= (off_t)my_get_ptr(pos,ref_length);
1149
 
  DBUG_RETURN(find_current_row(buf));
 
1126
  return(find_current_row(buf));
1150
1127
}
1151
1128
 
1152
1129
/*
1156
1133
*/
1157
1134
int ha_tina::info(uint flag __attribute__((__unused__)))
1158
1135
{
1159
 
  DBUG_ENTER("ha_tina::info");
1160
1136
  /* This is a lie, but you don't want the optimizer to see zero or 1 */
1161
1137
  if (!records_is_known && stats.records < 2) 
1162
1138
    stats.records= 2;
1163
 
  DBUG_RETURN(0);
 
1139
  return(0);
1164
1140
}
1165
1141
 
1166
1142
/*
1189
1165
{
1190
1166
  char updated_fname[FN_REFLEN];
1191
1167
  off_t file_buffer_start= 0;
1192
 
  DBUG_ENTER("ha_tina::rnd_end");
1193
1168
 
1194
1169
  free_root(&blobroot, MYF(0));
1195
1170
  records_is_known= 1;
1215
1190
 
1216
1191
    /* create the file to write updated table if it wasn't yet created */
1217
1192
    if (open_update_temp_file_if_needed())
1218
 
      DBUG_RETURN(-1);
 
1193
      return(-1);
1219
1194
 
1220
1195
    /* write the file with updated info */
1221
1196
    while ((file_buffer_start != -1))     // while not end of file
1251
1226
 
1252
1227
    if (my_sync(update_temp_file, MYF(MY_WME)) ||
1253
1228
        my_close(update_temp_file, MYF(0)))
1254
 
      DBUG_RETURN(-1);
 
1229
      return(-1);
1255
1230
 
1256
1231
    share->update_file_opened= false;
1257
1232
 
1258
1233
    if (share->tina_write_opened)
1259
1234
    {
1260
1235
      if (my_close(share->tina_write_filedes, MYF(0)))
1261
 
        DBUG_RETURN(-1);
 
1236
        return(-1);
1262
1237
      /*
1263
1238
        Mark that the writer fd is closed, so that init_tina_writer()
1264
1239
        will reopen it later.
1274
1249
        my_rename(fn_format(updated_fname, share->table_name, "", CSN_EXT,
1275
1250
                            MY_REPLACE_EXT | MY_UNPACK_FILENAME),
1276
1251
                  share->data_file_name, MYF(0)))
1277
 
      DBUG_RETURN(-1);
 
1252
      return(-1);
1278
1253
 
1279
1254
    /* Open the file again */
1280
1255
    if (((data_file= my_open(share->data_file_name, O_RDONLY, MYF(0))) == -1))
1281
 
      DBUG_RETURN(-1);
 
1256
      return(-1);
1282
1257
    /*
1283
1258
      As we reopened the data file, increase share->data_file_version 
1284
1259
      in order to force other threads waiting on a table lock and  
1302
1277
    local_saved_data_file_length= temp_file_length;
1303
1278
  }
1304
1279
 
1305
 
  DBUG_RETURN(0);
 
1280
  return(0);
1306
1281
error:
1307
1282
  my_close(update_temp_file, MYF(0));
1308
1283
  share->update_file_opened= false;
1309
 
  DBUG_RETURN(-1);
 
1284
  return(-1);
1310
1285
}
1311
1286
 
1312
1287
 
1337
1312
  int rc;
1338
1313
  ha_rows rows_repaired= 0;
1339
1314
  off_t write_begin= 0, write_end;
1340
 
  DBUG_ENTER("ha_tina::repair");
1341
1315
 
1342
1316
  /* empty file */
1343
1317
  if (!share->saved_data_file_length)
1349
1323
  /* Don't assert in field::val() functions */
1350
1324
  table->use_all_columns();
1351
1325
  if (!(buf= (uchar*) my_malloc(table->s->reclength, MYF(MY_WME))))
1352
 
    DBUG_RETURN(HA_ERR_OUT_OF_MEM);
 
1326
    return(HA_ERR_OUT_OF_MEM);
1353
1327
 
1354
1328
  /* position buffer to the start of the file */
1355
1329
  if (init_data_file())
1356
 
    DBUG_RETURN(HA_ERR_CRASHED_ON_REPAIR);
 
1330
    return(HA_ERR_CRASHED_ON_REPAIR);
1357
1331
 
1358
1332
  /*
1359
1333
    Local_saved_data_file_length is initialized during the lock phase.
1397
1371
                                        "", CSN_EXT,
1398
1372
                                        MY_REPLACE_EXT|MY_UNPACK_FILENAME),
1399
1373
                           0, O_RDWR | O_TRUNC,MYF(MY_WME))) < 0)
1400
 
    DBUG_RETURN(HA_ERR_CRASHED_ON_REPAIR);
 
1374
    return(HA_ERR_CRASHED_ON_REPAIR);
1401
1375
 
1402
1376
  file_buff->init_buff(data_file);
1403
1377
 
1412
1386
    if ((write_end - write_begin) &&
1413
1387
        (my_write(repair_file, (uchar*)file_buff->ptr(),
1414
1388
                  write_end - write_begin, MYF_RW)))
1415
 
      DBUG_RETURN(-1);
 
1389
      return(-1);
1416
1390
 
1417
1391
    write_begin= write_end;
1418
1392
    if (write_end== current_position)
1429
1403
  */
1430
1404
  if (my_close(data_file,MYF(0)) || my_close(repair_file, MYF(0)) ||
1431
1405
      my_rename(repaired_fname, share->data_file_name, MYF(0)))
1432
 
    DBUG_RETURN(-1);
 
1406
    return(-1);
1433
1407
 
1434
1408
  /* Open the file again, it should now be repaired */
1435
1409
  if ((data_file= my_open(share->data_file_name, O_RDWR|O_APPEND,
1436
1410
                          MYF(0))) == -1)
1437
 
     DBUG_RETURN(-1);
 
1411
     return(-1);
1438
1412
 
1439
1413
  /* Set new file size. The file size will be updated by ::update_status() */
1440
1414
  local_saved_data_file_length= (size_t) current_position;
1441
1415
 
1442
1416
end:
1443
1417
  share->crashed= false;
1444
 
  DBUG_RETURN(HA_ADMIN_OK);
 
1418
  return(HA_ADMIN_OK);
1445
1419
}
1446
1420
 
1447
1421
/*
1451
1425
int ha_tina::delete_all_rows()
1452
1426
{
1453
1427
  int rc;
1454
 
  DBUG_ENTER("ha_tina::delete_all_rows");
1455
1428
 
1456
1429
  if (!records_is_known)
1457
 
    DBUG_RETURN(my_errno=HA_ERR_WRONG_COMMAND);
 
1430
    return(my_errno=HA_ERR_WRONG_COMMAND);
1458
1431
 
1459
1432
  if (!share->tina_write_opened)
1460
1433
    if (init_tina_writer())
1461
 
      DBUG_RETURN(-1);
 
1434
      return(-1);
1462
1435
 
1463
1436
  /* Truncate the file to zero size */
1464
1437
  rc= ftruncate(share->tina_write_filedes, 0);
1469
1442
  share->rows_recorded= 0;
1470
1443
  pthread_mutex_unlock(&share->mutex);
1471
1444
  local_saved_data_file_length= 0;
1472
 
  DBUG_RETURN(rc);
 
1445
  return(rc);
1473
1446
}
1474
1447
 
1475
1448
/*
1496
1469
{
1497
1470
  char name_buff[FN_REFLEN];
1498
1471
  File create_file;
1499
 
  DBUG_ENTER("ha_tina::create");
1500
1472
 
1501
1473
  /*
1502
1474
    check columns
1506
1478
    if ((*field)->real_maybe_null())
1507
1479
    {
1508
1480
      my_error(ER_CHECK_NOT_IMPLEMENTED, MYF(0), "nullable columns");
1509
 
      DBUG_RETURN(HA_ERR_UNSUPPORTED);
 
1481
      return(HA_ERR_UNSUPPORTED);
1510
1482
    }
1511
1483
  }
1512
1484
  
1514
1486
  if ((create_file= my_create(fn_format(name_buff, name, "", CSM_EXT,
1515
1487
                                        MY_REPLACE_EXT|MY_UNPACK_FILENAME), 0,
1516
1488
                              O_RDWR | O_TRUNC,MYF(MY_WME))) < 0)
1517
 
    DBUG_RETURN(-1);
 
1489
    return(-1);
1518
1490
 
1519
1491
  write_meta_file(create_file, 0, false);
1520
1492
  my_close(create_file, MYF(0));
1522
1494
  if ((create_file= my_create(fn_format(name_buff, name, "", CSV_EXT,
1523
1495
                                        MY_REPLACE_EXT|MY_UNPACK_FILENAME),0,
1524
1496
                              O_RDWR | O_TRUNC,MYF(MY_WME))) < 0)
1525
 
    DBUG_RETURN(-1);
 
1497
    return(-1);
1526
1498
 
1527
1499
  my_close(create_file, MYF(0));
1528
1500
 
1529
 
  DBUG_RETURN(0);
 
1501
  return(0);
1530
1502
}
1531
1503
 
1532
1504
int ha_tina::check(THD* thd,
1536
1508
  uchar *buf;
1537
1509
  const char *old_proc_info;
1538
1510
  ha_rows count= share->rows_recorded;
1539
 
  DBUG_ENTER("ha_tina::check");
1540
1511
 
1541
1512
  old_proc_info= thd_proc_info(thd, "Checking table");
1542
1513
  if (!(buf= (uchar*) my_malloc(table->s->reclength, MYF(MY_WME))))
1543
 
    DBUG_RETURN(HA_ERR_OUT_OF_MEM);
 
1514
    return(HA_ERR_OUT_OF_MEM);
1544
1515
 
1545
1516
  /* position buffer to the start of the file */
1546
1517
   if (init_data_file())
1547
 
     DBUG_RETURN(HA_ERR_CRASHED);
 
1518
     return(HA_ERR_CRASHED);
1548
1519
 
1549
1520
  /*
1550
1521
    Local_saved_data_file_length is initialized during the lock phase.
1573
1544
  if ((rc != HA_ERR_END_OF_FILE) || count)
1574
1545
  {
1575
1546
    share->crashed= true;
1576
 
    DBUG_RETURN(HA_ADMIN_CORRUPT);
 
1547
    return(HA_ADMIN_CORRUPT);
1577
1548
  }
1578
1549
  else
1579
 
    DBUG_RETURN(HA_ADMIN_OK);
 
1550
    return(HA_ADMIN_OK);
1580
1551
}
1581
1552
 
1582
1553