~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_table.cc

  • Committer: Brian Aker
  • Date: 2008-11-21 23:53:09 UTC
  • mfrom: (590.1.8 drizzle-nofrm)
  • Revision ID: brian@tangent.org-20081121235309-77pu95n2pboadtos
Merge in Stewart's work

Show diffs side-by-side

added added

removed removed

Lines of Context:
32
32
 
33
33
int creating_table= 0;        // How many mysql_create_table are running
34
34
 
35
 
const char * primary_key_name="PRIMARY";
 
35
 
 
36
bool is_primary_key(KEY *key_info)
 
37
{
 
38
  static const char * primary_key_name="PRIMARY";
 
39
  return (strcmp(key_info->name, primary_key_name)==0);
 
40
}
 
41
 
 
42
const char* is_primary_key_name(const char* key_name)
 
43
{
 
44
  static const char * primary_key_name="PRIMARY";
 
45
  if (strcmp(key_name, primary_key_name)==0)
 
46
    return key_name;
 
47
  else
 
48
    return NULL;
 
49
}
36
50
 
37
51
static bool check_if_keyname_exists(const char *name,KEY *start, KEY *end);
38
52
static char *make_unique_key_name(const char *field_name,KEY *start,KEY *end);
308
322
    LOCK_open during wait_if_global_read_lock(), other threads could not
309
323
    close their tables. This would make a pretty deadlock.
310
324
  */
311
 
  error= mysql_rm_table_part2(session, tables, if_exists, drop_temporary, 0, 0);
 
325
  error= mysql_rm_table_part2(session, tables, if_exists, drop_temporary, 0);
312
326
 
313
327
  if (need_start_waiting)
314
328
    start_waiting_global_read_lock(session);
350
364
*/
351
365
 
352
366
int mysql_rm_table_part2(Session *session, TableList *tables, bool if_exists,
353
 
                         bool drop_temporary, bool drop_view,
354
 
                         bool dont_log_query)
 
367
                         bool drop_temporary, bool dont_log_query)
355
368
{
356
369
  TableList *table;
357
370
  char path[FN_REFLEN], *alias;
402
415
  {
403
416
    char *db=table->db;
404
417
    handlerton *table_type;
405
 
    enum legacy_db_type frm_db_type;
406
 
 
407
418
 
408
419
    error= drop_temporary_table(session, table);
409
420
 
471
482
                                        FN_IS_TMP : 0);
472
483
    }
473
484
    if (drop_temporary ||
474
 
        ((table_type == NULL && (access(path, F_OK) && ha_create_table_from_engine(session, db, alias))) ||
475
 
         (!drop_view && mysql_frm_type(session, path, &frm_db_type) != true)))
 
485
        ((table_type == NULL && (access(path, F_OK) && ha_create_table_from_engine(session, db, alias))))
 
486
        )
476
487
    {
477
488
      // Table was not found on disk and table can't be created from engine
478
489
      if (if_exists)
485
496
    else
486
497
    {
487
498
      char *end;
488
 
      if (table_type == NULL)
489
 
      {
490
 
        mysql_frm_type(session, path, &frm_db_type);
491
 
        table_type= ha_resolve_by_legacy_type(session, frm_db_type);
492
 
      }
493
499
      // Remove extension for delete
494
500
      *(end= path + path_length - reg_ext_length)= '\0';
495
 
      error= ha_delete_table(session, table_type, path, db, table->table_name,
 
501
      error= ha_delete_table(session, path, db, table->table_name,
496
502
                             !dont_log_query);
497
503
      if ((error == ENOENT || error == HA_ERR_NO_SUCH_TABLE) && 
498
 
          (if_exists || table_type == NULL))
 
504
          if_exists)
499
505
      {
500
506
        error= 0;
501
507
        session->clear_error();
617
623
    != 0        Error
618
624
*/
619
625
 
620
 
bool quick_rm_table(handlerton *base,const char *db,
 
626
bool quick_rm_table(handlerton *base __attribute__((unused)),const char *db,
621
627
                    const char *table_name, uint32_t flags)
622
628
{
623
629
  char path[FN_REFLEN];
632
638
 
633
639
  error|= delete_table_proto_file(path);
634
640
 
635
 
  return(ha_delete_table(current_session, base, path, db, table_name, 0) ||
 
641
  return(ha_delete_table(current_session, path, db, table_name, 0) ||
636
642
              error);
637
643
}
638
644
 
662
668
      /* Sort NOT NULL keys before other keys */
663
669
      return (a_flags & (HA_NULL_PART_KEY)) ? 1 : -1;
664
670
    }
665
 
    if (a->name == primary_key_name)
 
671
    if (is_primary_key(a))
666
672
      return -1;
667
 
    if (b->name == primary_key_name)
 
673
    if (is_primary_key(b))
668
674
      return 1;
669
675
    /* Sort keys don't containing partial segments before others */
670
676
    if ((a_flags ^ b_flags) & HA_KEY_HAS_PART_KEY_SEG)
1266
1272
    else
1267
1273
      (*key_count)--;
1268
1274
    if (key->name.str && !tmp_table && (key->type != Key::PRIMARY) &&
1269
 
        !my_strcasecmp(system_charset_info,key->name.str, primary_key_name))
 
1275
        is_primary_key_name(key->name.str))
1270
1276
    {
1271
1277
      my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0), key->name.str);
1272
1278
      return(true);
1536
1542
                       MYF(0));
1537
1543
            return(true);
1538
1544
          }
1539
 
          key_name=primary_key_name;
 
1545
          static const char pkey_name[]= "PRIMARY";
 
1546
          key_name=pkey_name;
1540
1547
          primary_key=1;
1541
1548
        }
1542
1549
        else if (!(key_name= key->name.str))
1898
1905
    /* Open table and put in temporary table list */
1899
1906
    if (!(open_temporary_table(session, path, db, table_name, 1, OTM_OPEN)))
1900
1907
    {
1901
 
      (void) rm_temporary_table(create_info->db_type, path, false);
 
1908
      (void) rm_temporary_table(create_info->db_type, path);
1902
1909
      goto unlock_and_end;
1903
1910
    }
1904
1911
    session->thread_specific_used= true;
2030
2037
  char buff[MAX_FIELD_NAME],*buff_end;
2031
2038
 
2032
2039
  if (!check_if_keyname_exists(field_name,start,end) &&
2033
 
      my_strcasecmp(system_charset_info,field_name,primary_key_name))
 
2040
      !is_primary_key_name(field_name))
2034
2041
    return (char*) field_name;                  // Use fieldname
2035
2042
  buff_end=strmake(buff,field_name, sizeof(buff)-4);
2036
2043
 
3030
3037
                                     OTM_OPEN))
3031
3038
    {
3032
3039
      (void) rm_temporary_table(create_info->db_type,
3033
 
                                dst_path, false); /* purecov: inspected */
 
3040
                                dst_path);
3034
3041
      goto err;     /* purecov: inspected */
3035
3042
    }
3036
3043
  }
3289
3296
  Create_field *new_field;
3290
3297
  KEY_PART_INFO *key_part;
3291
3298
  KEY_PART_INFO *end;
3292
 
  /*
3293
 
    Remember if the new definition has new VARCHAR column;
3294
 
    create_info->varchar will be reset in mysql_prepare_create_table.
3295
 
  */
3296
 
  bool varchar= create_info->varchar;
3297
3299
 
3298
3300
  {
3299
3301
    /*
3374
3376
      create_info->used_fields & HA_CREATE_USED_ROW_FORMAT ||
3375
3377
      (alter_info->flags & (ALTER_RECREATE | ALTER_FOREIGN_KEY)) ||
3376
3378
      order_num ||
3377
 
      !table->s->mysql_version ||
3378
 
      (table->s->frm_version < FRM_VER_TRUE_VARCHAR && varchar))
 
3379
      !table->s->mysql_version)
3379
3380
  {
3380
3381
    *table_changes= IS_EQUAL_NO;
3381
3382
    /*
3397
3398
    /* TODO check for ADD/DROP FOREIGN KEY */
3398
3399
    if (alter_info->flags & ALTER_FOREIGN_KEY)
3399
3400
      *alter_flags|=  HA_ALTER_FOREIGN_KEY;
3400
 
    if (!table->s->mysql_version ||
3401
 
        (table->s->frm_version < FRM_VER_TRUE_VARCHAR && varchar))
3402
 
      *alter_flags|=  HA_ALTER_COLUMN_TYPE;
3403
3401
  }
3404
3402
  /*
3405
3403
    Go through fields and check if the original ones are compatible
3499
3497
      if (table_key->flags & HA_NOSAME)
3500
3498
      {
3501
3499
        /* Unique key. Check for "PRIMARY". */
3502
 
        if (! my_strcasecmp(system_charset_info,
3503
 
                            table_key->name, primary_key_name))
 
3500
        if (is_primary_key(table_key))
3504
3501
          *alter_flags|= HA_DROP_PK_INDEX;
3505
3502
        else
3506
3503
          *alter_flags|= HA_DROP_UNIQUE_INDEX;
3520
3517
      if (table_key->flags & HA_NOSAME)
3521
3518
      {
3522
3519
        // Unique key. Check for "PRIMARY".
3523
 
        if (! my_strcasecmp(system_charset_info,
3524
 
                            table_key->name, primary_key_name))
 
3520
        if (is_primary_key(table_key))
3525
3521
          *alter_flags|= HA_ALTER_PK_INDEX;
3526
3522
        else
3527
3523
          *alter_flags|= HA_ALTER_UNIQUE_INDEX;
3550
3546
        if (table_key->flags & HA_NOSAME)
3551
3547
        {
3552
3548
          /* Unique key. Check for "PRIMARY" */
3553
 
          if (! my_strcasecmp(system_charset_info,
3554
 
                              table_key->name, primary_key_name))
 
3549
          if (is_primary_key(table_key))
3555
3550
            *alter_flags|= HA_ALTER_PK_INDEX;
3556
3551
          else
3557
3552
            *alter_flags|= HA_ALTER_UNIQUE_INDEX;
3613
3608
      if (new_key->flags & HA_NOSAME)
3614
3609
      {
3615
3610
        /* Unique key. Check for "PRIMARY" */
3616
 
        if (! my_strcasecmp(system_charset_info,
3617
 
                            new_key->name, primary_key_name))
 
3611
        if (is_primary_key(new_key))
3618
3612
          *alter_flags|= HA_ADD_PK_INDEX;
3619
3613
        else
3620
3614
        *alter_flags|= HA_ADD_UNIQUE_INDEX;
3734
3728
 
3735
3729
  /*
3736
3730
    Create a table with a temporary name.
3737
 
    With create_info->frm_only == 1 this creates a .frm file only.
3738
3731
    We don't log the statement, it will be logged later.
3739
3732
  */
3740
3733
  tmp_disable_binlog(session);
3784
3777
  if (lower_case_table_names)
3785
3778
    my_casedn_str(files_charset_info, tmp_name);
3786
3779
  altered_create_info.options&= ~HA_LEX_CREATE_TMP_TABLE;
3787
 
  altered_create_info.frm_only= 1;
 
3780
 
3788
3781
  if ((error= create_temporary_table(session, table, new_db, tmp_name,
3789
3782
                                     &altered_create_info,
3790
3783
                                     alter_info, db_change)))
4276
4269
 
4277
4270
      if (key_info->flags & HA_NOSAME)
4278
4271
      {
4279
 
        if (! my_strcasecmp(system_charset_info, key_name, primary_key_name))
 
4272
        if (is_primary_key_name(key_name))
4280
4273
          key_type= Key::PRIMARY;
4281
4274
        else
4282
4275
          key_type= Key::UNIQUE;
4300
4293
        goto err;
4301
4294
      if (key->type != Key::FOREIGN_KEY)
4302
4295
        new_key_list.push_back(key);
4303
 
      if (key->name.str &&
4304
 
          !my_strcasecmp(system_charset_info, key->name.str, primary_key_name))
 
4296
      if (key->name.str && is_primary_key_name(key->name.str))
4305
4297
      {
4306
4298
        my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0), key->name.str);
4307
4299
        goto err;
4408
4400
  char path[FN_REFLEN];
4409
4401
  ha_rows copied= 0,deleted= 0;
4410
4402
  handlerton *old_db_type, *new_db_type, *save_old_db_type;
4411
 
  legacy_db_type table_type;
4412
4403
 
4413
4404
  new_name_buff[0]= '\0';
4414
4405
 
4461
4452
    into the main table list, like open_tables does).
4462
4453
    This code is wrong and will be removed, please do not copy.
4463
4454
  */
4464
 
  (void)mysql_frm_type(session, new_name_buff, &table_type);
4465
4455
 
4466
4456
  if (!(table= open_n_lock_single_table(session, table_list, TL_WRITE_ALLOW_READ)))
4467
4457
    return(true);