~mdcallag/+junk/5.1-map

« back to all changes in this revision

Viewing changes to storage/myisam/ha_myisam.cc

  • Committer: msvensson at pilot
  • Date: 2007-04-24 09:11:45 UTC
  • mfrom: (2469.1.106)
  • Revision ID: sp1r-msvensson@pilot.blaudden-20070424091145-10463
Merge pilot.blaudden:/home/msvensson/mysql/my51-m-mysql_upgrade
into  pilot.blaudden:/home/msvensson/mysql/mysql-5.1-maint

Show diffs side-by-side

added added

removed removed

Lines of Context:
320
320
  RETURN VALUE
321
321
    0 - Equal definitions.
322
322
    1 - Different definitions.
 
323
 
 
324
  TODO
 
325
    - compare FULLTEXT keys;
 
326
    - compare SPATIAL keys;
 
327
    - compare FIELD_SKIP_ZERO which is converted to FIELD_NORMAL correctly
 
328
      (should be corretly detected in table2myisam).
323
329
*/
324
330
 
325
331
int check_definition(MI_KEYDEF *t1_keyinfo, MI_COLUMNDEF *t1_recinfo,
345
351
  {
346
352
    HA_KEYSEG *t1_keysegs= t1_keyinfo[i].seg;
347
353
    HA_KEYSEG *t2_keysegs= t2_keyinfo[i].seg;
 
354
    if (t1_keyinfo[i].flag & HA_FULLTEXT && t2_keyinfo[i].flag & HA_FULLTEXT)
 
355
      continue;
 
356
    else if (t1_keyinfo[i].flag & HA_FULLTEXT ||
 
357
             t2_keyinfo[i].flag & HA_FULLTEXT)
 
358
    {
 
359
       DBUG_PRINT("error", ("Key %d has different definition", i));
 
360
       DBUG_PRINT("error", ("t1_fulltext= %d, t2_fulltext=%d",
 
361
                            test(t1_keyinfo[i].flag & HA_FULLTEXT),
 
362
                            test(t2_keyinfo[i].flag & HA_FULLTEXT)));
 
363
       DBUG_RETURN(1);
 
364
    }
 
365
    if (t1_keyinfo[i].flag & HA_SPATIAL && t2_keyinfo[i].flag & HA_SPATIAL)
 
366
      continue;
 
367
    else if (t1_keyinfo[i].flag & HA_SPATIAL ||
 
368
             t2_keyinfo[i].flag & HA_SPATIAL)
 
369
    {
 
370
       DBUG_PRINT("error", ("Key %d has different definition", i));
 
371
       DBUG_PRINT("error", ("t1_spatial= %d, t2_spatial=%d",
 
372
                            test(t1_keyinfo[i].flag & HA_SPATIAL),
 
373
                            test(t2_keyinfo[i].flag & HA_SPATIAL)));
 
374
       DBUG_RETURN(1);
 
375
    }
348
376
    if (t1_keyinfo[i].keysegs != t2_keyinfo[i].keysegs ||
349
377
        t1_keyinfo[i].key_alg != t2_keyinfo[i].key_alg)
350
378
    {
381
409
  {
382
410
    MI_COLUMNDEF *t1_rec= &t1_recinfo[i];
383
411
    MI_COLUMNDEF *t2_rec= &t2_recinfo[i];
384
 
    if (t1_rec->type != t2_rec->type ||
 
412
    /*
 
413
      FIELD_SKIP_ZERO can be changed to FIELD_NORMAL in mi_create,
 
414
      see NOTE1 in mi_create.c
 
415
    */
 
416
    if ((t1_rec->type != t2_rec->type &&
 
417
         !(t1_rec->type == (int) FIELD_SKIP_ZERO &&
 
418
           t1_rec->length == 1 &&
 
419
           t2_rec->type == (int) FIELD_NORMAL)) ||
385
420
        t1_rec->length != t2_rec->length ||
386
421
        t1_rec->null_bit != t2_rec->null_bit)
387
422
    {
565
600
 
566
601
bool ha_myisam::check_if_locking_is_allowed(uint sql_command,
567
602
                                            ulong type, TABLE *table,
568
 
                                            uint count,
 
603
                                            uint count, uint current,
 
604
                                            uint *system_count,
569
605
                                            bool called_by_privileged_thread)
570
606
{
571
607
  /*
574
610
    we have to disallow write-locking of these tables with any other tables.
575
611
  */
576
612
  if (table->s->system_table &&
577
 
      table->reginfo.lock_type >= TL_WRITE_ALLOW_WRITE &&
578
 
      count != 1)
 
613
      table->reginfo.lock_type >= TL_WRITE_ALLOW_WRITE)
 
614
    (*system_count)++;
 
615
 
 
616
  /* 'current' is an index, that's why '<=' below. */
 
617
  if (*system_count > 0 && *system_count <= current)
579
618
  {
580
 
    my_error(ER_WRONG_LOCK_OF_SYSTEM_TABLE, MYF(0), table->s->db.str,
581
 
             table->s->table_name.str);
 
619
    my_error(ER_WRONG_LOCK_OF_SYSTEM_TABLE, MYF(0));
582
620
    return FALSE;
583
621
  }
584
622
 
597
635
 
598
636
int ha_myisam::open(const char *name, int mode, uint test_if_locked)
599
637
{
 
638
  MI_KEYDEF *keyinfo;
 
639
  MI_COLUMNDEF *recinfo= 0;
 
640
  uint recs;
600
641
  uint i;
601
642
 
602
643
  /*
619
660
 
620
661
  if (!(file=mi_open(name, mode, test_if_locked | HA_OPEN_FROM_SQL_LAYER)))
621
662
    return (my_errno ? my_errno : -1);
 
663
  if (!table->s->tmp_table) /* No need to perform a check for tmp table */
 
664
  {
 
665
    if ((my_errno= table2myisam(table, &keyinfo, &recinfo, &recs)))
 
666
    {
 
667
      /* purecov: begin inspected */
 
668
      DBUG_PRINT("error", ("Failed to convert TABLE object to MyISAM "
 
669
                           "key and column definition"));
 
670
      goto err;
 
671
      /* purecov: end */
 
672
    }
 
673
    if (check_definition(keyinfo, recinfo, table->s->keys, recs,
 
674
                         file->s->keyinfo, file->s->rec,
 
675
                         file->s->base.keys, file->s->base.fields, true))
 
676
    {
 
677
      /* purecov: begin inspected */
 
678
      my_errno= HA_ERR_CRASHED;
 
679
      goto err;
 
680
      /* purecov: end */
 
681
    }
 
682
  }
622
683
  
623
684
  if (test_if_locked & (HA_OPEN_IGNORE_IF_LOCKED | HA_OPEN_TMP_TABLE))
624
685
    VOID(mi_extra(file, HA_EXTRA_NO_WAIT_LOCK, 0));
639
700
        (struct st_mysql_ftparser *)parser->plugin->info;
640
701
    table->key_info[i].block_size= file->s->keyinfo[i].block_length;
641
702
  }
642
 
  return (0);
 
703
  my_errno= 0;
 
704
  goto end;
 
705
 err:
 
706
  this->close();
 
707
 end:
 
708
  /*
 
709
    Both recinfo and keydef are allocated by my_multi_malloc(), thus only
 
710
    recinfo must be freed.
 
711
  */
 
712
  if (recinfo)
 
713
    my_free((gptr) recinfo, MYF(0));
 
714
  return my_errno;
643
715
}
644
716
 
645
717
int ha_myisam::close(void)
985
1057
  ha_rows rows= file->state->records;
986
1058
  DBUG_ENTER("ha_myisam::repair");
987
1059
 
 
1060
  /*
 
1061
    Normally this method is entered with a properly opened table. If the
 
1062
    repair fails, it can be repeated with more elaborate options. Under
 
1063
    special circumstances it can happen that a repair fails so that it
 
1064
    closed the data file and cannot re-open it. In this case file->dfile
 
1065
    is set to -1. We must not try another repair without an open data
 
1066
    file. (Bug #25289)
 
1067
  */
 
1068
  if (file->dfile == -1)
 
1069
  {
 
1070
    sql_print_information("Retrying repair of: '%s' failed. "
 
1071
                          "Please try REPAIR EXTENDED or myisamchk",
 
1072
                          table->s->path.str);
 
1073
    DBUG_RETURN(HA_ADMIN_FAILED);
 
1074
  }
 
1075
 
988
1076
  param.db_name=    table->s->db.str;
989
1077
  param.table_name= table->alias;
990
1078
  param.tmpfile_createflag = O_RDWR | O_TRUNC;
1121
1209
  KEY_CACHE *new_key_cache= check_opt->key_cache;
1122
1210
  const char *errmsg= 0;
1123
1211
  int error= HA_ADMIN_OK;
1124
 
  ulonglong map= ~(ulonglong) 0;
 
1212
  ulonglong map;
1125
1213
  TABLE_LIST *table_list= table->pos_in_table_list;
1126
1214
  DBUG_ENTER("ha_myisam::assign_to_keycache");
1127
1215
 
1128
 
  /* Check validity of the index references */
1129
 
  if (table_list->use_index)
 
1216
  table->keys_in_use_for_query.clear_all();
 
1217
 
 
1218
  if (table_list->process_index_hints(table))
1130
1219
  {
1131
 
    /* We only come here when the user did specify an index map */
1132
 
    key_map kmap;
1133
 
    if (get_key_map_from_key_list(&kmap, table, table_list->use_index))
1134
 
    {
1135
 
      errmsg= thd->net.last_error;
1136
 
      error= HA_ADMIN_FAILED;
1137
 
      goto err;
1138
 
    }
1139
 
    map= kmap.to_ulonglong();
 
1220
    errmsg= thd->net.last_error;
 
1221
    error= HA_ADMIN_FAILED;
 
1222
    goto err;
1140
1223
  }
 
1224
  map= ~(ulonglong) 0;
 
1225
  if (!table->keys_in_use_for_query.is_clear_all())
 
1226
    /* use all keys if there's no list specified by the user through hints */
 
1227
    map= table->keys_in_use_for_query.to_ulonglong();
1141
1228
 
1142
1229
  if ((error= mi_assign_to_key_cache(file, map, new_key_cache)))
1143
1230
  { 
1173
1260
{
1174
1261
  int error;
1175
1262
  const char *errmsg;
1176
 
  ulonglong map= ~(ulonglong) 0;
 
1263
  ulonglong map;
1177
1264
  TABLE_LIST *table_list= table->pos_in_table_list;
1178
1265
  my_bool ignore_leaves= table_list->ignore_leaves;
1179
1266
 
1180
1267
  DBUG_ENTER("ha_myisam::preload_keys");
1181
1268
 
1182
 
  /* Check validity of the index references */
1183
 
  if (table_list->use_index)
 
1269
  table->keys_in_use_for_query.clear_all();
 
1270
 
 
1271
  if (table_list->process_index_hints(table))
1184
1272
  {
1185
 
    key_map kmap;
1186
 
    get_key_map_from_key_list(&kmap, table, table_list->use_index);
1187
 
    if (kmap.is_set_all())
1188
 
    {
1189
 
      errmsg= thd->net.last_error;
1190
 
      error= HA_ADMIN_FAILED;
1191
 
      goto err;
1192
 
    }
1193
 
    if (!kmap.is_clear_all())
1194
 
      map= kmap.to_ulonglong();
 
1273
    errmsg= thd->net.last_error;
 
1274
    error= HA_ADMIN_FAILED;
 
1275
    goto err;
1195
1276
  }
1196
1277
 
 
1278
  map= ~(ulonglong) 0;
 
1279
  /* Check validity of the index references */
 
1280
  if (!table->keys_in_use_for_query.is_clear_all())
 
1281
    /* use all keys if there's no list specified by the user through hints */
 
1282
    map= table->keys_in_use_for_query.to_ulonglong();
 
1283
 
1197
1284
  mi_extra(file, HA_EXTRA_PRELOAD_BUFFER_SIZE,
1198
1285
           (void *) &thd->variables.preload_buff_size);
1199
1286
 
1521
1608
  return mi_delete(file,buf);
1522
1609
}
1523
1610
 
1524
 
int ha_myisam::index_read(byte * buf, const byte * key,
1525
 
                          uint key_len, enum ha_rkey_function find_flag)
 
1611
int ha_myisam::index_read(byte *buf, const byte *key, key_part_map keypart_map,
 
1612
                          enum ha_rkey_function find_flag)
1526
1613
{
1527
1614
  DBUG_ASSERT(inited==INDEX);
1528
1615
  statistic_increment(table->in_use->status_var.ha_read_key_count,
1529
1616
                      &LOCK_status);
1530
 
  int error=mi_rkey(file,buf,active_index, key, key_len, find_flag);
 
1617
  int error=mi_rkey(file, buf, active_index, key, keypart_map, find_flag);
1531
1618
  table->status=error ? STATUS_NOT_FOUND: 0;
1532
1619
  return error;
1533
1620
}
1534
1621
 
1535
 
int ha_myisam::index_read_idx(byte * buf, uint index, const byte * key,
1536
 
                              uint key_len, enum ha_rkey_function find_flag)
 
1622
int ha_myisam::index_read_idx(byte *buf, uint index, const byte *key,
 
1623
                              key_part_map keypart_map,
 
1624
                              enum ha_rkey_function find_flag)
1537
1625
{
1538
1626
  statistic_increment(table->in_use->status_var.ha_read_key_count,
1539
1627
                      &LOCK_status);
1540
 
  int error=mi_rkey(file,buf,index, key, key_len, find_flag);
 
1628
  int error=mi_rkey(file, buf, index, key, keypart_map, find_flag);
1541
1629
  table->status=error ? STATUS_NOT_FOUND: 0;
1542
1630
  return error;
1543
1631
}
1544
1632
 
1545
 
int ha_myisam::index_read_last(byte * buf, const byte * key, uint key_len)
 
1633
int ha_myisam::index_read_last(byte *buf, const byte *key,
 
1634
                               key_part_map keypart_map)
1546
1635
{
1547
1636
  DBUG_ENTER("ha_myisam::index_read_last");
1548
1637
  DBUG_ASSERT(inited==INDEX);
1549
1638
  statistic_increment(table->in_use->status_var.ha_read_key_count,
1550
1639
                      &LOCK_status);
1551
 
  int error=mi_rkey(file,buf,active_index, key, key_len, HA_READ_PREFIX_LAST);
 
1640
  int error=mi_rkey(file, buf, active_index, key, keypart_map,
 
1641
                    HA_READ_PREFIX_LAST);
1552
1642
  table->status=error ? STATUS_NOT_FOUND: 0;
1553
1643
  DBUG_RETURN(error);
1554
1644
}
1857
1947
  key_copy(key, table->record[0],
1858
1948
           table->key_info + table->s->next_number_index,
1859
1949
           table->s->next_number_key_offset);
1860
 
  error= mi_rkey(file,table->record[1],(int) table->s->next_number_index,
1861
 
                 key,table->s->next_number_key_offset,HA_READ_PREFIX_LAST);
 
1950
  error= mi_rkey(file, table->record[1], (int) table->s->next_number_index,
 
1951
                 key, make_prev_keypart_map(table->s->next_number_keypart),
 
1952
                 HA_READ_PREFIX_LAST);
1862
1953
  if (error)
1863
1954
    nr= 1;
1864
1955
  else