~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to storage/myisam/ha_myisam.cc

  • Committer: Monty Taylor
  • Date: 2008-07-16 19:10:24 UTC
  • mfrom: (51.1.127 remove-dbug)
  • mto: This revision was merged to the branch mainline in revision 176.
  • Revision ID: monty@inaugust.com-20080716191024-prjgoh7fbri7rx26
MergedĀ fromĀ remove-dbug.

Show diffs side-by-side

added added

removed removed

Lines of Context:
68
68
  msg_length= vsnprintf(msgbuf, sizeof(msgbuf), fmt, args);
69
69
  msgbuf[sizeof(msgbuf) - 1] = 0; // healthy paranoia
70
70
 
71
 
  DBUG_PRINT(msg_type,("message: %s",msgbuf));
72
 
 
73
71
  if (!thd->vio_ok())
74
72
  {
75
73
    sql_print_error(msgbuf);
140
138
  HA_KEYSEG *keyseg;
141
139
  TABLE_SHARE *share= table_arg->s;
142
140
  uint options= share->db_options_in_use;
143
 
  DBUG_ENTER("table2myisam");
144
141
  if (!(my_multi_malloc(MYF(MY_WME),
145
142
          recinfo_out, (share->fields * 2 + 2) * sizeof(MI_COLUMNDEF),
146
143
          keydef_out, share->keys * sizeof(MI_KEYDEF),
147
144
          &keyseg,
148
145
          (share->key_parts + share->keys) * sizeof(HA_KEYSEG),
149
146
          NullS)))
150
 
    DBUG_RETURN(HA_ERR_OUT_OF_MEM); /* purecov: inspected */
 
147
    return(HA_ERR_OUT_OF_MEM); /* purecov: inspected */
151
148
  keydef= *keydef_out;
152
149
  recinfo= *recinfo_out;
153
150
  pos= table_arg->key_info;
242
239
        }
243
240
      }
244
241
    }
245
 
    DBUG_PRINT("loop", ("found: 0x%lx  recpos: %d  minpos: %d  length: %d",
246
 
                        (long) found, recpos, minpos, length));
247
242
    if (recpos != minpos)
248
243
    { // Reserved space (Null bits?)
249
244
      bzero((char*) recinfo_pos, sizeof(*recinfo_pos));
282
277
    }
283
278
    (recinfo_pos++)->length= (uint16) length;
284
279
    recpos= minpos + length;
285
 
    DBUG_PRINT("loop", ("length: %d  type: %d",
286
 
                        recinfo_pos[-1].length,recinfo_pos[-1].type));
287
280
  }
288
281
  *records_out= (uint) (recinfo_pos - recinfo);
289
 
  DBUG_RETURN(0);
 
282
  return(0);
290
283
}
291
284
 
292
285
 
336
329
                     uint t2_keys, uint t2_recs, bool strict)
337
330
{
338
331
  uint i, j;
339
 
  DBUG_ENTER("check_definition");
340
332
  if ((strict ? t1_keys != t2_keys : t1_keys > t2_keys))
341
333
  {
342
 
    DBUG_PRINT("error", ("Number of keys differs: t1_keys=%u, t2_keys=%u",
343
 
                         t1_keys, t2_keys));
344
 
    DBUG_RETURN(1);
 
334
    return(1);
345
335
  }
346
336
  if (t1_recs != t2_recs)
347
337
  {
348
 
    DBUG_PRINT("error", ("Number of recs differs: t1_recs=%u, t2_recs=%u",
349
 
                         t1_recs, t2_recs));
350
 
    DBUG_RETURN(1);
 
338
    return(1);
351
339
  }
352
340
  for (i= 0; i < t1_keys; i++)
353
341
  {
358
346
    else if (t1_keyinfo[i].flag & HA_FULLTEXT ||
359
347
             t2_keyinfo[i].flag & HA_FULLTEXT)
360
348
    {
361
 
       DBUG_PRINT("error", ("Key %d has different definition", i));
362
 
       DBUG_PRINT("error", ("t1_fulltext= %d, t2_fulltext=%d",
363
 
                            test(t1_keyinfo[i].flag & HA_FULLTEXT),
364
 
                            test(t2_keyinfo[i].flag & HA_FULLTEXT)));
365
 
       DBUG_RETURN(1);
 
349
       return(1);
366
350
    }
367
351
    if (t1_keyinfo[i].flag & HA_SPATIAL && t2_keyinfo[i].flag & HA_SPATIAL)
368
352
      continue;
369
353
    else if (t1_keyinfo[i].flag & HA_SPATIAL ||
370
354
             t2_keyinfo[i].flag & HA_SPATIAL)
371
355
    {
372
 
       DBUG_PRINT("error", ("Key %d has different definition", i));
373
 
       DBUG_PRINT("error", ("t1_spatial= %d, t2_spatial=%d",
374
 
                            test(t1_keyinfo[i].flag & HA_SPATIAL),
375
 
                            test(t2_keyinfo[i].flag & HA_SPATIAL)));
376
 
       DBUG_RETURN(1);
 
356
       return(1);
377
357
    }
378
358
    if (t1_keyinfo[i].keysegs != t2_keyinfo[i].keysegs ||
379
359
        t1_keyinfo[i].key_alg != t2_keyinfo[i].key_alg)
380
360
    {
381
 
      DBUG_PRINT("error", ("Key %d has different definition", i));
382
 
      DBUG_PRINT("error", ("t1_keysegs=%d, t1_key_alg=%d",
383
 
                           t1_keyinfo[i].keysegs, t1_keyinfo[i].key_alg));
384
 
      DBUG_PRINT("error", ("t2_keysegs=%d, t2_key_alg=%d",
385
 
                           t2_keyinfo[i].keysegs, t2_keyinfo[i].key_alg));
386
 
      DBUG_RETURN(1);
 
361
      return(1);
387
362
    }
388
363
    for (j=  t1_keyinfo[i].keysegs; j--;)
389
364
    {
411
386
          t1_keysegs[j].null_bit != t2_keysegs[j].null_bit ||
412
387
          t1_keysegs[j].length != t2_keysegs[j].length)
413
388
      {
414
 
        DBUG_PRINT("error", ("Key segment %d (key %d) has different "
415
 
                             "definition", j, i));
416
 
        DBUG_PRINT("error", ("t1_type=%d, t1_language=%d, t1_null_bit=%d, "
417
 
                             "t1_length=%d",
418
 
                             t1_keysegs[j].type, t1_keysegs[j].language,
419
 
                             t1_keysegs[j].null_bit, t1_keysegs[j].length));
420
 
        DBUG_PRINT("error", ("t2_type=%d, t2_language=%d, t2_null_bit=%d, "
421
 
                             "t2_length=%d",
422
 
                             t2_keysegs[j].type, t2_keysegs[j].language,
423
 
                             t2_keysegs[j].null_bit, t2_keysegs[j].length));
424
 
 
425
 
        DBUG_RETURN(1);
 
389
        return(1);
426
390
      }
427
391
    }
428
392
  }
441
405
        t1_rec->length != t2_rec->length ||
442
406
        t1_rec->null_bit != t2_rec->null_bit)
443
407
    {
444
 
      DBUG_PRINT("error", ("Field %d has different definition", i));
445
 
      DBUG_PRINT("error", ("t1_type=%d, t1_length=%d, t1_null_bit=%d",
446
 
                           t1_rec->type, t1_rec->length, t1_rec->null_bit));
447
 
      DBUG_PRINT("error", ("t2_type=%d, t2_length=%d, t2_null_bit=%d",
448
 
                           t2_rec->type, t2_rec->length, t2_rec->null_bit));
449
 
      DBUG_RETURN(1);
 
408
      return(1);
450
409
    }
451
410
  }
452
 
  DBUG_RETURN(0);
 
411
  return(0);
453
412
}
454
413
 
455
414
 
597
556
    if ((my_errno= table2myisam(table, &keyinfo, &recinfo, &recs)))
598
557
    {
599
558
      /* purecov: begin inspected */
600
 
      DBUG_PRINT("error", ("Failed to convert TABLE object to MyISAM "
601
 
                           "key and column definition"));
602
559
      goto err;
603
560
      /* purecov: end */
604
561
    }
889
846
  char fixed_name[FN_REFLEN];
890
847
  MYISAM_SHARE* share = file->s;
891
848
  ha_rows rows= file->state->records;
892
 
  DBUG_ENTER("ha_myisam::repair");
893
849
 
894
850
  /*
895
851
    Normally this method is entered with a properly opened table. If the
904
860
    sql_print_information("Retrying repair of: '%s' failed. "
905
861
                          "Please try REPAIR EXTENDED or myisamchk",
906
862
                          table->s->path.str);
907
 
    DBUG_RETURN(HA_ADMIN_FAILED);
 
863
    return(HA_ADMIN_FAILED);
908
864
  }
909
865
 
910
866
  param.db_name=    table->s->db.str;
921
877
      mi_lock_database(file, table->s->tmp_table ? F_EXTRA_LCK : F_WRLCK))
922
878
  {
923
879
    mi_check_print_error(&param,ER(ER_CANT_LOCK),my_errno);
924
 
    DBUG_RETURN(HA_ADMIN_FAILED);
 
880
    return(HA_ADMIN_FAILED);
925
881
  }
926
882
 
927
883
  if (!do_optimize ||
1029
985
  thd_proc_info(thd, old_proc_info);
1030
986
  if (!thd->locked_tables)
1031
987
    mi_lock_database(file,F_UNLCK);
1032
 
  DBUG_RETURN(error ? HA_ADMIN_FAILED :
 
988
  return(error ? HA_ADMIN_FAILED :
1033
989
              !optimize_done ? HA_ADMIN_ALREADY_DONE : HA_ADMIN_OK);
1034
990
}
1035
991
 
1045
1001
  int error= HA_ADMIN_OK;
1046
1002
  uint64_t map;
1047
1003
  TABLE_LIST *table_list= table->pos_in_table_list;
1048
 
  DBUG_ENTER("ha_myisam::assign_to_keycache");
1049
1004
 
1050
1005
  table->keys_in_use_for_query.clear_all();
1051
1006
 
1052
1007
  if (table_list->process_index_hints(table))
1053
 
    DBUG_RETURN(HA_ADMIN_FAILED);
 
1008
    return(HA_ADMIN_FAILED);
1054
1009
  map= ~(uint64_t) 0;
1055
1010
  if (!table->keys_in_use_for_query.is_clear_all())
1056
1011
    /* use all keys if there's no list specified by the user through hints */
1077
1032
    param.testflag= 0;
1078
1033
    mi_check_print_error(&param, errmsg);
1079
1034
  }
1080
 
  DBUG_RETURN(error);
 
1035
  return(error);
1081
1036
}
1082
1037
 
1083
1038
 
1251
1206
 
1252
1207
void ha_myisam::start_bulk_insert(ha_rows rows)
1253
1208
{
1254
 
  DBUG_ENTER("ha_myisam::start_bulk_insert");
1255
1209
  THD *thd= current_thd;
1256
1210
  ulong size= min(thd->variables.read_buff_size,
1257
1211
                  (ulong) (table->s->avg_row_length*rows));
1258
 
  DBUG_PRINT("info",("start_bulk_insert: rows %lu size %lu",
1259
 
                     (ulong) rows, size));
1260
1212
 
1261
1213
  /* don't enable row cache if too few rows */
1262
1214
  if (! rows || (rows > MI_MIN_ROWS_TO_USE_WRITE_CACHE))
1283
1235
      mi_init_bulk_insert(file, thd->variables.bulk_insert_buff_size, rows);
1284
1236
    }
1285
1237
  }
1286
 
  DBUG_VOID_RETURN;
 
1238
  return;
1287
1239
}
1288
1240
 
1289
1241
/*
1315
1267
  char *old_query;
1316
1268
  uint old_query_length;
1317
1269
  HA_CHECK_OPT check_opt;
1318
 
  DBUG_ENTER("ha_myisam::check_and_repair");
1319
1270
 
1320
1271
  check_opt.init();
1321
1272
  check_opt.flags= T_MEDIUM | T_AUTO_REPAIR;
1346
1297
  thd->query= old_query;
1347
1298
  thd->query_length= old_query_length;
1348
1299
  pthread_mutex_unlock(&LOCK_thread_count);
1349
 
  DBUG_RETURN(error);
 
1300
  return(error);
1350
1301
}
1351
1302
 
1352
1303
bool ha_myisam::is_crashed() const
1411
1362
                              key_part_map keypart_map,
1412
1363
                              enum ha_rkey_function find_flag)
1413
1364
{
1414
 
  DBUG_ASSERT(inited==INDEX);
 
1365
  assert(inited==INDEX);
1415
1366
  ha_statistic_increment(&SSV::ha_read_key_count);
1416
1367
  int error=mi_rkey(file, buf, active_index, key, keypart_map, find_flag);
1417
1368
  table->status=error ? STATUS_NOT_FOUND: 0;
1431
1382
int ha_myisam::index_read_last_map(uchar *buf, const uchar *key,
1432
1383
                                   key_part_map keypart_map)
1433
1384
{
1434
 
  DBUG_ENTER("ha_myisam::index_read_last");
1435
 
  DBUG_ASSERT(inited==INDEX);
 
1385
  assert(inited==INDEX);
1436
1386
  ha_statistic_increment(&SSV::ha_read_key_count);
1437
1387
  int error=mi_rkey(file, buf, active_index, key, keypart_map,
1438
1388
                    HA_READ_PREFIX_LAST);
1439
1389
  table->status=error ? STATUS_NOT_FOUND: 0;
1440
 
  DBUG_RETURN(error);
 
1390
  return(error);
1441
1391
}
1442
1392
 
1443
1393
int ha_myisam::index_next(uchar *buf)
1444
1394
{
1445
 
  DBUG_ASSERT(inited==INDEX);
 
1395
  assert(inited==INDEX);
1446
1396
  ha_statistic_increment(&SSV::ha_read_next_count);
1447
1397
  int error=mi_rnext(file,buf,active_index);
1448
1398
  table->status=error ? STATUS_NOT_FOUND: 0;
1451
1401
 
1452
1402
int ha_myisam::index_prev(uchar *buf)
1453
1403
{
1454
 
  DBUG_ASSERT(inited==INDEX);
 
1404
  assert(inited==INDEX);
1455
1405
  ha_statistic_increment(&SSV::ha_read_prev_count);
1456
1406
  int error=mi_rprev(file,buf, active_index);
1457
1407
  table->status=error ? STATUS_NOT_FOUND: 0;
1460
1410
 
1461
1411
int ha_myisam::index_first(uchar *buf)
1462
1412
{
1463
 
  DBUG_ASSERT(inited==INDEX);
 
1413
  assert(inited==INDEX);
1464
1414
  ha_statistic_increment(&SSV::ha_read_first_count);
1465
1415
  int error=mi_rfirst(file, buf, active_index);
1466
1416
  table->status=error ? STATUS_NOT_FOUND: 0;
1469
1419
 
1470
1420
int ha_myisam::index_last(uchar *buf)
1471
1421
{
1472
 
  DBUG_ASSERT(inited==INDEX);
 
1422
  assert(inited==INDEX);
1473
1423
  ha_statistic_increment(&SSV::ha_read_last_count);
1474
1424
  int error=mi_rlast(file, buf, active_index);
1475
1425
  table->status=error ? STATUS_NOT_FOUND: 0;
1481
1431
                               uint length __attribute__((unused)))
1482
1432
{
1483
1433
  int error;
1484
 
  DBUG_ASSERT(inited==INDEX);
 
1434
  assert(inited==INDEX);
1485
1435
  ha_statistic_increment(&SSV::ha_read_next_count);
1486
1436
  do
1487
1437
  {
1697
1647
  MI_CREATE_INFO create_info;
1698
1648
  TABLE_SHARE *share= table_arg->s;
1699
1649
  uint options= share->db_options_in_use;
1700
 
  DBUG_ENTER("ha_myisam::create");
1701
1650
  for (i= 0; i < share->keys; i++)
1702
1651
  {
1703
1652
    if (table_arg->key_info[i].flags & HA_USES_PARSER)
1707
1656
    }
1708
1657
  }
1709
1658
  if ((error= table2myisam(table_arg, &keydef, &recinfo, &records)))
1710
 
    DBUG_RETURN(error); /* purecov: inspected */
 
1659
    return(error); /* purecov: inspected */
1711
1660
  bzero((char*) &create_info, sizeof(create_info));
1712
1661
  create_info.max_rows= share->max_rows;
1713
1662
  create_info.reloc_rows= share->min_rows;
1740
1689
                   0, (MI_UNIQUEDEF*) 0,
1741
1690
                   &create_info, create_flags);
1742
1691
  my_free((uchar*) recinfo, MYF(0));
1743
 
  DBUG_RETURN(error);
 
1692
  return(error);
1744
1693
}
1745
1694
 
1746
1695
 
1952
1901
  NULL                        /* config options                  */
1953
1902
}
1954
1903
mysql_declare_plugin_end;
1955
 
 
1956
 
 
1957
 
#ifdef HAVE_QUERY_CACHE
1958
 
/**
1959
 
  @brief Register a named table with a call back function to the query cache.
1960
 
 
1961
 
  @param thd The thread handle
1962
 
  @param table_key A pointer to the table name in the table cache
1963
 
  @param key_length The length of the table name
1964
 
  @param[out] engine_callback The pointer to the storage engine call back
1965
 
    function, currently 0
1966
 
  @param[out] engine_data Engine data will be set to 0.
1967
 
 
1968
 
  @note Despite the name of this function, it is used to check each statement
1969
 
    before it is cached and not to register a table or callback function.
1970
 
 
1971
 
  @see handler::register_query_cache_table
1972
 
 
1973
 
  @return The error code. The engine_data and engine_callback will be set to 0.
1974
 
    @retval true Success
1975
 
    @retval false An error occured
1976
 
*/
1977
 
 
1978
 
my_bool ha_myisam::register_query_cache_table(THD *thd, char *table_name,
1979
 
                                              uint table_name_len,
1980
 
                                              qc_engine_callback
1981
 
                                              *engine_callback,
1982
 
                                              uint64_t *engine_data)
1983
 
{
1984
 
  DBUG_ENTER("ha_myisam::register_query_cache_table");
1985
 
  /*
1986
 
    No call back function is needed to determine if a cached statement
1987
 
    is valid or not.
1988
 
  */
1989
 
  *engine_callback= 0;
1990
 
 
1991
 
  /*
1992
 
    No engine data is needed.
1993
 
  */
1994
 
  *engine_data= 0;
1995
 
 
1996
 
  if (file->s->concurrent_insert)
1997
 
  {
1998
 
    /*
1999
 
      If a concurrent INSERT has happened just before the currently
2000
 
      processed SELECT statement, the total size of the table is
2001
 
      unknown.
2002
 
 
2003
 
      To determine if the table size is known, the current thread's snap
2004
 
      shot of the table size with the actual table size are compared.
2005
 
 
2006
 
      If the table size is unknown the SELECT statement can't be cached.
2007
 
 
2008
 
      When concurrent inserts are disabled at table open, mi_open()
2009
 
      does not assign a get_status() function. In this case the local
2010
 
      ("current") status is never updated. We would wrongly think that
2011
 
      we cannot cache the statement.
2012
 
    */
2013
 
    uint64_t actual_data_file_length;
2014
 
    uint64_t current_data_file_length;
2015
 
 
2016
 
    /*
2017
 
      POSIX visibility rules specify that "2. Whatever memory values a
2018
 
      thread can see when it unlocks a mutex <...> can also be seen by any
2019
 
      thread that later locks the same mutex". In this particular case,
2020
 
      concurrent insert thread had modified the data_file_length in
2021
 
      MYISAM_SHARE before it has unlocked (or even locked)
2022
 
      structure_guard_mutex. So, here we're guaranteed to see at least that
2023
 
      value after we've locked the same mutex. We can see a later value
2024
 
      (modified by some other thread) though, but it's ok, as we only want
2025
 
      to know if the variable was changed, the actual new value doesn't matter
2026
 
    */
2027
 
    actual_data_file_length= file->s->state.state.data_file_length;
2028
 
    current_data_file_length= file->save_state.data_file_length;
2029
 
 
2030
 
    if (current_data_file_length != actual_data_file_length)
2031
 
    {
2032
 
      /* Don't cache current statement. */
2033
 
      DBUG_RETURN(false);
2034
 
    }
2035
 
  }
2036
 
 
2037
 
  /* It is ok to try to cache current statement. */
2038
 
  DBUG_RETURN(true);
2039
 
}
2040
 
#endif