~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/statement/alter_table.cc

  • Committer: Lee Bieber
  • Date: 2011-03-01 22:41:46 UTC
  • mfrom: (2212.1.2 build)
  • Revision ID: kalebral@gmail.com-20110301224146-a4ulmgytz1lzb7ia
Merge Olaf - Use std::list
Merge Andrew - 724451: drizzle_escape_string doesn't handle blob data correctly

Show diffs side-by-side

added added

removed removed

Lines of Context:
249
249
                                message::Table &table_message,
250
250
                                AlterInfo *alter_info)
251
251
{
252
 
  /* New column definitions are added here */
253
 
  List<CreateField> new_create_list;
254
 
  /* New key definitions are added here */
255
 
  List<Key> new_key_list;
256
 
  List<AlterDrop>::iterator drop_it(alter_info->drop_list.begin());
257
 
  List<CreateField>::iterator def_it(alter_info->create_list.begin());
258
 
  List<AlterColumn>::iterator alter_it(alter_info->alter_list.begin());
259
 
  List<Key>::iterator key_it(alter_info->key_list.begin());
260
 
  List<CreateField>::iterator find_it(new_create_list.begin());
261
 
  List<CreateField>::iterator field_it(new_create_list.begin());
262
 
  List<Key_part_spec> key_parts;
263
252
  uint32_t used_fields= create_info->used_fields;
264
 
  KeyInfo *key_info= table->key_info;
265
 
  bool rc= true;
266
253
 
267
254
  /* Let new create options override the old ones */
268
 
  message::Table::TableOptions *table_options;
269
 
  table_options= table_message.mutable_options();
 
255
  message::Table::TableOptions *table_options= table_message.mutable_options();
270
256
 
271
257
  if (not (used_fields & HA_CREATE_USED_DEFAULT_CHARSET))
272
258
    create_info->default_table_charset= table->getShare()->table_charset;
281
267
  }
282
268
 
283
269
  table->restoreRecordAsDefault(); /* Empty record for DEFAULT */
284
 
  CreateField *def;
285
270
 
 
271
  List<CreateField> new_create_list;
 
272
  List<Key> new_key_list;
286
273
  /* First collect all fields from table which isn't in drop_list */
287
274
  Field *field;
288
275
  for (Field **f_ptr= table->getFields(); (field= *f_ptr); f_ptr++)
289
276
  {
290
277
    /* Check if field should be dropped */
291
 
    AlterDrop *drop;
292
 
    drop_it= alter_info->drop_list.begin();
293
 
    while ((drop= drop_it++))
 
278
    AlterInfo::drop_list_t::iterator drop(alter_info->drop_list.begin());
 
279
    for (; drop != alter_info->drop_list.end(); drop++)
294
280
    {
295
281
      if (drop->type == AlterDrop::COLUMN &&
296
282
          ! my_strcasecmp(system_charset_info, field->field_name, drop->name))
297
283
      {
298
284
        /* Reset auto_increment value if it was dropped */
299
285
        if (MTYP_TYPENR(field->unireg_check) == Field::NEXT_NUMBER &&
300
 
            ! (used_fields & HA_CREATE_USED_AUTO))
 
286
            not (used_fields & HA_CREATE_USED_AUTO))
301
287
        {
302
288
          create_info->auto_increment_value= 0;
303
289
          create_info->used_fields|= HA_CREATE_USED_AUTO;
306
292
      }
307
293
    }
308
294
 
309
 
    if (drop)
 
295
    if (drop != alter_info->drop_list.end())
310
296
    {
311
 
      drop_it.remove();
 
297
      alter_info->drop_list.erase(drop);
312
298
      continue;
313
299
    }
314
300
    
315
301
    /* Mark that we will read the field */
316
302
    field->setReadSet();
317
303
 
 
304
    CreateField *def;
318
305
    /* Check if field is changed */
319
 
    def_it= alter_info->create_list.begin();
 
306
    List<CreateField>::iterator def_it= alter_info->create_list.begin();
320
307
    while ((def= def_it++))
321
308
    {
322
309
      if (def->change &&
342
329
      */
343
330
      def= new CreateField(field, field);
344
331
      new_create_list.push_back(def);
345
 
      alter_it= alter_info->alter_list.begin(); /* Change default if ALTER */
346
 
      AlterColumn *alter;
 
332
      AlterInfo::alter_list_t::iterator alter(alter_info->alter_list.begin());
347
333
 
348
 
      while ((alter= alter_it++))
 
334
      for (; alter != alter_info->alter_list.end(); alter++)
349
335
      {
350
 
        if (! my_strcasecmp(system_charset_info,field->field_name, alter->name))
 
336
        if (not my_strcasecmp(system_charset_info,field->field_name, alter->name))
351
337
          break;
352
338
      }
353
339
 
354
 
      if (alter)
 
340
      if (alter != alter_info->alter_list.end())
355
341
      {
356
342
        if (def->sql_type == DRIZZLE_TYPE_BLOB)
357
343
        {
368
354
        {
369
355
          def->flags|= NO_DEFAULT_VALUE_FLAG;
370
356
        }
371
 
        alter_it.remove();
 
357
        alter_info->alter_list.erase(alter);
372
358
      }
373
359
    }
374
360
  }
375
361
 
376
 
  def_it= alter_info->create_list.begin();
 
362
  CreateField *def;
 
363
  List<CreateField>::iterator def_it= alter_info->create_list.begin();
377
364
  while ((def= def_it++)) /* Add new columns */
378
365
  {
379
366
    if (def->change && ! def->field)
399
386
    else
400
387
    {
401
388
      CreateField *find;
402
 
      find_it= new_create_list.begin();
 
389
      List<CreateField>::iterator find_it= new_create_list.begin();
403
390
 
404
391
      while ((find= find_it++)) /* Add new columns */
405
392
      {
430
417
        my_error(*session->getQueryString(), ER_NOT_SUPPORTED_YET);
431
418
        return true;
432
419
      }
433
 
 
434
420
      alter_info->build_method= HA_BUILD_OFFLINE;
435
421
    }
436
422
  }
437
423
 
438
 
  if (alter_info->alter_list.size())
 
424
  if (not alter_info->alter_list.empty())
439
425
  {
440
 
    my_error(ER_BAD_FIELD_ERROR,
441
 
             MYF(0),
442
 
             alter_info->alter_list.front().name,
443
 
             table->getMutableShare()->getTableName());
 
426
    my_error(ER_BAD_FIELD_ERROR, MYF(0), alter_info->alter_list.front().name, table->getMutableShare()->getTableName());
444
427
    return true;
445
428
  }
446
429
 
447
 
  if (not new_create_list.size())
 
430
  if (new_create_list.is_empty())
448
431
  {
449
 
    my_message(ER_CANT_REMOVE_ALL_FIELDS,
450
 
               ER(ER_CANT_REMOVE_ALL_FIELDS),
451
 
               MYF(0));
 
432
    my_message(ER_CANT_REMOVE_ALL_FIELDS, ER(ER_CANT_REMOVE_ALL_FIELDS), MYF(0));
452
433
    return true;
453
434
  }
454
435
 
456
437
    Collect all keys which isn't in drop list. Add only those
457
438
    for which some fields exists.
458
439
  */
 
440
  KeyInfo *key_info= table->key_info;
459
441
  for (uint32_t i= 0; i < table->getShare()->sizeKeys(); i++, key_info++)
460
442
  {
461
443
    char *key_name= key_info->name;
462
 
    AlterDrop *drop;
463
 
 
464
 
    drop_it= alter_info->drop_list.begin();
465
 
    while ((drop= drop_it++))
 
444
    AlterInfo::drop_list_t::iterator drop(alter_info->drop_list.begin());
 
445
    for (; drop != alter_info->drop_list.end(); drop++)
466
446
    {
467
447
      if (drop->type == AlterDrop::KEY &&
468
 
          ! my_strcasecmp(system_charset_info, key_name, drop->name))
 
448
          not my_strcasecmp(system_charset_info, key_name, drop->name))
469
449
        break;
470
450
    }
471
451
 
472
 
    if (drop)
 
452
    if (drop != alter_info->drop_list.end())
473
453
    {
474
 
      drop_it.remove();
 
454
      alter_info->drop_list.erase(drop);
475
455
      continue;
476
456
    }
477
457
 
478
458
    KeyPartInfo *key_part= key_info->key_part;
479
 
    key_parts.clear();
 
459
    List<Key_part_spec> key_parts;
480
460
    for (uint32_t j= 0; j < key_info->key_parts; j++, key_part++)
481
461
    {
482
462
      if (! key_part->field)
484
464
 
485
465
      const char *key_part_name= key_part->field->field_name;
486
466
      CreateField *cfield;
487
 
      field_it= new_create_list.begin();
 
467
      List<CreateField>::iterator field_it= new_create_list.begin();
488
468
      while ((cfield= field_it++))
489
469
      {
490
470
        if (cfield->change)
565
545
  /* Copy over existing foreign keys */
566
546
  for (int32_t j= 0; j < original_proto.fk_constraint_size(); j++)
567
547
  {
568
 
    AlterDrop *drop;
569
 
    drop_it= alter_info->drop_list.begin();
570
 
    while ((drop= drop_it++))
 
548
    AlterInfo::drop_list_t::iterator drop(alter_info->drop_list.begin());
 
549
    for (; drop != alter_info->drop_list.end(); drop++)
571
550
    {
572
551
      if (drop->type == AlterDrop::FOREIGN_KEY &&
573
 
          ! my_strcasecmp(system_charset_info, original_proto.fk_constraint(j).name().c_str(), drop->name))
 
552
          not my_strcasecmp(system_charset_info, original_proto.fk_constraint(j).name().c_str(), drop->name))
574
553
      {
575
554
        break;
576
555
      }
577
556
    }
578
 
    if (drop)
 
557
    if (drop != alter_info->drop_list.end())
579
558
    {
580
 
      drop_it.remove();
 
559
      alter_info->drop_list.erase(drop);
581
560
      continue;
582
561
    }
583
562
 
587
566
 
588
567
  {
589
568
    Key *key;
 
569
    List<Key>::iterator key_it(alter_info->key_list.begin());
590
570
    while ((key= key_it++)) /* Add new keys */
591
571
    {
592
572
      if (key->type == Key::FOREIGN_KEY)
637
617
    }
638
618
  }
639
619
 
640
 
  if (alter_info->drop_list.size())
 
620
  if (not alter_info->drop_list.empty())
641
621
  {
642
622
    my_error(ER_CANT_DROP_FIELD_OR_KEY,
643
623
             MYF(0),
645
625
    return true;
646
626
  }
647
627
 
648
 
  if (alter_info->alter_list.size())
 
628
  if (not alter_info->alter_list.empty())
649
629
  {
650
630
    my_error(ER_CANT_DROP_FIELD_OR_KEY,
651
631
             MYF(0),
668
648
  table_message.set_version(table->getShare()->getTableMessage()->version());
669
649
  table_message.set_uuid(table->getShare()->getTableMessage()->uuid());
670
650
 
671
 
  rc= false;
672
651
  alter_info->create_list.swap(new_create_list);
673
652
  alter_info->key_list.swap(new_key_list);
674
653
 
701
680
}
702
681
 
703
682
/* table_list should contain just one table */
704
 
static int discard_or_import_tablespace(Session *session,
705
 
                                              TableList *table_list,
706
 
                                              enum tablespace_op_type tablespace_op)
 
683
static int discard_or_import_tablespace(Session *session, TableList *table_list, tablespace_op_type tablespace_op)
707
684
{
708
 
  Table *table;
709
 
  bool discard;
710
 
 
711
685
  /*
712
686
    Note that DISCARD/IMPORT TABLESPACE always is the only operation in an
713
687
    ALTER Table
715
689
  TransactionServices &transaction_services= TransactionServices::singleton();
716
690
  session->set_proc_info("discard_or_import_tablespace");
717
691
 
718
 
  discard= test(tablespace_op == DISCARD_TABLESPACE);
719
 
 
720
692
 /*
721
693
   We set this flag so that ha_innobase::open and ::external_lock() do
722
694
   not complain when we lock the table
723
695
 */
724
696
  session->setDoingTablespaceOperation(true);
725
 
  if (not (table= session->openTableLock(table_list, TL_WRITE)))
 
697
  Table* table= session->openTableLock(table_list, TL_WRITE);
 
698
  if (not table)
726
699
  {
727
700
    session->setDoingTablespaceOperation(false);
728
701
    return -1;
730
703
 
731
704
  int error;
732
705
  do {
733
 
    error= table->cursor->ha_discard_or_import_tablespace(discard);
 
706
    error= table->cursor->ha_discard_or_import_tablespace(tablespace_op == DISCARD_TABLESPACE);
734
707
 
735
708
    session->set_proc_info("end");
736
709
 
1486
1459
  to->cursor->ha_start_bulk_insert(from->cursor->stats.records);
1487
1460
 
1488
1461
  List<CreateField>::iterator it(create.begin());
1489
 
  CreateField *def;
1490
1462
  copy_end= copy;
1491
1463
  for (Field **ptr= to->getFields(); *ptr ; ptr++)
1492
1464
  {
1493
 
    def=it++;
 
1465
    CreateField* def=it++;
1494
1466
    if (def->field)
1495
1467
    {
1496
1468
      if (*ptr == to->next_number_field)
1660
1632
 
1661
1633
static Table *open_alter_table(Session *session, Table *table, identifier::Table &identifier)
1662
1634
{
1663
 
  Table *new_table;
1664
 
 
1665
1635
  /* Open the table so we need to copy the data to it. */
1666
1636
  if (table->getShare()->getType())
1667
1637
  {
1671
1641
    tbl.setTableName(const_cast<char *>(identifier.getTableName().c_str()));
1672
1642
 
1673
1643
    /* Table is in session->temporary_tables */
1674
 
    new_table= session->openTable(&tbl, (bool*) 0, DRIZZLE_LOCK_IGNORE_FLUSH);
 
1644
    return session->openTable(&tbl, (bool*) 0, DRIZZLE_LOCK_IGNORE_FLUSH);
1675
1645
  }
1676
1646
  else
1677
1647
  {
1678
1648
    /* Open our intermediate table */
1679
 
    new_table= session->open_temporary_table(identifier, false);
 
1649
    return session->open_temporary_table(identifier, false);
1680
1650
  }
1681
 
 
1682
 
  return new_table;
1683
1651
}
1684
1652
 
1685
1653
} /* namespace drizzled */