~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/statement/alter_table.cc

  • Committer: Stewart Smith
  • Date: 2010-06-16 14:23:07 UTC
  • mto: (1626.1.3 build)
  • mto: This revision was merged to the branch mainline in revision 1633.
  • Revision ID: stewart@flamingspork.com-20100616142307-xzid4yzriltwu6tt
add basic test for Handler_update status variable

Show diffs side-by-side

added added

removed removed

Lines of Context:
44
44
 
45
45
#include "drizzled/transaction_services.h"
46
46
 
47
 
#include "drizzled/filesort.h"
48
 
 
49
 
#include "drizzled/message.h"
50
 
 
51
47
using namespace std;
52
48
 
53
49
namespace drizzled
60
56
                                    List<CreateField> &create,
61
57
                                    bool ignore,
62
58
                                    uint32_t order_num,
63
 
                                    Order *order,
 
59
                                    order_st *order,
64
60
                                    ha_rows *copied,
65
61
                                    ha_rows *deleted,
66
62
                                    enum enum_enable_or_disable keys_onoff,
107
103
  assert(select_lex->db);
108
104
 
109
105
  /* Chicken/Egg... we need to search for the table, to know if the table exists, so we can build a full identifier from it */
110
 
  message::table::shared_ptr original_table_message;
 
106
  message::Table original_table_message;
111
107
  {
112
 
    TableIdentifier identifier(first_table->getSchemaName(), first_table->getTableName());
 
108
    TableIdentifier identifier(first_table->db, first_table->table_name);
113
109
    if (plugin::StorageEngine::getTableDefinition(*session, identifier, original_table_message) != EEXIST)
114
110
    {
115
 
      std::string path;
116
 
      identifier.getSQLPath(path);
117
 
      my_error(ER_BAD_TABLE_ERROR, MYF(0), path.c_str());
 
111
      my_error(ER_BAD_TABLE_ERROR, MYF(0), identifier.getSQLPath().c_str());
118
112
      return true;
119
113
    }
120
114
 
121
115
    if (not  create_info.db_type)
122
116
    {
123
117
      create_info.db_type= 
124
 
        plugin::StorageEngine::findByName(*session, original_table_message->engine().name());
 
118
        plugin::StorageEngine::findByName(*session, original_table_message.engine().name());
125
119
 
126
120
      if (not create_info.db_type)
127
121
      {
128
 
        std::string path;
129
 
        identifier.getSQLPath(path);
130
 
        my_error(ER_BAD_TABLE_ERROR, MYF(0), path.c_str());
 
122
        my_error(ER_BAD_TABLE_ERROR, MYF(0), identifier.getSQLPath().c_str());
131
123
        return true;
132
124
      }
133
125
    }
134
126
  }
135
127
 
136
128
  if (not validateCreateTableOption())
 
129
  {
137
130
    return true;
 
131
  }
138
132
 
139
133
  /* ALTER TABLE ends previous transaction */
140
134
  if (not session->endActiveTransaction())
 
135
  {
141
136
    return true;
 
137
  }
142
138
 
143
 
  if (not (need_start_waiting= not session->wait_if_global_read_lock(0, 1)))
 
139
  if (not (need_start_waiting= ! wait_if_global_read_lock(session, 0, 1)))
 
140
  {
144
141
    return true;
 
142
  }
145
143
 
146
144
  bool res;
147
 
  if (original_table_message->type() == message::Table::STANDARD )
 
145
  if (original_table_message.type() == message::Table::STANDARD )
148
146
  {
149
 
    TableIdentifier identifier(first_table->getSchemaName(), first_table->getTableName());
150
 
    TableIdentifier new_identifier(select_lex->db ? select_lex->db : first_table->getSchemaName(),
151
 
                                   session->lex->name.str ? session->lex->name.str : first_table->getTableName());
 
147
    TableIdentifier identifier(first_table->db, first_table->table_name);
 
148
    TableIdentifier new_identifier(select_lex->db ? select_lex->db : first_table->db,
 
149
                                   session->lex->name.str ? session->lex->name.str : first_table->table_name);
152
150
 
153
151
    res= alter_table(session, 
154
152
                     identifier,
155
153
                     new_identifier,
156
154
                     &create_info,
157
 
                     *original_table_message,
 
155
                     original_table_message,
158
156
                     create_table_message,
159
157
                     first_table,
160
158
                     &alter_info,
161
159
                     select_lex->order_list.elements,
162
 
                     (Order *) select_lex->order_list.first,
 
160
                     (order_st *) select_lex->order_list.first,
163
161
                     session->lex->ignore);
164
162
  }
165
163
  else
166
164
  {
167
 
    TableIdentifier catch22(first_table->getSchemaName(), first_table->getTableName());
168
 
    Table *table= session->find_temporary_table(catch22);
 
165
    Table *table= session->find_temporary_table(first_table);
169
166
    assert(table);
170
167
    {
171
 
      TableIdentifier identifier(first_table->getSchemaName(), first_table->getTableName(), table->getMutableShare()->getPath());
172
 
      TableIdentifier new_identifier(select_lex->db ? select_lex->db : first_table->getSchemaName(),
173
 
                                     session->lex->name.str ? session->lex->name.str : first_table->getTableName(),
 
168
      TableIdentifier identifier(first_table->db, first_table->table_name, table->getMutableShare()->getPath());
 
169
      TableIdentifier new_identifier(select_lex->db ? select_lex->db : first_table->db,
 
170
                                     session->lex->name.str ? session->lex->name.str : first_table->table_name,
174
171
                                     table->getMutableShare()->getPath());
175
172
 
176
173
      res= alter_table(session, 
177
174
                       identifier,
178
175
                       new_identifier,
179
176
                       &create_info,
180
 
                       *original_table_message,
 
177
                       original_table_message,
181
178
                       create_table_message,
182
179
                       first_table,
183
180
                       &alter_info,
184
181
                       select_lex->order_list.elements,
185
 
                       (Order *) select_lex->order_list.first,
 
182
                       (order_st *) select_lex->order_list.first,
186
183
                       session->lex->ignore);
187
184
    }
188
185
  }
191
188
     Release the protection against the global read lock and wake
192
189
     everyone, who might want to set a global read lock.
193
190
   */
194
 
  session->startWaitingGlobalReadLock();
195
 
 
 
191
  start_waiting_global_read_lock(session);
196
192
  return res;
197
193
}
198
194
 
271
267
    /* Table has an autoincrement, copy value to new table */
272
268
    table->cursor->info(HA_STATUS_AUTO);
273
269
    create_info->auto_increment_value= table->cursor->stats.auto_increment_value;
274
 
    if (create_info->auto_increment_value != original_proto.options().auto_increment_value())
275
 
      table_options->set_has_user_set_auto_increment_value(false);
276
270
  }
277
271
  table->restoreRecordAsDefault(); /* Empty record for DEFAULT */
278
272
  CreateField *def;
347
341
        if (def->sql_type == DRIZZLE_TYPE_BLOB)
348
342
        {
349
343
          my_error(ER_BLOB_CANT_HAVE_DEFAULT, MYF(0), def->change);
350
 
          return true;
 
344
                goto err;
351
345
        }
352
346
        if ((def->def= alter->def))
353
347
        {
355
349
          def->flags&= ~NO_DEFAULT_VALUE_FLAG;
356
350
        }
357
351
        else
358
 
        {
359
352
          def->flags|= NO_DEFAULT_VALUE_FLAG;
360
 
        }
361
353
        alter_it.remove();
362
354
      }
363
355
    }
368
360
    if (def->change && ! def->field)
369
361
    {
370
362
      my_error(ER_BAD_FIELD_ERROR, MYF(0), def->change, table->getMutableShare()->getTableName());
371
 
      return true;
 
363
      goto err;
372
364
    }
373
365
    /*
374
 
      If we have been given a field which has no default value, and is not null then we need to bail.
 
366
      Check that the DATE/DATETIME not null field we are going to add is
 
367
      either has a default value or the '0000-00-00' is allowed by the
 
368
      set sql mode.
 
369
      If the '0000-00-00' value isn't allowed then raise the error_if_not_empty
 
370
      flag to allow ALTER Table only if the table to be altered is empty.
375
371
    */
376
 
    if (not (~def->flags & (NO_DEFAULT_VALUE_FLAG | NOT_NULL_FLAG)) and not def->change)
 
372
    if ((def->sql_type == DRIZZLE_TYPE_DATE ||
 
373
         def->sql_type == DRIZZLE_TYPE_DATETIME) &&
 
374
        ! alter_info->datetime_field &&
 
375
        ! (~def->flags & (NO_DEFAULT_VALUE_FLAG | NOT_NULL_FLAG)))
377
376
    {
 
377
      alter_info->datetime_field= def;
378
378
      alter_info->error_if_not_empty= true;
379
379
    }
380
380
    if (! def->after)
381
 
    {
382
381
      new_create_list.push_back(def);
383
 
    }
384
382
    else if (def->after == first_keyword)
385
 
    {
386
383
      new_create_list.push_front(def);
387
 
    }
388
384
    else
389
385
    {
390
386
      CreateField *find;
397
393
      if (! find)
398
394
      {
399
395
        my_error(ER_BAD_FIELD_ERROR, MYF(0), def->after, table->getMutableShare()->getTableName());
400
 
        return true;
 
396
        goto err;
401
397
      }
402
398
      find_it.after(def); /* Put element after this */
403
399
      /*
412
408
      */
413
409
      if (alter_info->build_method == HA_BUILD_ONLINE)
414
410
      {
415
 
        my_error(ER_NOT_SUPPORTED_YET, MYF(0), session->getQueryString()->c_str());
416
 
        return true;
 
411
        my_error(ER_NOT_SUPPORTED_YET, MYF(0), session->query.c_str());
 
412
        goto err;
417
413
      }
418
414
      alter_info->build_method= HA_BUILD_OFFLINE;
419
415
    }
424
420
             MYF(0),
425
421
             alter_info->alter_list.head()->name,
426
422
             table->getMutableShare()->getTableName());
427
 
    return true;
 
423
    goto err;
428
424
  }
429
425
  if (! new_create_list.elements)
430
426
  {
431
427
    my_message(ER_CANT_REMOVE_ALL_FIELDS,
432
428
               ER(ER_CANT_REMOVE_ALL_FIELDS),
433
429
               MYF(0));
434
 
    return true;
 
430
    goto err;
435
431
  }
436
432
 
437
433
  /*
537
533
      new_key_list.push_back(key);
538
534
    }
539
535
  }
540
 
 
541
 
  /* Copy over existing foreign keys */
542
 
  for (int j= 0; j < original_proto.fk_constraint_size(); j++)
543
 
  {
544
 
    AlterDrop *drop;
545
 
    drop_it.rewind();
546
 
    while ((drop= drop_it++))
547
 
    {
548
 
      if (drop->type == AlterDrop::FOREIGN_KEY &&
549
 
          ! my_strcasecmp(system_charset_info, original_proto.fk_constraint(j).name().c_str(), drop->name))
550
 
      {
551
 
        break;
552
 
      }
553
 
    }
554
 
    if (drop)
555
 
    {
556
 
      drop_it.remove();
557
 
      continue;
558
 
    }
559
 
 
560
 
    message::Table::ForeignKeyConstraint *pfkey= table_message.add_fk_constraint();
561
 
    *pfkey= original_proto.fk_constraint(j);
562
 
  }
563
 
 
564
536
  {
565
537
    Key *key;
566
538
    while ((key= key_it++)) /* Add new keys */
567
539
    {
568
 
      if (key->type == Key::FOREIGN_KEY)
569
 
      {
570
 
        if (((Foreign_key *)key)->validate(new_create_list))
571
 
        {
572
 
          return true;
573
 
        }
574
 
 
575
 
        Foreign_key *fkey= (Foreign_key*)key;
576
 
        add_foreign_key_to_table_message(&table_message,
577
 
                                         fkey->name.str,
578
 
                                         fkey->columns,
579
 
                                         fkey->ref_table,
580
 
                                         fkey->ref_columns,
581
 
                                         fkey->delete_opt,
582
 
                                         fkey->update_opt,
583
 
                                         fkey->match_opt);
584
 
      }
585
 
 
 
540
      if (key->type == Key::FOREIGN_KEY &&
 
541
          ((Foreign_key *)key)->validate(new_create_list))
 
542
        goto err;
586
543
      if (key->type != Key::FOREIGN_KEY)
587
544
        new_key_list.push_back(key);
588
 
 
589
545
      if (key->name.str && is_primary_key_name(key->name.str))
590
546
      {
591
547
        my_error(ER_WRONG_NAME_FOR_INDEX,
592
548
                 MYF(0),
593
549
                 key->name.str);
594
 
        return true;
 
550
        goto err;
595
551
      }
596
552
    }
597
553
  }
598
554
 
599
 
  /* Fix names of foreign keys being added */
600
 
  for (int j= 0; j < table_message.fk_constraint_size(); j++)
601
 
  {
602
 
    if (! table_message.fk_constraint(j).has_name())
603
 
    {
604
 
      std::string name(table->getMutableShare()->getTableName());
605
 
      char number[20];
606
 
 
607
 
      name.append("_ibfk_");
608
 
      snprintf(number, sizeof(number), "%d", j+1);
609
 
      name.append(number);
610
 
 
611
 
      message::Table::ForeignKeyConstraint *pfkey= table_message.mutable_fk_constraint(j);
612
 
      pfkey->set_name(name);
613
 
    }
614
 
  }
615
 
 
616
555
  if (alter_info->drop_list.elements)
617
556
  {
618
557
    my_error(ER_CANT_DROP_FIELD_OR_KEY,
619
558
             MYF(0),
620
559
             alter_info->drop_list.head()->name);
621
 
    return true;
 
560
    goto err;
622
561
  }
623
562
  if (alter_info->alter_list.elements)
624
563
  {
625
564
    my_error(ER_CANT_DROP_FIELD_OR_KEY,
626
565
             MYF(0),
627
566
             alter_info->alter_list.head()->name);
628
 
    return true;
 
567
    goto err;
629
568
  }
630
569
 
631
570
  if (not table_message.options().has_comment()
638
577
  }
639
578
 
640
579
  table_message.set_creation_timestamp(table->getShare()->getTableProto()->creation_timestamp());
641
 
  table_message.set_version(table->getShare()->getTableProto()->version());
642
 
  table_message.set_uuid(table->getShare()->getTableProto()->uuid());
 
580
 
 
581
  table_message.set_update_timestamp(time(NULL));
643
582
 
644
583
  rc= false;
645
584
  alter_info->create_list.swap(new_create_list);
646
585
  alter_info->key_list.swap(new_key_list);
 
586
err:
647
587
 
648
588
  size_t num_engine_options= table_message.engine().options_size();
649
589
  size_t original_num_engine_options= original_proto.engine().options_size();
668
608
    }
669
609
  }
670
610
 
671
 
  drizzled::message::update(table_message);
672
 
 
673
 
  return false;
 
611
  return rc;
674
612
}
675
613
 
676
614
/* table_list should contain just one table */
712
650
 
713
651
  /* The ALTER Table is always in its own transaction */
714
652
  error= transaction_services.autocommitOrRollback(session, false);
715
 
  if (not session->endActiveTransaction())
 
653
  if (! session->endActiveTransaction())
716
654
    error=1;
717
 
 
718
655
  if (error)
719
656
    goto err;
720
 
 
721
 
  write_bin_log(session, *session->getQueryString());
 
657
  write_bin_log(session, session->query.c_str());
722
658
 
723
659
err:
724
660
  (void) transaction_services.autocommitOrRollback(session, error);
791
727
 
792
728
      if (session.find_temporary_table(new_table_identifier))
793
729
      {
794
 
        std::string path;
795
 
        new_table_identifier.getSQLPath(path);
796
 
        my_error(ER_TABLE_EXISTS_ERROR, MYF(0), path.c_str());
 
730
        my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_table_identifier.getSQLPath().c_str());
797
731
        return false;
798
732
      }
799
733
    }
806
740
 
807
741
      if (not name_lock)
808
742
      {
809
 
        std::string path;
810
 
        new_table_identifier.getSQLPath(path);
811
 
        my_error(ER_TABLE_EXISTS_ERROR, MYF(0), path.c_str());
 
743
        my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_table_identifier.getSQLPath().c_str());
812
744
        return false;
813
745
      }
814
746
 
815
747
      if (plugin::StorageEngine::doesTableExist(session, new_table_identifier))
816
748
      {
817
 
        std::string path;
818
 
        new_table_identifier.getSQLPath(path);
819
 
 
820
749
        /* Table will be closed by Session::executeCommand() */
821
 
        my_error(ER_TABLE_EXISTS_ERROR, MYF(0), path.c_str());
 
750
        my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_table_identifier.getSQLPath().c_str());
822
751
 
823
 
        table::Cache::singleton().mutex().lock(); /* ALTER TABLe */
 
752
        pthread_mutex_lock(&LOCK_open); /* ALTER TABLe */
824
753
        session.unlink_open_table(name_lock);
825
 
        table::Cache::singleton().mutex().unlock();
 
754
        pthread_mutex_unlock(&LOCK_open);
826
755
 
827
756
        return false;
828
757
      }
884
813
                                 TableList *table_list,
885
814
                                 AlterInfo *alter_info,
886
815
                                 uint32_t order_num,
887
 
                                 Order *order,
 
816
                                 order_st *order,
888
817
                                 bool ignore)
889
818
{
 
819
  Table *new_table= NULL;
890
820
  int error= 0;
891
821
  char tmp_name[80];
892
822
  char old_name[32];
893
823
  ha_rows copied= 0;
894
824
  ha_rows deleted= 0;
895
825
 
896
 
  if (not original_table_identifier.isValid())
897
 
    return true;
898
 
 
899
 
  if (not new_table_identifier.isValid())
900
 
    return true;
 
826
  message::Table *original_table_definition= table->getMutableShare()->getTableProto();
901
827
 
902
828
  session->set_proc_info("init");
903
829
 
934
860
  if (original_engine->check_flag(HTON_BIT_ALTER_NOT_SUPPORTED) ||
935
861
      new_engine->check_flag(HTON_BIT_ALTER_NOT_SUPPORTED))
936
862
  {
937
 
    std::string path;
938
 
    new_table_identifier.getSQLPath(path);
939
 
    my_error(ER_ILLEGAL_HA, MYF(0), path.c_str());
 
863
    my_error(ER_ILLEGAL_HA, MYF(0), new_table_identifier.getSQLPath().c_str());
940
864
 
941
865
    return true;
942
866
  }
943
867
 
 
868
  if (create_info->row_type == ROW_TYPE_NOT_USED)
 
869
  {
 
870
    message::Table::TableOptions *table_options;
 
871
    table_options= create_proto.mutable_options();
 
872
 
 
873
    create_info->row_type= table->getShare()->row_type;
 
874
    table_options->set_row_type(original_table_definition->options().row_type());
 
875
  }
 
876
 
944
877
  session->set_proc_info("setup");
945
878
 
946
879
  /*
970
903
          while the fact that the table is still open gives us protection
971
904
          from concurrent DDL statements.
972
905
        */
973
 
        table::Cache::singleton().mutex().lock(); /* DDL wait for/blocker */
 
906
        pthread_mutex_lock(&LOCK_open); /* DDL wait for/blocker */
974
907
        wait_while_table_is_used(session, table, HA_EXTRA_FORCE_REOPEN);
975
 
        table::Cache::singleton().mutex().unlock();
 
908
        pthread_mutex_unlock(&LOCK_open);
976
909
        error= table->cursor->ha_enable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
977
910
        /* COND_refresh will be signaled in close_thread_tables() */
978
911
        break;
979
912
      case DISABLE:
980
 
        table::Cache::singleton().mutex().lock(); /* DDL wait for/blocker */
 
913
        pthread_mutex_lock(&LOCK_open); /* DDL wait for/blocker */
981
914
        wait_while_table_is_used(session, table, HA_EXTRA_FORCE_REOPEN);
982
 
        table::Cache::singleton().mutex().unlock();
 
915
        pthread_mutex_unlock(&LOCK_open);
983
916
        error=table->cursor->ha_disable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
984
917
        /* COND_refresh will be signaled in close_thread_tables() */
985
918
        break;
994
927
        error= 0;
995
928
        push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
996
929
                            ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA),
997
 
                            table->getAlias());
 
930
                            table->alias);
998
931
      }
999
932
 
1000
 
      table::Cache::singleton().mutex().lock(); /* Lock to remove all instances of table from table cache before ALTER */
 
933
      pthread_mutex_lock(&LOCK_open); /* Lock to remove all instances of table from table cache before ALTER */
1001
934
      /*
1002
935
        Unlike to the above case close_cached_table() below will remove ALL
1003
936
        instances of Table from table cache (it will also remove table lock
1004
937
        held by this thread). So to make actual table renaming and writing
1005
938
        to binlog atomic we have to put them into the same critical section
1006
 
        protected by table::Cache::singleton().mutex() mutex. This also removes gap for races between
 
939
        protected by LOCK_open mutex. This also removes gap for races between
1007
940
        access() and mysql_rename_table() calls.
1008
941
      */
1009
942
 
1025
958
        */
1026
959
        if (plugin::StorageEngine::doesTableExist(*session, new_table_identifier))
1027
960
        {
1028
 
          std::string path;
1029
 
          new_table_identifier.getSQLPath(path);
1030
 
          my_error(ER_TABLE_EXISTS_ERROR, MYF(0), path.c_str());
 
961
          my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_table_identifier.getSQLPath().c_str());
1031
962
          error= -1;
1032
963
        }
1033
964
        else
1044
975
        error= 0;
1045
976
        push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
1046
977
                            ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA),
1047
 
                            table->getAlias());
 
978
                            table->alias);
1048
979
      }
1049
980
 
1050
981
      if (error == 0)
1051
982
      {
1052
 
        TransactionServices &transaction_services= TransactionServices::singleton();
1053
 
        transaction_services.allocateNewTransactionId();
1054
 
        write_bin_log(session, *session->getQueryString());
 
983
        write_bin_log(session, session->query.c_str());
1055
984
        session->my_ok();
1056
985
      }
1057
986
      else if (error > 0)
1060
989
        error= -1;
1061
990
      }
1062
991
 
1063
 
      table::Cache::singleton().mutex().unlock();
 
992
      pthread_mutex_unlock(&LOCK_open);
1064
993
      table_list->table= NULL;
1065
994
 
1066
995
      return error;
1100
1029
  }
1101
1030
 
1102
1031
  /* Open the table so we need to copy the data to it. */
1103
 
  Table *new_table= open_alter_table(session, table, new_table_as_temporary);
1104
 
 
 
1032
  new_table= open_alter_table(session, table, new_table_as_temporary);
1105
1033
 
1106
1034
  if (not new_table)
1107
1035
  {
1108
 
    plugin::StorageEngine::dropTable(*session, new_table_as_temporary);
 
1036
    quick_rm_table(*session, new_table_as_temporary);
1109
1037
    return true;
1110
1038
  }
1111
1039
 
1112
1040
  /* Copy the data if necessary. */
1113
1041
  {
1114
 
    /* We must not ignore bad input! */
1115
 
    session->count_cuted_fields= CHECK_FIELD_ERROR_FOR_NULL;    // calc cuted fields
 
1042
    session->count_cuted_fields= CHECK_FIELD_WARN;      // calc cuted fields
1116
1043
    session->cuted_fields= 0L;
1117
1044
    session->set_proc_info("copy to tmp table");
1118
1045
    copied= deleted= 0;
1133
1060
                                    alter_info->error_if_not_empty);
1134
1061
 
1135
1062
    /* We must not ignore bad input! */
1136
 
    assert(session->count_cuted_fields == CHECK_FIELD_ERROR_FOR_NULL);
 
1063
    session->count_cuted_fields= CHECK_FIELD_ERROR_FOR_NULL;
1137
1064
  }
1138
1065
 
1139
1066
  /* Now we need to resolve what just happened with the data copy. */
1149
1076
    */
1150
1077
    if (alter_info->error_if_not_empty && session->row_count)
1151
1078
    {
1152
 
      my_error(ER_INVALID_ALTER_TABLE_FOR_NOT_NULL, MYF(0));
 
1079
      const char *f_val= 0;
 
1080
      enum enum_drizzle_timestamp_type t_type= DRIZZLE_TIMESTAMP_DATE;
 
1081
 
 
1082
      switch (alter_info->datetime_field->sql_type)
 
1083
      {
 
1084
      case DRIZZLE_TYPE_DATE:
 
1085
        f_val= "0000-00-00";
 
1086
        t_type= DRIZZLE_TIMESTAMP_DATE;
 
1087
        break;
 
1088
      case DRIZZLE_TYPE_DATETIME:
 
1089
        f_val= "0000-00-00 00:00:00";
 
1090
        t_type= DRIZZLE_TIMESTAMP_DATETIME;
 
1091
        break;
 
1092
      default:
 
1093
        /* Shouldn't get here. */
 
1094
        assert(0);
 
1095
      }
 
1096
      bool save_abort_on_warning= session->abort_on_warning;
 
1097
      session->abort_on_warning= true;
 
1098
      make_truncated_value_warning(session, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
 
1099
                                   f_val, internal::strlength(f_val), t_type,
 
1100
                                   alter_info->datetime_field->field_name);
 
1101
      session->abort_on_warning= save_abort_on_warning;
1153
1102
    }
1154
1103
 
1155
1104
    if (original_table_identifier.isTmp())
1161
1110
      }
1162
1111
      else
1163
1112
      {
1164
 
        plugin::StorageEngine::dropTable(*session, new_table_as_temporary);
 
1113
        quick_rm_table(*session, new_table_as_temporary);
1165
1114
      }
1166
1115
 
1167
1116
      return true;
1177
1126
        new_table->intern_close_table();
1178
1127
        if (new_table->hasShare())
1179
1128
        {
1180
 
          delete new_table->getMutableShare();
 
1129
          assert(new_table->getShare()->newed);
 
1130
          delete new_table->s;
 
1131
          new_table->s= NULL;
1181
1132
        }
1182
1133
 
1183
 
        delete new_table;
 
1134
        free(new_table);
1184
1135
      }
1185
1136
 
1186
 
      table::Cache::singleton().mutex().lock(); /* ALTER TABLE */
 
1137
      pthread_mutex_lock(&LOCK_open); /* ALTER TABLE */
1187
1138
 
1188
 
      plugin::StorageEngine::dropTable(*session, new_table_as_temporary);
1189
 
      table::Cache::singleton().mutex().unlock();
 
1139
      quick_rm_table(*session, new_table_as_temporary);
 
1140
      pthread_mutex_unlock(&LOCK_open);
1190
1141
 
1191
1142
      return true;
1192
1143
    }
1197
1148
    /* Close lock if this is a transactional table */
1198
1149
    if (session->lock)
1199
1150
    {
1200
 
      session->unlockTables(session->lock);
 
1151
      mysql_unlock_tables(session, session->lock);
1201
1152
      session->lock= 0;
1202
1153
    }
1203
1154
 
1227
1178
 
1228
1179
      if (new_table->hasShare())
1229
1180
      {
1230
 
        delete new_table->getMutableShare();
 
1181
        assert(new_table->getShare()->newed);
 
1182
        delete new_table->s;
 
1183
        new_table->s= NULL;
1231
1184
      }
1232
1185
 
1233
 
      delete new_table;
 
1186
      free(new_table);
1234
1187
    }
1235
1188
 
1236
 
    table::Cache::singleton().mutex().lock(); /* ALTER TABLE */
 
1189
    pthread_mutex_lock(&LOCK_open); /* ALTER TABLE */
1237
1190
 
1238
1191
    /*
1239
1192
      Data is copied. Now we:
1272
1225
      compare_table(). Then, we need one additional call to
1273
1226
    */
1274
1227
    TableIdentifier original_table_to_drop(original_table_identifier.getSchemaName(),
1275
 
                                           old_name, create_proto.type() != message::Table::TEMPORARY ? message::Table::INTERNAL :
1276
 
                                         message::Table::TEMPORARY);
 
1228
                                           old_name, message::Table::TEMPORARY);
1277
1229
 
1278
1230
    if (mysql_rename_table(*session, original_engine, original_table_identifier, original_table_to_drop))
1279
1231
    {
1280
1232
      error= 1;
1281
 
      plugin::StorageEngine::dropTable(*session, new_table_as_temporary);
 
1233
      quick_rm_table(*session, new_table_as_temporary);
1282
1234
    }
1283
1235
    else
1284
1236
    {
1287
1239
        /* Try to get everything back. */
1288
1240
        error= 1;
1289
1241
 
1290
 
        plugin::StorageEngine::dropTable(*session, new_table_identifier);
 
1242
        quick_rm_table(*session, new_table_identifier);
1291
1243
 
1292
 
        plugin::StorageEngine::dropTable(*session, new_table_as_temporary);
 
1244
        quick_rm_table(*session, new_table_as_temporary);
1293
1245
 
1294
1246
        mysql_rename_table(*session, original_engine, original_table_to_drop, original_table_identifier);
1295
1247
      }
1296
1248
      else
1297
1249
      {
1298
 
        plugin::StorageEngine::dropTable(*session, original_table_to_drop);
 
1250
        quick_rm_table(*session, original_table_to_drop);
1299
1251
      }
1300
1252
    }
1301
1253
 
1307
1259
        from list of open tables list and table cache.
1308
1260
      */
1309
1261
      session->unlink_open_table(table);
1310
 
      table::Cache::singleton().mutex().unlock();
 
1262
      pthread_mutex_unlock(&LOCK_open);
1311
1263
 
1312
1264
      return true;
1313
1265
    }
1314
1266
 
1315
 
    table::Cache::singleton().mutex().unlock();
 
1267
    pthread_mutex_unlock(&LOCK_open);
1316
1268
 
1317
1269
    session->set_proc_info("end");
1318
1270
 
1319
 
    write_bin_log(session, *session->getQueryString());
 
1271
    write_bin_log(session, session->query.c_str());
1320
1272
    table_list->table= NULL;
1321
1273
  }
1322
1274
 
1349
1301
                 TableList *table_list,
1350
1302
                 AlterInfo *alter_info,
1351
1303
                 uint32_t order_num,
1352
 
                 Order *order,
 
1304
                 order_st *order,
1353
1305
                 bool ignore)
1354
1306
{
1355
1307
  bool error;
1395
1347
 
1396
1348
    if (name_lock)
1397
1349
    {
1398
 
      table::Cache::singleton().mutex().lock(); /* ALTER TABLe */
 
1350
      pthread_mutex_lock(&LOCK_open); /* ALTER TABLe */
1399
1351
      session->unlink_open_table(name_lock);
1400
 
      table::Cache::singleton().mutex().unlock();
 
1352
      pthread_mutex_unlock(&LOCK_open);
1401
1353
    }
1402
1354
  }
1403
1355
 
1410
1362
                         Table *from, Table *to,
1411
1363
                         List<CreateField> &create,
1412
1364
                         bool ignore,
1413
 
                         uint32_t order_num, Order *order,
 
1365
                         uint32_t order_num, order_st *order,
1414
1366
                         ha_rows *copied,
1415
1367
                         ha_rows *deleted,
1416
1368
                         enum enum_enable_or_disable keys_onoff,
1420
1372
  CopyField *copy,*copy_end;
1421
1373
  ulong found_count,delete_count;
1422
1374
  uint32_t length= 0;
1423
 
  SortField *sortorder;
 
1375
  SORT_FIELD *sortorder;
1424
1376
  ReadRecord info;
1425
1377
  TableList   tables;
1426
1378
  List<Item>   fields;
1440
1392
  /* 
1441
1393
   * LP Bug #552420 
1442
1394
   *
1443
 
   * Since open_temporary_table() doesn't invoke lockTables(), we
 
1395
   * Since open_temporary_table() doesn't invoke mysql_lock_tables(), we
1444
1396
   * don't get the usual automatic call to StorageEngine::startStatement(), so
1445
1397
   * we manually call it here...
1446
1398
   */
1447
 
  to->getMutableShare()->getEngine()->startStatement(session);
 
1399
  to->s->getEngine()->startStatement(session);
1448
1400
 
1449
1401
  if (!(copy= new CopyField[to->getShare()->sizeFields()]))
1450
1402
    return -1;
1493
1445
    }
1494
1446
    else
1495
1447
    {
1496
 
      FileSort filesort(*session);
1497
1448
      from->sort.io_cache= new internal::IO_CACHE;
1498
1449
 
1499
1450
      memset(&tables, 0, sizeof(tables));
1500
1451
      tables.table= from;
1501
 
      tables.setTableName(const_cast<char *>(from->getMutableShare()->getTableName()));
1502
 
      tables.alias= const_cast<char *>(tables.getTableName());
1503
 
      tables.setSchemaName(const_cast<char *>(from->getMutableShare()->getSchemaName()));
 
1452
      tables.alias= tables.table_name= const_cast<char *>(from->getMutableShare()->getTableName());
 
1453
      tables.db= const_cast<char *>(from->getMutableShare()->getSchemaName());
1504
1454
      error= 1;
1505
1455
 
1506
1456
      if (session->lex->select_lex.setup_ref_array(session, order_num) ||
1507
1457
          setup_order(session, session->lex->select_lex.ref_pointer_array,
1508
1458
                      &tables, fields, all_fields, order) ||
1509
1459
          !(sortorder= make_unireg_sortorder(order, &length, NULL)) ||
1510
 
          (from->sort.found_records= filesort.run(from, sortorder, length,
1511
 
                                                  (optimizer::SqlSelect *) 0, HA_POS_ERROR,
1512
 
                                                  1, examined_rows)) == HA_POS_ERROR)
 
1460
          (from->sort.found_records= filesort(session, from, sortorder, length,
 
1461
                                              (optimizer::SqlSelect *) 0, HA_POS_ERROR,
 
1462
                                              1, &examined_rows)) ==
 
1463
          HA_POS_ERROR)
1513
1464
      {
1514
1465
        goto err;
1515
1466
      }
1525
1476
  to->restoreRecordAsDefault();        // Create empty record
1526
1477
  while (!(error=info.read_record(&info)))
1527
1478
  {
1528
 
    if (session->getKilled())
 
1479
    if (session->killed)
1529
1480
    {
1530
1481
      session->send_kill_message();
1531
1482
      error= 1;
1546
1497
        to->next_number_field->reset();
1547
1498
    }
1548
1499
 
1549
 
    for (CopyField *copy_ptr= copy; copy_ptr != copy_end ; copy_ptr++)
 
1500
    for (CopyField *copy_ptr=copy ; copy_ptr != copy_end ; copy_ptr++)
1550
1501
    {
1551
 
      if (not copy->to_field->hasDefault() and copy->from_null_ptr and  *copy->from_null_ptr & copy->from_bit)
1552
 
      {
1553
 
        copy->to_field->set_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN,
1554
 
                                    ER_WARN_DATA_TRUNCATED, 1);
1555
 
        copy->to_field->reset();
1556
 
        error= 1;
1557
 
        break;
1558
 
      }
1559
 
 
1560
1502
      copy_ptr->do_copy(copy_ptr);
1561
1503
    }
1562
 
 
1563
 
    if (error)
1564
 
    {
1565
 
      break;
1566
 
    }
1567
 
 
1568
1504
    prev_insert_id= to->cursor->next_insert_id;
1569
1505
    error= to->cursor->insertRecord(to->record[0]);
1570
1506
    to->auto_increment_field_not_null= false;
1571
1507
 
1572
1508
    if (error)
1573
1509
    { 
1574
 
      if (!ignore || to->cursor->is_fatal_error(error, HA_CHECK_DUP))
 
1510
      if (!ignore ||
 
1511
          to->cursor->is_fatal_error(error, HA_CHECK_DUP))
1575
1512
      { 
1576
1513
        to->print_error(error, MYF(0));
1577
1514
        break;
1649
1586
  if (table->getShare()->getType())
1650
1587
  {
1651
1588
    TableList tbl;
1652
 
    tbl.setSchemaName(const_cast<char *>(identifier.getSchemaName().c_str()));
 
1589
    tbl.db= const_cast<char *>(identifier.getSchemaName().c_str());
1653
1590
    tbl.alias= const_cast<char *>(identifier.getTableName().c_str());
1654
 
    tbl.setTableName(const_cast<char *>(identifier.getTableName().c_str()));
 
1591
    tbl.table_name= const_cast<char *>(identifier.getTableName().c_str());
1655
1592
 
1656
1593
    /* Table is in session->temporary_tables */
1657
1594
    new_table= session->openTable(&tbl, (bool*) 0, DRIZZLE_LOCK_IGNORE_FLUSH);