~drizzle-trunk/drizzle/development

1100.3.63 by Padraig O'Sullivan
Extracted the ALTER TABLE command into its own class and implementation
1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3
 *
1999.6.1 by kalebral at gmail
update Copyright strings to a more common format to help with creating the master debian copyright file
4
 *  Copyright (C) 2009 Sun Microsystems, Inc.
1100.3.63 by Padraig O'Sullivan
Extracted the ALTER TABLE command into its own class and implementation
5
 *
6
 *  This program is free software; you can redistribute it and/or modify
7
 *  it under the terms of the GNU General Public License as published by
8
 *  the Free Software Foundation; either version 2 of the License, or
9
 *  (at your option) any later version.
10
 *
11
 *  This program is distributed in the hope that it will be useful,
12
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 *  GNU General Public License for more details.
15
 *
16
 *  You should have received a copy of the GNU General Public License
17
 *  along with this program; if not, write to the Free Software
18
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19
 */
20
1241.9.36 by Monty Taylor
ZOMG. I deleted drizzled/server_includes.h.
21
#include "config.h"
1241.9.1 by Monty Taylor
Removed global.h. Fixed all the headers.
22
23
#include <fcntl.h>
24
1241.9.17 by Monty Taylor
Removed more bits from server_includes.
25
#include <sstream>
26
1237.9.4 by Padraig O'Sullivan
Removed the inclusion of drizzled/field.h in the server_includes header file.
27
#include "drizzled/show.h"
28
#include "drizzled/lock.h"
29
#include "drizzled/session.h"
30
#include "drizzled/statement/alter_table.h"
1241.9.28 by Monty Taylor
Removed global_charset_info.h from server_includes.h
31
#include "drizzled/global_charset_info.h"
32
1100.3.63 by Padraig O'Sullivan
Extracted the ALTER TABLE command into its own class and implementation
33
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
34
#include "drizzled/gettext.h"
35
#include "drizzled/data_home.h"
36
#include "drizzled/sql_table.h"
37
#include "drizzled/table_proto.h"
1237.9.2 by Padraig O'Sullivan
Moved opt_range.[cc,h] into the optimizer directory and namespace and renamed the files to
38
#include "drizzled/optimizer/range.h"
1237.9.8 by Monty Taylor
Fixed solaris build.
39
#include "drizzled/time_functions.h"
1237.9.4 by Padraig O'Sullivan
Removed the inclusion of drizzled/field.h in the server_includes header file.
40
#include "drizzled/records.h"
1241.9.31 by Monty Taylor
Moved global pthread variables into their own header.
41
#include "drizzled/pthread_globals.h"
1241.9.64 by Monty Taylor
Moved remaining non-public portions of mysys and mystrings to drizzled/internal.
42
#include "drizzled/internal/my_sys.h"
43
#include "drizzled/internal/iocache.h"
1241.9.31 by Monty Taylor
Moved global pthread variables into their own header.
44
1273.1.2 by Jay Pipes
This patch does not change any algorithms or code paths,
45
#include "drizzled/transaction_services.h"
46
1905.1.1 by Brian Aker
Adding FileSort class.
47
#include "drizzled/filesort.h"
48
1802.12.2 by Brian Aker
Correcting alter schema to fix bug around schema not altering collate
49
#include "drizzled/message.h"
50
1130.3.6 by Monty Taylor
Removed use of using namespace std; from a header.
51
using namespace std;
1100.3.63 by Padraig O'Sullivan
Extracted the ALTER TABLE command into its own class and implementation
52
1130.3.13 by Monty Taylor
Finished cleaning namespaces in drizzled/statement
53
namespace drizzled
54
{
55
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
56
extern pid_t current_pid;
57
1578.4.11 by Brian Aker
PAss through the code removing current_session
58
static int copy_data_between_tables(Session *session,
59
                                    Table *from,Table *to,
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
60
                                    List<CreateField> &create,
61
                                    bool ignore,
62
                                    uint32_t order_num,
1892.3.3 by tdavies
struct order_st changed and renamed to c++ class named:Order
63
                                    Order *order,
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
64
                                    ha_rows *copied,
65
                                    ha_rows *deleted,
66
                                    enum enum_enable_or_disable keys_onoff,
67
                                    bool error_if_not_empty);
1223.4.13 by Brian Aker
Small shift in alter table (break the baby down...).
68
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
69
static bool mysql_prepare_alter_table(Session *session,
70
                                      Table *table,
71
                                      HA_CREATE_INFO *create_info,
1502.1.30 by Brian Aker
First pass on cleanup of Stewart's patch, plus re-engineer to make it work a
72
                                      const message::Table &original_proto,
1340.1.4 by Brian Aker
A first pass through adding a timestamp to our proto.
73
                                      message::Table &table_message,
1126.3.3 by Jay Pipes
Moves Alter_info out into its own header and source file, cleans up some related include mess in sql_lex.h, and renames Alter_info to AlterInfo.
74
                                      AlterInfo *alter_info);
1223.4.13 by Brian Aker
Small shift in alter table (break the baby down...).
75
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
76
static int create_temporary_table(Session *session,
1235.2.1 by Brian Aker
More identifier work.
77
                                  TableIdentifier &identifier,
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
78
                                  HA_CREATE_INFO *create_info,
1340.1.4 by Brian Aker
A first pass through adding a timestamp to our proto.
79
                                  message::Table &create_message,
1126.3.3 by Jay Pipes
Moves Alter_info out into its own header and source file, cleans up some related include mess in sql_lex.h, and renames Alter_info to AlterInfo.
80
                                  AlterInfo *alter_info);
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
81
1395.1.2 by Brian Aker
More logic pulling from ALTER TABLE
82
static Table *open_alter_table(Session *session, Table *table, TableIdentifier &identifier);
1223.4.13 by Brian Aker
Small shift in alter table (break the baby down...).
83
1100.3.63 by Padraig O'Sullivan
Extracted the ALTER TABLE command into its own class and implementation
84
bool statement::AlterTable::execute()
85
{
86
  TableList *first_table= (TableList *) session->lex->select_lex.table_list.first;
87
  TableList *all_tables= session->lex->query_tables;
88
  assert(first_table == all_tables && first_table != 0);
89
  Select_Lex *select_lex= &session->lex->select_lex;
90
  bool need_start_waiting= false;
91
1222.1.3 by Brian Aker
Remove used flag for engine.
92
  if (is_engine_set)
1160.1.5 by Brian Aker
Final parser SE removal.
93
  {
94
    create_info.db_type= 
1340.1.4 by Brian Aker
A first pass through adding a timestamp to our proto.
95
      plugin::StorageEngine::findByName(*session, create_table_message.engine().name());
1160.1.5 by Brian Aker
Final parser SE removal.
96
97
    if (create_info.db_type == NULL)
98
    {
99
      my_error(ER_UNKNOWN_STORAGE_ENGINE, MYF(0), 
1377.6.2 by pawel
changed tab to spaces
100
               create_table_message.engine().name().c_str());
1160.1.5 by Brian Aker
Final parser SE removal.
101
102
      return true;
103
    }
104
  }
105
1100.3.63 by Padraig O'Sullivan
Extracted the ALTER TABLE command into its own class and implementation
106
  /* Must be set in the parser */
107
  assert(select_lex->db);
108
1389 by Brian Aker
Large reord in ALTER TABLE for RENAME.
109
  /* Chicken/Egg... we need to search for the table, to know if the table exists, so we can build a full identifier from it */
1938.4.2 by Brian Aker
Fix style issue around table for message (though this is imperfect,...)
110
  message::table::shared_ptr original_table_message;
1389 by Brian Aker
Large reord in ALTER TABLE for RENAME.
111
  {
1874.1.2 by Brian Aker
Encapsulate table_name from table_list.
112
    TableIdentifier identifier(first_table->getSchemaName(), first_table->getTableName());
1389 by Brian Aker
Large reord in ALTER TABLE for RENAME.
113
    if (plugin::StorageEngine::getTableDefinition(*session, identifier, original_table_message) != EEXIST)
114
    {
1954.2.1 by Brian Aker
getSQLPath() modified to take a string so that we can const the table
115
      std::string path;
116
      identifier.getSQLPath(path);
117
      my_error(ER_BAD_TABLE_ERROR, MYF(0), path.c_str());
1389 by Brian Aker
Large reord in ALTER TABLE for RENAME.
118
      return true;
119
    }
1502.1.30 by Brian Aker
First pass on cleanup of Stewart's patch, plus re-engineer to make it work a
120
121
    if (not  create_info.db_type)
122
    {
123
      create_info.db_type= 
1910.2.15 by Brian Aker
Update so that we use shared_ptr from the cache throughout more of the
124
        plugin::StorageEngine::findByName(*session, original_table_message->engine().name());
1502.1.30 by Brian Aker
First pass on cleanup of Stewart's patch, plus re-engineer to make it work a
125
126
      if (not create_info.db_type)
127
      {
1954.2.1 by Brian Aker
getSQLPath() modified to take a string so that we can const the table
128
        std::string path;
129
        identifier.getSQLPath(path);
130
        my_error(ER_BAD_TABLE_ERROR, MYF(0), path.c_str());
1502.1.30 by Brian Aker
First pass on cleanup of Stewart's patch, plus re-engineer to make it work a
131
        return true;
132
      }
133
    }
134
  }
135
136
  if (not validateCreateTableOption())
137
    return true;
1389 by Brian Aker
Large reord in ALTER TABLE for RENAME.
138
1100.3.63 by Padraig O'Sullivan
Extracted the ALTER TABLE command into its own class and implementation
139
  /* ALTER TABLE ends previous transaction */
1389 by Brian Aker
Large reord in ALTER TABLE for RENAME.
140
  if (not session->endActiveTransaction())
141
    return true;
142
1910.2.3 by Brian Aker
Second pass on move code to global lock encapsulation.
143
  if (not (need_start_waiting= not session->wait_if_global_read_lock(0, 1)))
1389 by Brian Aker
Large reord in ALTER TABLE for RENAME.
144
    return true;
145
146
  bool res;
1910.2.15 by Brian Aker
Update so that we use shared_ptr from the cache throughout more of the
147
  if (original_table_message->type() == message::Table::STANDARD )
1389 by Brian Aker
Large reord in ALTER TABLE for RENAME.
148
  {
1874.1.2 by Brian Aker
Encapsulate table_name from table_list.
149
    TableIdentifier identifier(first_table->getSchemaName(), first_table->getTableName());
1874.1.1 by Brian Aker
Encapsulate schema_name it table_list.
150
    TableIdentifier new_identifier(select_lex->db ? select_lex->db : first_table->getSchemaName(),
1874.1.2 by Brian Aker
Encapsulate table_name from table_list.
151
                                   session->lex->name.str ? session->lex->name.str : first_table->getTableName());
1389 by Brian Aker
Large reord in ALTER TABLE for RENAME.
152
153
    res= alter_table(session, 
154
                     identifier,
1395.1.2 by Brian Aker
More logic pulling from ALTER TABLE
155
                     new_identifier,
1389 by Brian Aker
Large reord in ALTER TABLE for RENAME.
156
                     &create_info,
1910.2.15 by Brian Aker
Update so that we use shared_ptr from the cache throughout more of the
157
                     *original_table_message,
1389 by Brian Aker
Large reord in ALTER TABLE for RENAME.
158
                     create_table_message,
159
                     first_table,
160
                     &alter_info,
161
                     select_lex->order_list.elements,
1892.3.3 by tdavies
struct order_st changed and renamed to c++ class named:Order
162
                     (Order *) select_lex->order_list.first,
1389 by Brian Aker
Large reord in ALTER TABLE for RENAME.
163
                     session->lex->ignore);
164
  }
165
  else
166
  {
1874.1.2 by Brian Aker
Encapsulate table_name from table_list.
167
    TableIdentifier catch22(first_table->getSchemaName(), first_table->getTableName());
1864.3.14 by Brian Aker
Remove cases where we do not use an identifier to find/delete temp tables,
168
    Table *table= session->find_temporary_table(catch22);
1389 by Brian Aker
Large reord in ALTER TABLE for RENAME.
169
    assert(table);
170
    {
1874.1.2 by Brian Aker
Encapsulate table_name from table_list.
171
      TableIdentifier identifier(first_table->getSchemaName(), first_table->getTableName(), table->getMutableShare()->getPath());
1874.1.1 by Brian Aker
Encapsulate schema_name it table_list.
172
      TableIdentifier new_identifier(select_lex->db ? select_lex->db : first_table->getSchemaName(),
1874.1.2 by Brian Aker
Encapsulate table_name from table_list.
173
                                     session->lex->name.str ? session->lex->name.str : first_table->getTableName(),
1574 by Brian Aker
Rollup patch for hiding tableshare.
174
                                     table->getMutableShare()->getPath());
1389 by Brian Aker
Large reord in ALTER TABLE for RENAME.
175
176
      res= alter_table(session, 
177
                       identifier,
1395.1.2 by Brian Aker
More logic pulling from ALTER TABLE
178
                       new_identifier,
1389 by Brian Aker
Large reord in ALTER TABLE for RENAME.
179
                       &create_info,
1910.2.15 by Brian Aker
Update so that we use shared_ptr from the cache throughout more of the
180
                       *original_table_message,
1389 by Brian Aker
Large reord in ALTER TABLE for RENAME.
181
                       create_table_message,
182
                       first_table,
183
                       &alter_info,
184
                       select_lex->order_list.elements,
1892.3.3 by tdavies
struct order_st changed and renamed to c++ class named:Order
185
                       (Order *) select_lex->order_list.first,
1389 by Brian Aker
Large reord in ALTER TABLE for RENAME.
186
                       session->lex->ignore);
187
    }
188
  }
189
1100.3.63 by Padraig O'Sullivan
Extracted the ALTER TABLE command into its own class and implementation
190
  /*
191
     Release the protection against the global read lock and wake
192
     everyone, who might want to set a global read lock.
193
   */
1910.2.2 by Brian Aker
First pass through the global lock refactor merge.
194
  session->startWaitingGlobalReadLock();
195
1100.3.63 by Padraig O'Sullivan
Extracted the ALTER TABLE command into its own class and implementation
196
  return res;
197
}
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
198
1130.3.12 by Monty Taylor
using namespace drizzled; to namespace drizzled { in statement/
199
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
200
/**
201
  Prepare column and key definitions for CREATE TABLE in ALTER Table.
202
203
  This function transforms parse output of ALTER Table - lists of
204
  columns and keys to add, drop or modify into, essentially,
205
  CREATE TABLE definition - a list of columns and keys of the new
206
  table. While doing so, it also performs some (bug not all)
207
  semantic checks.
208
209
  This function is invoked when we know that we're going to
210
  perform ALTER Table via a temporary table -- i.e. fast ALTER Table
211
  is not possible, perhaps because the ALTER statement contains
212
  instructions that require change in table data, not only in
213
  table definition or indexes.
214
215
  @param[in,out]  session         thread handle. Used as a memory pool
216
                              and source of environment information.
217
  @param[in]      table       the source table, open and locked
218
                              Used as an interface to the storage engine
219
                              to acquire additional information about
220
                              the original table.
221
  @param[in,out]  create_info A blob with CREATE/ALTER Table
222
                              parameters
223
  @param[in,out]  alter_info  Another blob with ALTER/CREATE parameters.
224
                              Originally create_info was used only in
225
                              CREATE TABLE and alter_info only in ALTER Table.
226
                              But since ALTER might end-up doing CREATE,
227
                              this distinction is gone and we just carry
228
                              around two structures.
229
230
  @return
231
    Fills various create_info members based on information retrieved
232
    from the storage engine.
233
    Sets create_info->varchar if the table has a VARCHAR column.
234
    Prepares alter_info->create_list and alter_info->key_list with
235
    columns and keys of the new table.
236
  @retval true   error, out of memory or a semantical error in ALTER
237
                 Table instructions
238
  @retval false  success
239
*/
1126.3.3 by Jay Pipes
Moves Alter_info out into its own header and source file, cleans up some related include mess in sql_lex.h, and renames Alter_info to AlterInfo.
240
static bool mysql_prepare_alter_table(Session *session,
241
                                      Table *table,
242
                                      HA_CREATE_INFO *create_info,
1502.1.30 by Brian Aker
First pass on cleanup of Stewart's patch, plus re-engineer to make it work a
243
                                      const message::Table &original_proto,
1340.1.4 by Brian Aker
A first pass through adding a timestamp to our proto.
244
                                      message::Table &table_message,
1126.3.3 by Jay Pipes
Moves Alter_info out into its own header and source file, cleans up some related include mess in sql_lex.h, and renames Alter_info to AlterInfo.
245
                                      AlterInfo *alter_info)
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
246
{
247
  /* New column definitions are added here */
248
  List<CreateField> new_create_list;
249
  /* New key definitions are added here */
250
  List<Key> new_key_list;
1126.3.4 by Jay Pipes
Changes Alter_drop and Alter_column to AlterDrop and AlterColumn. Next up: bye bye List<> in AlterInfo.
251
  List_iterator<AlterDrop> drop_it(alter_info->drop_list);
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
252
  List_iterator<CreateField> def_it(alter_info->create_list);
1126.3.4 by Jay Pipes
Changes Alter_drop and Alter_column to AlterDrop and AlterColumn. Next up: bye bye List<> in AlterInfo.
253
  List_iterator<AlterColumn> alter_it(alter_info->alter_list);
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
254
  List_iterator<Key> key_it(alter_info->key_list);
255
  List_iterator<CreateField> find_it(new_create_list);
256
  List_iterator<CreateField> field_it(new_create_list);
257
  List<Key_part_spec> key_parts;
258
  uint32_t used_fields= create_info->used_fields;
1535 by Brian Aker
Rename of KEY to KeyInfo
259
  KeyInfo *key_info= table->key_info;
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
260
  bool rc= true;
261
262
  /* Let new create options override the old ones */
1130.3.13 by Monty Taylor
Finished cleaning namespaces in drizzled/statement
263
  message::Table::TableOptions *table_options;
1340.1.4 by Brian Aker
A first pass through adding a timestamp to our proto.
264
  table_options= table_message.mutable_options();
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
265
1126.3.5 by Jay Pipes
Clean up the style and spacing in mysql_prepare_alter_table() before I lose my friggin mind.
266
  if (! (used_fields & HA_CREATE_USED_DEFAULT_CHARSET))
1574 by Brian Aker
Rollup patch for hiding tableshare.
267
    create_info->default_table_charset= table->getShare()->table_charset;
1126.3.5 by Jay Pipes
Clean up the style and spacing in mysql_prepare_alter_table() before I lose my friggin mind.
268
  if (! (used_fields & HA_CREATE_USED_AUTO) &&
269
      table->found_next_number_field)
270
  {
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
271
    /* Table has an autoincrement, copy value to new table */
1208.3.2 by brian
Update for Cursor renaming.
272
    table->cursor->info(HA_STATUS_AUTO);
273
    create_info->auto_increment_value= table->cursor->stats.auto_increment_value;
1638.10.116 by Stewart Smith
only display AUTO_INCREMENT value if explicitly set by user (and preserve across ALTER TABLE).
274
    if (create_info->auto_increment_value != original_proto.options().auto_increment_value())
275
      table_options->set_has_user_set_auto_increment_value(false);
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
276
  }
1126.3.5 by Jay Pipes
Clean up the style and spacing in mysql_prepare_alter_table() before I lose my friggin mind.
277
  table->restoreRecordAsDefault(); /* Empty record for DEFAULT */
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
278
  CreateField *def;
279
1126.3.5 by Jay Pipes
Clean up the style and spacing in mysql_prepare_alter_table() before I lose my friggin mind.
280
  /* First collect all fields from table which isn't in drop_list */
281
  Field **f_ptr;
282
  Field *field;
1578.2.16 by Brian Aker
Merge in change to getTable() to private the field objects.
283
  for (f_ptr= table->getFields(); (field= *f_ptr); f_ptr++)
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
284
  {
285
    /* Check if field should be dropped */
1126.3.4 by Jay Pipes
Changes Alter_drop and Alter_column to AlterDrop and AlterColumn. Next up: bye bye List<> in AlterInfo.
286
    AlterDrop *drop;
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
287
    drop_it.rewind();
1126.3.5 by Jay Pipes
Clean up the style and spacing in mysql_prepare_alter_table() before I lose my friggin mind.
288
    while ((drop= drop_it++))
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
289
    {
1126.3.4 by Jay Pipes
Changes Alter_drop and Alter_column to AlterDrop and AlterColumn. Next up: bye bye List<> in AlterInfo.
290
      if (drop->type == AlterDrop::COLUMN &&
1126.3.5 by Jay Pipes
Clean up the style and spacing in mysql_prepare_alter_table() before I lose my friggin mind.
291
          ! my_strcasecmp(system_charset_info, field->field_name, drop->name))
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
292
      {
1126.3.5 by Jay Pipes
Clean up the style and spacing in mysql_prepare_alter_table() before I lose my friggin mind.
293
        /* Reset auto_increment value if it was dropped */
294
        if (MTYP_TYPENR(field->unireg_check) == Field::NEXT_NUMBER &&
295
            ! (used_fields & HA_CREATE_USED_AUTO))
296
        {
297
          create_info->auto_increment_value= 0;
298
          create_info->used_fields|= HA_CREATE_USED_AUTO;
299
        }
300
        break;
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
301
      }
302
    }
303
    if (drop)
304
    {
305
      drop_it.remove();
306
      continue;
307
    }
308
    
309
    /* Mark that we will read the field */
310
    field->setReadSet();
311
312
    /* Check if field is changed */
313
    def_it.rewind();
1126.3.5 by Jay Pipes
Clean up the style and spacing in mysql_prepare_alter_table() before I lose my friggin mind.
314
    while ((def= def_it++))
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
315
    {
316
      if (def->change &&
1126.3.5 by Jay Pipes
Clean up the style and spacing in mysql_prepare_alter_table() before I lose my friggin mind.
317
          ! my_strcasecmp(system_charset_info, field->field_name, def->change))
318
	      break;
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
319
    }
320
    if (def)
1126.3.5 by Jay Pipes
Clean up the style and spacing in mysql_prepare_alter_table() before I lose my friggin mind.
321
    {
322
      /* Field is changed */
323
      def->field= field;
324
      if (! def->after)
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
325
      {
1126.3.5 by Jay Pipes
Clean up the style and spacing in mysql_prepare_alter_table() before I lose my friggin mind.
326
        new_create_list.push_back(def);
327
        def_it.remove();
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
328
      }
329
    }
330
    else
331
    {
332
      /*
333
        This field was not dropped and not changed, add it to the list
334
        for the new table.
335
      */
336
      def= new CreateField(field, field);
337
      new_create_list.push_back(def);
1126.3.5 by Jay Pipes
Clean up the style and spacing in mysql_prepare_alter_table() before I lose my friggin mind.
338
      alter_it.rewind(); /* Change default if ALTER */
1126.3.4 by Jay Pipes
Changes Alter_drop and Alter_column to AlterDrop and AlterColumn. Next up: bye bye List<> in AlterInfo.
339
      AlterColumn *alter;
2008.2.4 by Brian Aker
Merge in additional fixes for sign, plus alter table, plus TIME on
340
1126.3.5 by Jay Pipes
Clean up the style and spacing in mysql_prepare_alter_table() before I lose my friggin mind.
341
      while ((alter= alter_it++))
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
342
      {
1126.3.5 by Jay Pipes
Clean up the style and spacing in mysql_prepare_alter_table() before I lose my friggin mind.
343
        if (! my_strcasecmp(system_charset_info,field->field_name, alter->name))
344
          break;
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
345
      }
2008.2.4 by Brian Aker
Merge in additional fixes for sign, plus alter table, plus TIME on
346
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
347
      if (alter)
348
      {
1126.3.5 by Jay Pipes
Clean up the style and spacing in mysql_prepare_alter_table() before I lose my friggin mind.
349
        if (def->sql_type == DRIZZLE_TYPE_BLOB)
350
        {
351
          my_error(ER_BLOB_CANT_HAVE_DEFAULT, MYF(0), def->change);
1976.6.1 by Brian Aker
This is a fix for bug lp:686197
352
          return true;
1126.3.5 by Jay Pipes
Clean up the style and spacing in mysql_prepare_alter_table() before I lose my friggin mind.
353
        }
2008.2.4 by Brian Aker
Merge in additional fixes for sign, plus alter table, plus TIME on
354
1126.3.5 by Jay Pipes
Clean up the style and spacing in mysql_prepare_alter_table() before I lose my friggin mind.
355
        if ((def->def= alter->def))
356
        {
357
          /* Use new default */
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
358
          def->flags&= ~NO_DEFAULT_VALUE_FLAG;
1126.3.5 by Jay Pipes
Clean up the style and spacing in mysql_prepare_alter_table() before I lose my friggin mind.
359
        }
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
360
        else
1976.6.1 by Brian Aker
This is a fix for bug lp:686197
361
        {
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
362
          def->flags|= NO_DEFAULT_VALUE_FLAG;
1976.6.1 by Brian Aker
This is a fix for bug lp:686197
363
        }
1126.3.5 by Jay Pipes
Clean up the style and spacing in mysql_prepare_alter_table() before I lose my friggin mind.
364
        alter_it.remove();
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
365
      }
366
    }
367
  }
368
  def_it.rewind();
1126.3.5 by Jay Pipes
Clean up the style and spacing in mysql_prepare_alter_table() before I lose my friggin mind.
369
  while ((def= def_it++)) /* Add new columns */
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
370
  {
371
    if (def->change && ! def->field)
372
    {
1574 by Brian Aker
Rollup patch for hiding tableshare.
373
      my_error(ER_BAD_FIELD_ERROR, MYF(0), def->change, table->getMutableShare()->getTableName());
1976.6.1 by Brian Aker
This is a fix for bug lp:686197
374
      return true;
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
375
    }
376
    /*
1976.6.1 by Brian Aker
This is a fix for bug lp:686197
377
      If we have been given a field which has no default value, and is not null then we need to bail.
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
378
    */
1976.6.1 by Brian Aker
This is a fix for bug lp:686197
379
    if (not (~def->flags & (NO_DEFAULT_VALUE_FLAG | NOT_NULL_FLAG)) and not def->change)
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
380
    {
381
      alter_info->error_if_not_empty= true;
382
    }
1126.3.5 by Jay Pipes
Clean up the style and spacing in mysql_prepare_alter_table() before I lose my friggin mind.
383
    if (! def->after)
1976.6.1 by Brian Aker
This is a fix for bug lp:686197
384
    {
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
385
      new_create_list.push_back(def);
1976.6.1 by Brian Aker
This is a fix for bug lp:686197
386
    }
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
387
    else if (def->after == first_keyword)
1976.6.1 by Brian Aker
This is a fix for bug lp:686197
388
    {
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
389
      new_create_list.push_front(def);
1976.6.1 by Brian Aker
This is a fix for bug lp:686197
390
    }
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
391
    else
392
    {
393
      CreateField *find;
394
      find_it.rewind();
1126.3.5 by Jay Pipes
Clean up the style and spacing in mysql_prepare_alter_table() before I lose my friggin mind.
395
      while ((find= find_it++)) /* Add new columns */
396
      {
397
        if (! my_strcasecmp(system_charset_info,def->after, find->field_name))
398
          break;
399
      }
400
      if (! find)
401
      {
1574 by Brian Aker
Rollup patch for hiding tableshare.
402
        my_error(ER_BAD_FIELD_ERROR, MYF(0), def->after, table->getMutableShare()->getTableName());
1976.6.1 by Brian Aker
This is a fix for bug lp:686197
403
        return true;
1126.3.5 by Jay Pipes
Clean up the style and spacing in mysql_prepare_alter_table() before I lose my friggin mind.
404
      }
405
      find_it.after(def); /* Put element after this */
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
406
      /*
407
        XXX: hack for Bug#28427.
408
        If column order has changed, force OFFLINE ALTER Table
409
        without querying engine capabilities.  If we ever have an
410
        engine that supports online ALTER Table CHANGE COLUMN
411
        <name> AFTER <name1> (Falcon?), this fix will effectively
412
        disable the capability.
413
        TODO: detect the situation in compare_tables, behave based
414
        on engine capabilities.
415
      */
416
      if (alter_info->build_method == HA_BUILD_ONLINE)
417
      {
1921.4.13 by Brian Aker
Fix issue where session info might not be correct.
418
        my_error(ER_NOT_SUPPORTED_YET, MYF(0), session->getQueryString()->c_str());
1976.6.1 by Brian Aker
This is a fix for bug lp:686197
419
        return true;
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
420
      }
421
      alter_info->build_method= HA_BUILD_OFFLINE;
422
    }
423
  }
424
  if (alter_info->alter_list.elements)
425
  {
1126.3.5 by Jay Pipes
Clean up the style and spacing in mysql_prepare_alter_table() before I lose my friggin mind.
426
    my_error(ER_BAD_FIELD_ERROR,
427
             MYF(0),
428
             alter_info->alter_list.head()->name,
1574 by Brian Aker
Rollup patch for hiding tableshare.
429
             table->getMutableShare()->getTableName());
1976.6.1 by Brian Aker
This is a fix for bug lp:686197
430
    return true;
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
431
  }
1126.3.5 by Jay Pipes
Clean up the style and spacing in mysql_prepare_alter_table() before I lose my friggin mind.
432
  if (! new_create_list.elements)
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
433
  {
1126.3.5 by Jay Pipes
Clean up the style and spacing in mysql_prepare_alter_table() before I lose my friggin mind.
434
    my_message(ER_CANT_REMOVE_ALL_FIELDS,
435
               ER(ER_CANT_REMOVE_ALL_FIELDS),
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
436
               MYF(0));
1976.6.1 by Brian Aker
This is a fix for bug lp:686197
437
    return true;
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
438
  }
439
440
  /*
441
    Collect all keys which isn't in drop list. Add only those
442
    for which some fields exists.
443
  */
1578.2.10 by Brian Aker
keys and fields partial encapsulation.
444
  for (uint32_t i= 0; i < table->getShare()->sizeKeys(); i++, key_info++)
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
445
  {
446
    char *key_name= key_info->name;
1126.3.4 by Jay Pipes
Changes Alter_drop and Alter_column to AlterDrop and AlterColumn. Next up: bye bye List<> in AlterInfo.
447
    AlterDrop *drop;
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
448
    drop_it.rewind();
1126.3.5 by Jay Pipes
Clean up the style and spacing in mysql_prepare_alter_table() before I lose my friggin mind.
449
    while ((drop= drop_it++))
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
450
    {
1126.3.4 by Jay Pipes
Changes Alter_drop and Alter_column to AlterDrop and AlterColumn. Next up: bye bye List<> in AlterInfo.
451
      if (drop->type == AlterDrop::KEY &&
1126.3.5 by Jay Pipes
Clean up the style and spacing in mysql_prepare_alter_table() before I lose my friggin mind.
452
          ! my_strcasecmp(system_charset_info, key_name, drop->name))
453
        break;
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
454
    }
455
    if (drop)
456
    {
457
      drop_it.remove();
458
      continue;
459
    }
460
1534 by Brian Aker
Remove of KeyPartInfo
461
    KeyPartInfo *key_part= key_info->key_part;
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
462
    key_parts.empty();
1126.3.5 by Jay Pipes
Clean up the style and spacing in mysql_prepare_alter_table() before I lose my friggin mind.
463
    for (uint32_t j= 0; j < key_info->key_parts; j++, key_part++)
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
464
    {
1126.3.5 by Jay Pipes
Clean up the style and spacing in mysql_prepare_alter_table() before I lose my friggin mind.
465
      if (! key_part->field)
466
	      continue;	/* Wrong field (from UNIREG) */
467
468
      const char *key_part_name= key_part->field->field_name;
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
469
      CreateField *cfield;
470
      field_it.rewind();
1126.3.5 by Jay Pipes
Clean up the style and spacing in mysql_prepare_alter_table() before I lose my friggin mind.
471
      while ((cfield= field_it++))
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
472
      {
1126.3.5 by Jay Pipes
Clean up the style and spacing in mysql_prepare_alter_table() before I lose my friggin mind.
473
        if (cfield->change)
474
        {
475
          if (! my_strcasecmp(system_charset_info, key_part_name, cfield->change))
476
            break;
477
        }
478
        else if (! my_strcasecmp(system_charset_info, key_part_name, cfield->field_name))
479
          break;
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
480
      }
1126.3.5 by Jay Pipes
Clean up the style and spacing in mysql_prepare_alter_table() before I lose my friggin mind.
481
      if (! cfield)
482
	      continue; /* Field is removed */
483
      
484
      uint32_t key_part_length= key_part->length;
485
      if (cfield->field) /* Not new field */
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
486
      {
487
        /*
488
          If the field can't have only a part used in a key according to its
489
          new type, or should not be used partially according to its
490
          previous type, or the field length is less than the key part
491
          length, unset the key part length.
492
493
          We also unset the key part length if it is the same as the
494
          old field's length, so the whole new field will be used.
495
496
          BLOBs may have cfield->length == 0, which is why we test it before
497
          checking whether cfield->length < key_part_length (in chars).
498
         */
1126.3.5 by Jay Pipes
Clean up the style and spacing in mysql_prepare_alter_table() before I lose my friggin mind.
499
        if (! Field::type_can_have_key_part(cfield->field->type()) ||
500
            ! Field::type_can_have_key_part(cfield->sql_type) ||
1119.9.17 by Stewart Smith
merge with trunk
501
            (cfield->field->field_length == key_part_length) ||
1126.3.5 by Jay Pipes
Clean up the style and spacing in mysql_prepare_alter_table() before I lose my friggin mind.
502
            (cfield->length &&
503
             (cfield->length < key_part_length / key_part->field->charset()->mbmaxlen)))
504
          key_part_length= 0; /* Use whole field */
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
505
      }
1126.3.5 by Jay Pipes
Clean up the style and spacing in mysql_prepare_alter_table() before I lose my friggin mind.
506
      key_part_length/= key_part->field->charset()->mbmaxlen;
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
507
      key_parts.push_back(new Key_part_spec(cfield->field_name,
508
                                            strlen(cfield->field_name),
1126.3.5 by Jay Pipes
Clean up the style and spacing in mysql_prepare_alter_table() before I lose my friggin mind.
509
                                            key_part_length));
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
510
    }
511
    if (key_parts.elements)
512
    {
513
      KEY_CREATE_INFO key_create_info;
514
      Key *key;
515
      enum Key::Keytype key_type;
516
      memset(&key_create_info, 0, sizeof(key_create_info));
517
518
      key_create_info.algorithm= key_info->algorithm;
519
      if (key_info->flags & HA_USES_BLOCK_SIZE)
520
        key_create_info.block_size= key_info->block_size;
521
      if (key_info->flags & HA_USES_COMMENT)
522
        key_create_info.comment= key_info->comment;
523
524
      if (key_info->flags & HA_NOSAME)
525
      {
526
        if (is_primary_key_name(key_name))
527
          key_type= Key::PRIMARY;
528
        else
529
          key_type= Key::UNIQUE;
530
      }
531
      else
532
        key_type= Key::MULTIPLE;
533
1126.3.5 by Jay Pipes
Clean up the style and spacing in mysql_prepare_alter_table() before I lose my friggin mind.
534
      key= new Key(key_type,
535
                   key_name,
536
                   strlen(key_name),
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
537
                   &key_create_info,
538
                   test(key_info->flags & HA_GENERATED_KEY),
539
                   key_parts);
540
      new_key_list.push_back(key);
541
    }
542
  }
1638.10.80 by Stewart Smith
fix storing and manipulating foreign keys in the proto around ALTER TABLE, CREATE TABLE and ALTER TABLE ADD/DROP FOREIGN KEY. We also (mostly) emulate the naming of innodb foreign keys in the upper layer.
543
544
  /* Copy over existing foreign keys */
545
  for (int j= 0; j < original_proto.fk_constraint_size(); j++)
546
  {
547
    AlterDrop *drop;
548
    drop_it.rewind();
549
    while ((drop= drop_it++))
550
    {
551
      if (drop->type == AlterDrop::FOREIGN_KEY &&
552
          ! my_strcasecmp(system_charset_info, original_proto.fk_constraint(j).name().c_str(), drop->name))
553
      {
554
        break;
555
      }
556
    }
557
    if (drop)
558
    {
559
      drop_it.remove();
560
      continue;
561
    }
562
563
    message::Table::ForeignKeyConstraint *pfkey= table_message.add_fk_constraint();
564
    *pfkey= original_proto.fk_constraint(j);
565
  }
566
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
567
  {
568
    Key *key;
1126.3.5 by Jay Pipes
Clean up the style and spacing in mysql_prepare_alter_table() before I lose my friggin mind.
569
    while ((key= key_it++)) /* Add new keys */
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
570
    {
1638.10.80 by Stewart Smith
fix storing and manipulating foreign keys in the proto around ALTER TABLE, CREATE TABLE and ALTER TABLE ADD/DROP FOREIGN KEY. We also (mostly) emulate the naming of innodb foreign keys in the upper layer.
571
      if (key->type == Key::FOREIGN_KEY)
572
      {
573
        if (((Foreign_key *)key)->validate(new_create_list))
1976.6.1 by Brian Aker
This is a fix for bug lp:686197
574
        {
575
          return true;
576
        }
1638.10.80 by Stewart Smith
fix storing and manipulating foreign keys in the proto around ALTER TABLE, CREATE TABLE and ALTER TABLE ADD/DROP FOREIGN KEY. We also (mostly) emulate the naming of innodb foreign keys in the upper layer.
577
578
        Foreign_key *fkey= (Foreign_key*)key;
579
        add_foreign_key_to_table_message(&table_message,
580
                                         fkey->name.str,
581
                                         fkey->columns,
582
                                         fkey->ref_table,
583
                                         fkey->ref_columns,
584
                                         fkey->delete_opt,
585
                                         fkey->update_opt,
586
                                         fkey->match_opt);
587
      }
588
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
589
      if (key->type != Key::FOREIGN_KEY)
590
        new_key_list.push_back(key);
1638.10.80 by Stewart Smith
fix storing and manipulating foreign keys in the proto around ALTER TABLE, CREATE TABLE and ALTER TABLE ADD/DROP FOREIGN KEY. We also (mostly) emulate the naming of innodb foreign keys in the upper layer.
591
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
592
      if (key->name.str && is_primary_key_name(key->name.str))
593
      {
1126.3.5 by Jay Pipes
Clean up the style and spacing in mysql_prepare_alter_table() before I lose my friggin mind.
594
        my_error(ER_WRONG_NAME_FOR_INDEX,
595
                 MYF(0),
596
                 key->name.str);
1976.6.1 by Brian Aker
This is a fix for bug lp:686197
597
        return true;
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
598
      }
599
    }
600
  }
601
1638.10.80 by Stewart Smith
fix storing and manipulating foreign keys in the proto around ALTER TABLE, CREATE TABLE and ALTER TABLE ADD/DROP FOREIGN KEY. We also (mostly) emulate the naming of innodb foreign keys in the upper layer.
602
  /* Fix names of foreign keys being added */
603
  for (int j= 0; j < table_message.fk_constraint_size(); j++)
604
  {
605
    if (! table_message.fk_constraint(j).has_name())
606
    {
607
      std::string name(table->getMutableShare()->getTableName());
608
      char number[20];
609
610
      name.append("_ibfk_");
611
      snprintf(number, sizeof(number), "%d", j+1);
612
      name.append(number);
613
614
      message::Table::ForeignKeyConstraint *pfkey= table_message.mutable_fk_constraint(j);
615
      pfkey->set_name(name);
616
    }
617
  }
618
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
619
  if (alter_info->drop_list.elements)
620
  {
1126.3.5 by Jay Pipes
Clean up the style and spacing in mysql_prepare_alter_table() before I lose my friggin mind.
621
    my_error(ER_CANT_DROP_FIELD_OR_KEY,
622
             MYF(0),
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
623
             alter_info->drop_list.head()->name);
1976.6.1 by Brian Aker
This is a fix for bug lp:686197
624
    return true;
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
625
  }
2008.2.4 by Brian Aker
Merge in additional fixes for sign, plus alter table, plus TIME on
626
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
627
  if (alter_info->alter_list.elements)
628
  {
1126.3.5 by Jay Pipes
Clean up the style and spacing in mysql_prepare_alter_table() before I lose my friggin mind.
629
    my_error(ER_CANT_DROP_FIELD_OR_KEY,
630
             MYF(0),
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
631
             alter_info->alter_list.head()->name);
1976.6.1 by Brian Aker
This is a fix for bug lp:686197
632
    return true;
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
633
  }
634
1340.1.4 by Brian Aker
A first pass through adding a timestamp to our proto.
635
  if (not table_message.options().has_comment()
1574 by Brian Aker
Rollup patch for hiding tableshare.
636
      && table->getMutableShare()->hasComment())
637
    table_options->set_comment(table->getMutableShare()->getComment());
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
638
1608.2.3 by Brian Aker
Encapsulate type for TableShare.
639
  if (table->getShare()->getType())
1222.2.1 by Brian Aker
Takes the majority usage of parser based HA_CREATE_INFO usage around
640
  {
1340.1.4 by Brian Aker
A first pass through adding a timestamp to our proto.
641
    table_message.set_type(message::Table::TEMPORARY);
1222.2.1 by Brian Aker
Takes the majority usage of parser based HA_CREATE_INFO usage around
642
  }
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
643
1340.1.4 by Brian Aker
A first pass through adding a timestamp to our proto.
644
  table_message.set_creation_timestamp(table->getShare()->getTableProto()->creation_timestamp());
1802.12.2 by Brian Aker
Correcting alter schema to fix bug around schema not altering collate
645
  table_message.set_version(table->getShare()->getTableProto()->version());
646
  table_message.set_uuid(table->getShare()->getTableProto()->uuid());
1340.1.4 by Brian Aker
A first pass through adding a timestamp to our proto.
647
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
648
  rc= false;
649
  alter_info->create_list.swap(new_create_list);
650
  alter_info->key_list.swap(new_key_list);
1502.1.30 by Brian Aker
First pass on cleanup of Stewart's patch, plus re-engineer to make it work a
651
652
  size_t num_engine_options= table_message.engine().options_size();
653
  size_t original_num_engine_options= original_proto.engine().options_size();
654
  for (size_t x= 0; x < original_num_engine_options; ++x)
655
  {
656
    bool found= false;
657
658
    for (size_t y= 0; y < num_engine_options; ++y)
659
    {
660
      found= not table_message.engine().options(y).name().compare(original_proto.engine().options(x).name());
661
      
662
      if (found)
663
        break;
664
    }
665
666
    if (not found)
667
    {
1502.1.31 by Brian Aker
Merge engine options for schema/table.
668
      message::Engine::Option *opt= table_message.mutable_engine()->add_options();
1502.1.30 by Brian Aker
First pass on cleanup of Stewart's patch, plus re-engineer to make it work a
669
670
      opt->set_name(original_proto.engine().options(x).name());
671
      opt->set_state(original_proto.engine().options(x).state());
672
    }
673
  }
674
1802.12.2 by Brian Aker
Correcting alter schema to fix bug around schema not altering collate
675
  drizzled::message::update(table_message);
676
1976.6.1 by Brian Aker
This is a fix for bug lp:686197
677
  return false;
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
678
}
679
680
/* table_list should contain just one table */
1126.3.3 by Jay Pipes
Moves Alter_info out into its own header and source file, cleans up some related include mess in sql_lex.h, and renames Alter_info to AlterInfo.
681
static int mysql_discard_or_import_tablespace(Session *session,
682
                                              TableList *table_list,
683
                                              enum tablespace_op_type tablespace_op)
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
684
{
685
  Table *table;
686
  bool discard;
687
  int error;
688
689
  /*
690
    Note that DISCARD/IMPORT TABLESPACE always is the only operation in an
691
    ALTER Table
692
  */
693
1273.1.2 by Jay Pipes
This patch does not change any algorithms or code paths,
694
  TransactionServices &transaction_services= TransactionServices::singleton();
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
695
  session->set_proc_info("discard_or_import_tablespace");
696
697
  discard= test(tablespace_op == DISCARD_TABLESPACE);
698
699
 /*
700
   We set this flag so that ha_innobase::open and ::external_lock() do
701
   not complain when we lock the table
702
 */
703
  session->tablespace_op= true;
704
  if (!(table= session->openTableLock(table_list, TL_WRITE)))
705
  {
706
    session->tablespace_op= false;
707
    return -1;
708
  }
709
1208.3.2 by brian
Update for Cursor renaming.
710
  error= table->cursor->ha_discard_or_import_tablespace(discard);
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
711
712
  session->set_proc_info("end");
713
714
  if (error)
715
    goto err;
716
717
  /* The ALTER Table is always in its own transaction */
1405.3.5 by Jay Pipes
TransactionServices method names now meet code style guidelines.
718
  error= transaction_services.autocommitOrRollback(session, false);
1921.4.13 by Brian Aker
Fix issue where session info might not be correct.
719
  if (not session->endActiveTransaction())
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
720
    error=1;
1921.4.13 by Brian Aker
Fix issue where session info might not be correct.
721
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
722
  if (error)
723
    goto err;
1921.4.13 by Brian Aker
Fix issue where session info might not be correct.
724
725
  write_bin_log(session, *session->getQueryString());
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
726
727
err:
1405.3.5 by Jay Pipes
TransactionServices method names now meet code style guidelines.
728
  (void) transaction_services.autocommitOrRollback(session, error);
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
729
  session->tablespace_op=false;
730
731
  if (error == 0)
732
  {
733
    session->my_ok();
734
    return 0;
735
  }
736
1216.1.1 by Brian Aker
Move print_error up to Engine.
737
  table->print_error(error, MYF(0));
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
738
739
  return -1;
740
}
741
1126.3.3 by Jay Pipes
Moves Alter_info out into its own header and source file, cleans up some related include mess in sql_lex.h, and renames Alter_info to AlterInfo.
742
/**
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
743
  Manages enabling/disabling of indexes for ALTER Table
744
745
  SYNOPSIS
746
    alter_table_manage_keys()
747
      table                  Target table
748
      indexes_were_disabled  Whether the indexes of the from table
749
                             were disabled
750
      keys_onoff             ENABLE | DISABLE | LEAVE_AS_IS
751
752
  RETURN VALUES
753
    false  OK
754
    true   Error
755
*/
1578.4.11 by Brian Aker
PAss through the code removing current_session
756
static bool alter_table_manage_keys(Session *session,
757
                                    Table *table, int indexes_were_disabled,
1502.1.30 by Brian Aker
First pass on cleanup of Stewart's patch, plus re-engineer to make it work a
758
                                    enum enum_enable_or_disable keys_onoff)
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
759
{
760
  int error= 0;
761
  switch (keys_onoff) {
762
  case ENABLE:
1208.3.2 by brian
Update for Cursor renaming.
763
    error= table->cursor->ha_enable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
764
    break;
765
  case LEAVE_AS_IS:
1502.1.30 by Brian Aker
First pass on cleanup of Stewart's patch, plus re-engineer to make it work a
766
    if (not indexes_were_disabled)
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
767
      break;
768
    /* fall-through: disabled indexes */
769
  case DISABLE:
1208.3.2 by brian
Update for Cursor renaming.
770
    error= table->cursor->ha_disable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
771
  }
772
773
  if (error == HA_ERR_WRONG_COMMAND)
774
  {
1578.4.11 by Brian Aker
PAss through the code removing current_session
775
    push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
776
                        ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA),
1574 by Brian Aker
Rollup patch for hiding tableshare.
777
                        table->getMutableShare()->getTableName());
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
778
    error= 0;
779
  } else if (error)
1216.1.1 by Brian Aker
Move print_error up to Engine.
780
    table->print_error(error, MYF(0));
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
781
782
  return(error);
783
}
784
1395.1.2 by Brian Aker
More logic pulling from ALTER TABLE
785
static bool lockTableIfDifferent(Session &session,
786
                                 TableIdentifier &original_table_identifier,
787
                                 TableIdentifier &new_table_identifier,
788
                                 Table *name_lock)
789
{
790
  /* Check that we are not trying to rename to an existing table */
791
  if (not (original_table_identifier == new_table_identifier))
792
  {
1395.1.3 by Brian Aker
Pass through on refactoring, locks now are wrapped up in layer above.
793
    if (original_table_identifier.isTmp())
1395.1.2 by Brian Aker
More logic pulling from ALTER TABLE
794
    {
795
796
      if (session.find_temporary_table(new_table_identifier))
797
      {
1954.2.1 by Brian Aker
getSQLPath() modified to take a string so that we can const the table
798
        std::string path;
799
        new_table_identifier.getSQLPath(path);
800
        my_error(ER_TABLE_EXISTS_ERROR, MYF(0), path.c_str());
1395.1.2 by Brian Aker
More logic pulling from ALTER TABLE
801
        return false;
802
      }
803
    }
804
    else
805
    {
806
      if (session.lock_table_name_if_not_cached(new_table_identifier, &name_lock))
807
      {
808
        return false;
809
      }
810
811
      if (not name_lock)
812
      {
1954.2.1 by Brian Aker
getSQLPath() modified to take a string so that we can const the table
813
        std::string path;
814
        new_table_identifier.getSQLPath(path);
815
        my_error(ER_TABLE_EXISTS_ERROR, MYF(0), path.c_str());
1395.1.2 by Brian Aker
More logic pulling from ALTER TABLE
816
        return false;
817
      }
818
819
      if (plugin::StorageEngine::doesTableExist(session, new_table_identifier))
820
      {
1954.2.1 by Brian Aker
getSQLPath() modified to take a string so that we can const the table
821
        std::string path;
822
        new_table_identifier.getSQLPath(path);
823
1395.1.2 by Brian Aker
More logic pulling from ALTER TABLE
824
        /* Table will be closed by Session::executeCommand() */
1954.2.1 by Brian Aker
getSQLPath() modified to take a string so that we can const the table
825
        my_error(ER_TABLE_EXISTS_ERROR, MYF(0), path.c_str());
1395.1.2 by Brian Aker
More logic pulling from ALTER TABLE
826
1938.4.10 by Brian Aker
Convert LOCK_open to lock in mutex
827
        table::Cache::singleton().mutex().lock(); /* ALTER TABLe */
1395.1.2 by Brian Aker
More logic pulling from ALTER TABLE
828
        session.unlink_open_table(name_lock);
1938.4.10 by Brian Aker
Convert LOCK_open to lock in mutex
829
        table::Cache::singleton().mutex().unlock();
1395.1.2 by Brian Aker
More logic pulling from ALTER TABLE
830
831
        return false;
832
      }
833
    }
834
  }
835
836
  return true;
837
}
838
1126.3.3 by Jay Pipes
Moves Alter_info out into its own header and source file, cleans up some related include mess in sql_lex.h, and renames Alter_info to AlterInfo.
839
/**
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
840
  Alter table
841
842
  SYNOPSIS
1130.3.13 by Monty Taylor
Finished cleaning namespaces in drizzled/statement
843
    alter_table()
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
844
      session              Thread handle
845
      new_db           If there is a RENAME clause
846
      new_name         If there is a RENAME clause
847
      create_info      Information from the parsing phase about new
848
                       table properties.
849
      table_list       The table to change.
850
      alter_info       Lists of fields, keys to be changed, added
851
                       or dropped.
1273.2.13 by Stewart Smith
fix accidental mangling of comment: s/order_st BY/ORDER BY/. in drizzled/statement/alter_table.cc
852
      order_num        How many ORDER BY fields has been specified.
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
853
      order            List of fields to order_st BY.
854
      ignore           Whether we have ALTER IGNORE Table
855
856
  DESCRIPTION
857
    This is a veery long function and is everything but the kitchen sink :)
858
    It is used to alter a table and not only by ALTER Table but also
859
    CREATE|DROP INDEX are mapped on this function.
860
861
    When the ALTER Table statement just does a RENAME or ENABLE|DISABLE KEYS,
862
    or both, then this function short cuts its operation by renaming
863
    the table and/or enabling/disabling the keys. In this case, the FRM is
1130.3.13 by Monty Taylor
Finished cleaning namespaces in drizzled/statement
864
    not changed, directly by alter_table. However, if there is a
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
865
    RENAME + change of a field, or an index, the short cut is not used.
866
    See how `create_list` is used to generate the new FRM regarding the
867
    structure of the fields. The same is done for the indices of the table.
868
869
    Important is the fact, that this function tries to do as little work as
870
    possible, by finding out whether a intermediate table is needed to copy
871
    data into and when finishing the altering to use it as the original table.
872
    For this reason the function compare_tables() is called, which decides
873
    based on all kind of data how similar are the new and the original
874
    tables.
875
876
  RETURN VALUES
877
    false  OK
878
    true   Error
879
*/
1395.1.3 by Brian Aker
Pass through on refactoring, locks now are wrapped up in layer above.
880
881
static bool internal_alter_table(Session *session,
882
                                 Table *table,
883
                                 TableIdentifier &original_table_identifier,
884
                                 TableIdentifier &new_table_identifier,
885
                                 HA_CREATE_INFO *create_info,
1502.1.30 by Brian Aker
First pass on cleanup of Stewart's patch, plus re-engineer to make it work a
886
                                 const message::Table &original_proto,
1395.1.3 by Brian Aker
Pass through on refactoring, locks now are wrapped up in layer above.
887
                                 message::Table &create_proto,
888
                                 TableList *table_list,
889
                                 AlterInfo *alter_info,
890
                                 uint32_t order_num,
1892.3.3 by tdavies
struct order_st changed and renamed to c++ class named:Order
891
                                 Order *order,
1395.1.3 by Brian Aker
Pass through on refactoring, locks now are wrapped up in layer above.
892
                                 bool ignore)
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
893
{
894
  int error= 0;
895
  char tmp_name[80];
896
  char old_name[32];
897
  ha_rows copied= 0;
898
  ha_rows deleted= 0;
899
1992.4.1 by Brian Aker
Update code for testing identifiers/table/schema name correctness.
900
  if (not original_table_identifier.isValid())
901
    return true;
902
903
  if (not new_table_identifier.isValid())
904
    return true;
905
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
906
  session->set_proc_info("init");
907
908
  table->use_all_columns();
909
1395.1.4 by Brian Aker
Last of the goto are gone.
910
  plugin::StorageEngine *new_engine;
911
  plugin::StorageEngine *original_engine;
912
1574 by Brian Aker
Rollup patch for hiding tableshare.
913
  original_engine= table->getMutableShare()->getEngine();
1395.1.4 by Brian Aker
Last of the goto are gone.
914
915
  if (not create_info->db_type)
916
  {
917
    create_info->db_type= original_engine;
918
  }
919
  new_engine= create_info->db_type;
920
921
1395.1.9 by Brian Aker
Small cleanup around how we do types internally.
922
  create_proto.set_schema(new_table_identifier.getSchemaName());
923
  create_proto.set_type(new_table_identifier.getType());
1395.1.4 by Brian Aker
Last of the goto are gone.
924
925
  /**
926
    @todo Have a check on the table definition for FK in the future 
927
    to remove the need for the cursor. (aka can_switch_engines())
928
  */
929
  if (new_engine != original_engine &&
930
      not table->cursor->can_switch_engines())
931
  {
932
    assert(0);
933
    my_error(ER_ROW_IS_REFERENCED, MYF(0));
934
935
    return true;
936
  }
937
938
  if (original_engine->check_flag(HTON_BIT_ALTER_NOT_SUPPORTED) ||
939
      new_engine->check_flag(HTON_BIT_ALTER_NOT_SUPPORTED))
940
  {
1954.2.1 by Brian Aker
getSQLPath() modified to take a string so that we can const the table
941
    std::string path;
942
    new_table_identifier.getSQLPath(path);
943
    my_error(ER_ILLEGAL_HA, MYF(0), path.c_str());
1395.1.4 by Brian Aker
Last of the goto are gone.
944
945
    return true;
946
  }
947
948
  session->set_proc_info("setup");
949
950
  /*
951
   * test if no other bits except ALTER_RENAME and ALTER_KEYS_ONOFF are set
952
 */
953
  {
954
    bitset<32> tmp;
955
956
    tmp.set();
957
    tmp.reset(ALTER_RENAME);
958
    tmp.reset(ALTER_KEYS_ONOFF);
959
    tmp&= alter_info->flags;
960
1608.2.3 by Brian Aker
Encapsulate type for TableShare.
961
    if (! (tmp.any()) && ! table->getShare()->getType()) // no need to touch frm
1395.1.4 by Brian Aker
Last of the goto are gone.
962
    {
963
      switch (alter_info->keys_onoff)
964
      {
965
      case LEAVE_AS_IS:
966
        break;
967
      case ENABLE:
968
        /*
969
          wait_while_table_is_used() ensures that table being altered is
970
          opened only by this thread and that Table::TableShare::version
971
          of Table object corresponding to this table is 0.
972
          The latter guarantees that no DML statement will open this table
973
          until ALTER Table finishes (i.e. until close_thread_tables())
974
          while the fact that the table is still open gives us protection
975
          from concurrent DDL statements.
976
        */
1938.4.10 by Brian Aker
Convert LOCK_open to lock in mutex
977
        table::Cache::singleton().mutex().lock(); /* DDL wait for/blocker */
1395.1.4 by Brian Aker
Last of the goto are gone.
978
        wait_while_table_is_used(session, table, HA_EXTRA_FORCE_REOPEN);
1938.4.10 by Brian Aker
Convert LOCK_open to lock in mutex
979
        table::Cache::singleton().mutex().unlock();
1395.1.4 by Brian Aker
Last of the goto are gone.
980
        error= table->cursor->ha_enable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
981
        /* COND_refresh will be signaled in close_thread_tables() */
982
        break;
983
      case DISABLE:
1938.4.10 by Brian Aker
Convert LOCK_open to lock in mutex
984
        table::Cache::singleton().mutex().lock(); /* DDL wait for/blocker */
1395.1.4 by Brian Aker
Last of the goto are gone.
985
        wait_while_table_is_used(session, table, HA_EXTRA_FORCE_REOPEN);
1938.4.10 by Brian Aker
Convert LOCK_open to lock in mutex
986
        table::Cache::singleton().mutex().unlock();
1395.1.4 by Brian Aker
Last of the goto are gone.
987
        error=table->cursor->ha_disable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
988
        /* COND_refresh will be signaled in close_thread_tables() */
989
        break;
990
      default:
991
        assert(false);
992
        error= 0;
993
        break;
994
      }
995
996
      if (error == HA_ERR_WRONG_COMMAND)
997
      {
998
        error= 0;
999
        push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
1000
                            ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA),
1669.2.6 by Brian Aker
First pass through encapsulating getAlias() from table.
1001
                            table->getAlias());
1395.1.4 by Brian Aker
Last of the goto are gone.
1002
      }
1003
1938.4.10 by Brian Aker
Convert LOCK_open to lock in mutex
1004
      table::Cache::singleton().mutex().lock(); /* Lock to remove all instances of table from table cache before ALTER */
1395.1.4 by Brian Aker
Last of the goto are gone.
1005
      /*
1006
        Unlike to the above case close_cached_table() below will remove ALL
1007
        instances of Table from table cache (it will also remove table lock
1008
        held by this thread). So to make actual table renaming and writing
1009
        to binlog atomic we have to put them into the same critical section
1938.4.10 by Brian Aker
Convert LOCK_open to lock in mutex
1010
        protected by table::Cache::singleton().mutex() mutex. This also removes gap for races between
1395.1.4 by Brian Aker
Last of the goto are gone.
1011
        access() and mysql_rename_table() calls.
1012
      */
1013
1014
      if (error == 0 &&  not (original_table_identifier == new_table_identifier))
1015
      {
1016
        session->set_proc_info("rename");
1017
        /*
1018
          Then do a 'simple' rename of the table. First we need to close all
1019
          instances of 'source' table.
1020
        */
1021
        session->close_cached_table(table);
1022
        /*
1023
          Then, we want check once again that target table does not exist.
1024
          Actually the order of these two steps does not matter since
1025
          earlier we took name-lock on the target table, so we do them
1026
          in this particular order only to be consistent with 5.0, in which
1027
          we don't take this name-lock and where this order really matters.
1028
          @todo Investigate if we need this access() check at all.
1029
        */
1030
        if (plugin::StorageEngine::doesTableExist(*session, new_table_identifier))
1031
        {
1954.2.1 by Brian Aker
getSQLPath() modified to take a string so that we can const the table
1032
          std::string path;
1033
          new_table_identifier.getSQLPath(path);
1034
          my_error(ER_TABLE_EXISTS_ERROR, MYF(0), path.c_str());
1395.1.4 by Brian Aker
Last of the goto are gone.
1035
          error= -1;
1036
        }
1037
        else
1038
        {
1578.4.11 by Brian Aker
PAss through the code removing current_session
1039
          if (mysql_rename_table(*session, original_engine, original_table_identifier, new_table_identifier))
1395.1.2 by Brian Aker
More logic pulling from ALTER TABLE
1040
          {
1041
            error= -1;
1042
          }
1395.1.4 by Brian Aker
Last of the goto are gone.
1043
        }
1044
      }
1045
1046
      if (error == HA_ERR_WRONG_COMMAND)
1047
      {
1048
        error= 0;
1049
        push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
1050
                            ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA),
1669.2.6 by Brian Aker
First pass through encapsulating getAlias() from table.
1051
                            table->getAlias());
1395.1.4 by Brian Aker
Last of the goto are gone.
1052
      }
1053
1054
      if (error == 0)
1055
      {
1926.3.3 by Joseph Daly
move the call to allocate the trx id to the exact place its needed having it in write_bin_log will result in it being allocated where it is not needed
1056
        TransactionServices &transaction_services= TransactionServices::singleton();
1057
        transaction_services.allocateNewTransactionId();
1921.4.13 by Brian Aker
Fix issue where session info might not be correct.
1058
        write_bin_log(session, *session->getQueryString());
1395.1.4 by Brian Aker
Last of the goto are gone.
1059
        session->my_ok();
1060
      }
1061
      else if (error > 0)
1062
      {
1063
        table->print_error(error, MYF(0));
1064
        error= -1;
1065
      }
1066
1938.4.10 by Brian Aker
Convert LOCK_open to lock in mutex
1067
      table::Cache::singleton().mutex().unlock();
1395.1.4 by Brian Aker
Last of the goto are gone.
1068
      table_list->table= NULL;
1069
1070
      return error;
1372.1.1 by Brian Aker
Removed/rewrite to remove goto in alter table.
1071
    }
1395.1.4 by Brian Aker
Last of the goto are gone.
1072
  }
1073
1074
  /* We have to do full alter table. */
1075
  new_engine= create_info->db_type;
1076
1502.1.30 by Brian Aker
First pass on cleanup of Stewart's patch, plus re-engineer to make it work a
1077
  if (mysql_prepare_alter_table(session, table, create_info, original_proto, create_proto, alter_info))
1395.1.4 by Brian Aker
Last of the goto are gone.
1078
  {
1079
    return true;
1080
  }
1081
1082
  set_table_default_charset(create_info, new_table_identifier.getSchemaName().c_str());
1083
1084
  alter_info->build_method= HA_BUILD_OFFLINE;
1085
1086
  snprintf(tmp_name, sizeof(tmp_name), "%s-%lx_%"PRIx64, TMP_FILE_PREFIX, (unsigned long) current_pid, session->thread_id);
1087
1088
  /* Create a temporary table with the new format */
1089
  /**
1090
    @note we make an internal temporary table unless the table is a temporary table. In last
1091
    case we just use it as is. Neither of these tables require locks in order to  be
1092
    filled.
1093
  */
1094
  TableIdentifier new_table_as_temporary(original_table_identifier.getSchemaName(),
1095
                                         tmp_name,
1395.1.7 by Brian Aker
Removed the internal table type in favor of the protobuf one.
1096
                                         create_proto.type() != message::Table::TEMPORARY ? message::Table::INTERNAL :
1097
                                         message::Table::TEMPORARY);
1395.1.4 by Brian Aker
Last of the goto are gone.
1098
1099
  error= create_temporary_table(session, new_table_as_temporary, create_info, create_proto, alter_info);
1100
1101
  if (error != 0)
1102
  {
1103
    return true;
1104
  }
1105
1106
  /* Open the table so we need to copy the data to it. */
1669.2.4 by Brian Aker
Fix temp tables to use new over malloc.
1107
  Table *new_table= open_alter_table(session, table, new_table_as_temporary);
1108
1395.1.4 by Brian Aker
Last of the goto are gone.
1109
1110
  if (not new_table)
1111
  {
1954.2.4 by Brian Aker
Remove quick_rm_table().
1112
    plugin::StorageEngine::dropTable(*session, new_table_as_temporary);
1395.1.4 by Brian Aker
Last of the goto are gone.
1113
    return true;
1114
  }
1115
1116
  /* Copy the data if necessary. */
1117
  {
1633.4.8 by Brian Aker
Update for count_cuted_fields.
1118
    /* We must not ignore bad input! */
1119
    session->count_cuted_fields= CHECK_FIELD_ERROR_FOR_NULL;	// calc cuted fields
1372.1.1 by Brian Aker
Removed/rewrite to remove goto in alter table.
1120
    session->cuted_fields= 0L;
1121
    session->set_proc_info("copy to tmp table");
1122
    copied= deleted= 0;
1123
1124
    /* We don't want update TIMESTAMP fields during ALTER Table. */
1125
    new_table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
1126
    new_table->next_number_field= new_table->found_next_number_field;
1578.4.11 by Brian Aker
PAss through the code removing current_session
1127
    error= copy_data_between_tables(session,
1128
                                    table,
1372.1.1 by Brian Aker
Removed/rewrite to remove goto in alter table.
1129
                                    new_table,
1130
                                    alter_info->create_list,
1131
                                    ignore,
1132
                                    order_num,
1133
                                    order,
1134
                                    &copied,
1135
                                    &deleted,
1136
                                    alter_info->keys_onoff,
1137
                                    alter_info->error_if_not_empty);
1138
1139
    /* We must not ignore bad input! */
1637.1.1 by Brian Aker
Add in assert for detecting changes during alter.
1140
    assert(session->count_cuted_fields == CHECK_FIELD_ERROR_FOR_NULL);
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
1141
  }
1142
1395.1.4 by Brian Aker
Last of the goto are gone.
1143
  /* Now we need to resolve what just happened with the data copy. */
1144
1145
  if (error)
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
1146
  {
1376 by Brian Aker
Fix for goto that could be removed.
1147
1395.1.4 by Brian Aker
Last of the goto are gone.
1148
    /*
1149
      No default value was provided for a DATE/DATETIME field, the
1150
      current sql_mode doesn't allow the '0000-00-00' value and
1151
      the table to be altered isn't empty.
1152
      Report error here.
1153
    */
1154
    if (alter_info->error_if_not_empty && session->row_count)
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
1155
    {
1976.6.1 by Brian Aker
This is a fix for bug lp:686197
1156
      my_error(ER_INVALID_ALTER_TABLE_FOR_NOT_NULL, MYF(0));
1395.1.4 by Brian Aker
Last of the goto are gone.
1157
    }
1158
1159
    if (original_table_identifier.isTmp())
1160
    {
1161
      if (new_table)
1162
      {
1163
        /* close_temporary_table() frees the new_table pointer. */
1164
        session->close_temporary_table(new_table);
1165
      }
1166
      else
1167
      {
1954.2.4 by Brian Aker
Remove quick_rm_table().
1168
        plugin::StorageEngine::dropTable(*session, new_table_as_temporary);
1395.1.4 by Brian Aker
Last of the goto are gone.
1169
      }
1170
1171
      return true;
1172
    }
1173
    else
1174
    {
1175
      if (new_table)
1176
      {
1177
        /*
1178
          Close the intermediate table that will be the new table.
1179
          Note that MERGE tables do not have their children attached here.
1180
        */
1181
        new_table->intern_close_table();
1574 by Brian Aker
Rollup patch for hiding tableshare.
1182
        if (new_table->hasShare())
1502.1.13 by Brian Aker
Next bit of TableShare to c++.
1183
        {
1827.2.1 by Brian Aker
Encapsulate Table (remove its direct access of the share it contains)
1184
          delete new_table->getMutableShare();
1502.1.13 by Brian Aker
Next bit of TableShare to c++.
1185
        }
1186
1669.2.4 by Brian Aker
Fix temp tables to use new over malloc.
1187
        delete new_table;
1395.1.4 by Brian Aker
Last of the goto are gone.
1188
      }
1189
1938.4.10 by Brian Aker
Convert LOCK_open to lock in mutex
1190
      table::Cache::singleton().mutex().lock(); /* ALTER TABLE */
1395.1.4 by Brian Aker
Last of the goto are gone.
1191
1954.2.4 by Brian Aker
Remove quick_rm_table().
1192
      plugin::StorageEngine::dropTable(*session, new_table_as_temporary);
1938.4.10 by Brian Aker
Convert LOCK_open to lock in mutex
1193
      table::Cache::singleton().mutex().unlock();
1395.1.4 by Brian Aker
Last of the goto are gone.
1194
1195
      return true;
1196
    }
1197
  }
1198
  // Temporary table and success
1199
  else if (original_table_identifier.isTmp())
1200
  {
1201
    /* Close lock if this is a transactional table */
1202
    if (session->lock)
1203
    {
1910.2.7 by Brian Aker
Rename lock methods to be style + well make sense.
1204
      session->unlockTables(session->lock);
1395.1.4 by Brian Aker
Last of the goto are gone.
1205
      session->lock= 0;
1206
    }
1207
1208
    /* Remove link to old table and rename the new one */
1209
    session->close_temporary_table(table);
1210
1211
    /* Should pass the 'new_name' as we store table name in the cache */
1618 by Brian Aker
This is a rollup set of patches for modifications to TableIdentifier to have
1212
    new_table->getMutableShare()->setIdentifier(new_table_identifier);
1395.1.14 by Brian Aker
Fix for Innodb dfe files.
1213
1214
    new_table_identifier.setPath(new_table_as_temporary.getPath());
1215
1578.4.11 by Brian Aker
PAss through the code removing current_session
1216
    if (mysql_rename_table(*session, new_engine, new_table_as_temporary, new_table_identifier) != 0)
1395.1.14 by Brian Aker
Fix for Innodb dfe files.
1217
    {
1218
      return true;
1219
    }
1395.1.4 by Brian Aker
Last of the goto are gone.
1220
  }
1221
  // Normal table success
1222
  else
1223
  {
1224
    if (new_table)
1225
    {
1226
      /*
1227
        Close the intermediate table that will be the new table.
1228
        Note that MERGE tables do not have their children attached here.
1229
      */
1230
      new_table->intern_close_table();
1502.1.12 by Brian Aker
Second pass through TableShare to new(). Partial hack in using bool for the
1231
1574 by Brian Aker
Rollup patch for hiding tableshare.
1232
      if (new_table->hasShare())
1502.1.13 by Brian Aker
Next bit of TableShare to c++.
1233
      {
1827.2.1 by Brian Aker
Encapsulate Table (remove its direct access of the share it contains)
1234
        delete new_table->getMutableShare();
1502.1.12 by Brian Aker
Second pass through TableShare to new(). Partial hack in using bool for the
1235
      }
1236
1669.2.4 by Brian Aker
Fix temp tables to use new over malloc.
1237
      delete new_table;
1395.1.4 by Brian Aker
Last of the goto are gone.
1238
    }
1239
1938.4.10 by Brian Aker
Convert LOCK_open to lock in mutex
1240
    table::Cache::singleton().mutex().lock(); /* ALTER TABLE */
1395.1.4 by Brian Aker
Last of the goto are gone.
1241
1242
    /*
1243
      Data is copied. Now we:
1244
      1) Wait until all other threads close old version of table.
1245
      2) Close instances of table open by this thread and replace them
1246
      with exclusive name-locks.
1247
      3) Rename the old table to a temp name, rename the new one to the
1248
      old name.
1249
      4) If we are under LOCK TABLES and don't do ALTER Table ... RENAME
1250
      we reopen new version of table.
1251
      5) Write statement to the binary log.
1252
      6) If we are under LOCK TABLES and do ALTER Table ... RENAME we
1253
      remove name-locks from list of open tables and table cache.
1254
      7) If we are not not under LOCK TABLES we rely on close_thread_tables()
1255
      call to remove name-locks from table cache and list of open table.
1256
    */
1257
1258
    session->set_proc_info("rename result table");
1259
1260
    snprintf(old_name, sizeof(old_name), "%s2-%lx-%"PRIx64, TMP_FILE_PREFIX, (unsigned long) current_pid, session->thread_id);
1261
1262
    my_casedn_str(files_charset_info, old_name);
1263
1264
    wait_while_table_is_used(session, table, HA_EXTRA_PREPARE_FOR_RENAME);
1265
    session->close_data_files_and_morph_locks(original_table_identifier);
1266
1267
    error= 0;
1268
1269
    /*
1270
      This leads to the storage engine (SE) not being notified for renames in
1271
      mysql_rename_table(), because we just juggle with the FRM and nothing
1272
      more. If we have an intermediate table, then we notify the SE that
1273
      it should become the actual table. Later, we will recycle the old table.
1274
      However, in case of ALTER Table RENAME there might be no intermediate
1275
      table. This is when the old and new tables are compatible, according to
1276
      compare_table(). Then, we need one additional call to
1277
    */
1278
    TableIdentifier original_table_to_drop(original_table_identifier.getSchemaName(),
1696.1.1 by Stewart Smith
fix identifier generation in alter_table. fixes a failure in embedded_innodb
1279
                                           old_name, create_proto.type() != message::Table::TEMPORARY ? message::Table::INTERNAL :
1280
                                         message::Table::TEMPORARY);
1395.1.4 by Brian Aker
Last of the goto are gone.
1281
1578.4.11 by Brian Aker
PAss through the code removing current_session
1282
    if (mysql_rename_table(*session, original_engine, original_table_identifier, original_table_to_drop))
1395.1.4 by Brian Aker
Last of the goto are gone.
1283
    {
1284
      error= 1;
1954.2.4 by Brian Aker
Remove quick_rm_table().
1285
      plugin::StorageEngine::dropTable(*session, new_table_as_temporary);
1395.1.4 by Brian Aker
Last of the goto are gone.
1286
    }
1287
    else
1288
    {
1578.4.11 by Brian Aker
PAss through the code removing current_session
1289
      if (mysql_rename_table(*session, new_engine, new_table_as_temporary, new_table_identifier) != 0)
1395.1.4 by Brian Aker
Last of the goto are gone.
1290
      {
1291
        /* Try to get everything back. */
1292
        error= 1;
1293
1954.2.4 by Brian Aker
Remove quick_rm_table().
1294
        plugin::StorageEngine::dropTable(*session, new_table_identifier);
1395.1.4 by Brian Aker
Last of the goto are gone.
1295
1954.2.4 by Brian Aker
Remove quick_rm_table().
1296
        plugin::StorageEngine::dropTable(*session, new_table_as_temporary);
1395.1.4 by Brian Aker
Last of the goto are gone.
1297
1578.4.11 by Brian Aker
PAss through the code removing current_session
1298
        mysql_rename_table(*session, original_engine, original_table_to_drop, original_table_identifier);
1395.1.4 by Brian Aker
Last of the goto are gone.
1299
      }
1300
      else
1301
      {
1954.2.4 by Brian Aker
Remove quick_rm_table().
1302
        plugin::StorageEngine::dropTable(*session, original_table_to_drop);
1395.1.4 by Brian Aker
Last of the goto are gone.
1303
      }
1304
    }
1305
1306
    if (error)
1307
    {
1308
      /*
1309
        An error happened while we were holding exclusive name-lock on table
1310
        being altered. To be safe under LOCK TABLES we should remove placeholders
1311
        from list of open tables list and table cache.
1312
      */
1313
      session->unlink_open_table(table);
1938.4.10 by Brian Aker
Convert LOCK_open to lock in mutex
1314
      table::Cache::singleton().mutex().unlock();
1395.1.4 by Brian Aker
Last of the goto are gone.
1315
1316
      return true;
1317
    }
1318
1938.4.10 by Brian Aker
Convert LOCK_open to lock in mutex
1319
    table::Cache::singleton().mutex().unlock();
1395.1.4 by Brian Aker
Last of the goto are gone.
1320
1321
    session->set_proc_info("end");
1322
1921.4.13 by Brian Aker
Fix issue where session info might not be correct.
1323
    write_bin_log(session, *session->getQueryString());
1395.1.4 by Brian Aker
Last of the goto are gone.
1324
    table_list->table= NULL;
1325
  }
1326
1327
  /*
1328
   * Field::store() may have called my_error().  If this is 
1329
   * the case, we must not send an ok packet, since 
1330
   * Diagnostics_area::is_set() will fail an assert.
1331
 */
1332
  if (session->is_error())
1333
  {
1334
    /* my_error() was called.  Return true (which means error...) */
1335
    return true;
1336
  }
1337
1338
  snprintf(tmp_name, sizeof(tmp_name), ER(ER_INSERT_INFO),
1339
           (ulong) (copied + deleted), (ulong) deleted,
1340
           (ulong) session->cuted_fields);
1341
  session->my_ok(copied + deleted, 0, 0L, tmp_name);
1342
  session->some_tables_deleted= 0;
1343
1344
  return false;
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
1345
}
1395.1.3 by Brian Aker
Pass through on refactoring, locks now are wrapped up in layer above.
1346
1347
bool alter_table(Session *session,
1348
                 TableIdentifier &original_table_identifier,
1349
                 TableIdentifier &new_table_identifier,
1350
                 HA_CREATE_INFO *create_info,
1502.1.30 by Brian Aker
First pass on cleanup of Stewart's patch, plus re-engineer to make it work a
1351
                 const message::Table &original_proto,
1395.1.3 by Brian Aker
Pass through on refactoring, locks now are wrapped up in layer above.
1352
                 message::Table &create_proto,
1353
                 TableList *table_list,
1354
                 AlterInfo *alter_info,
1355
                 uint32_t order_num,
1892.3.3 by tdavies
struct order_st changed and renamed to c++ class named:Order
1356
                 Order *order,
1395.1.3 by Brian Aker
Pass through on refactoring, locks now are wrapped up in layer above.
1357
                 bool ignore)
1358
{
1359
  bool error;
1360
  Table *table;
1361
1362
  if (alter_info->tablespace_op != NO_TABLESPACE_OP)
1363
  {
1364
    /* DISCARD/IMPORT TABLESPACE is always alone in an ALTER Table */
1365
    return mysql_discard_or_import_tablespace(session, table_list, alter_info->tablespace_op);
1366
  }
1367
1368
  session->set_proc_info("init");
1369
1370
  if (not (table= session->openTableLock(table_list, TL_WRITE_ALLOW_READ)))
1371
    return true;
1372
1373
  session->set_proc_info("gained write lock on table");
1374
1375
  /* 
1376
    Check that we are not trying to rename to an existing table,
1377
    if one existed we get a lock, if we can't we error.
1378
  */
1379
  {
1380
    Table *name_lock= NULL;
1381
1382
    if (not lockTableIfDifferent(*session, original_table_identifier, new_table_identifier, name_lock))
1383
    {
1384
      return true;
1385
    }
1386
1387
    error= internal_alter_table(session,
1388
                                table,
1389
                                original_table_identifier,
1390
                                new_table_identifier,
1391
                                create_info,
1502.1.30 by Brian Aker
First pass on cleanup of Stewart's patch, plus re-engineer to make it work a
1392
                                original_proto,
1395.1.3 by Brian Aker
Pass through on refactoring, locks now are wrapped up in layer above.
1393
                                create_proto,
1394
                                table_list,
1395
                                alter_info,
1396
                                order_num,
1397
                                order,
1398
                                ignore);
1399
1400
    if (name_lock)
1401
    {
1938.4.10 by Brian Aker
Convert LOCK_open to lock in mutex
1402
      table::Cache::singleton().mutex().lock(); /* ALTER TABLe */
1395.1.3 by Brian Aker
Pass through on refactoring, locks now are wrapped up in layer above.
1403
      session->unlink_open_table(name_lock);
1938.4.10 by Brian Aker
Convert LOCK_open to lock in mutex
1404
      table::Cache::singleton().mutex().unlock();
1395.1.3 by Brian Aker
Pass through on refactoring, locks now are wrapped up in layer above.
1405
    }
1406
  }
1407
1408
  return error;
1409
}
1130.3.13 by Monty Taylor
Finished cleaning namespaces in drizzled/statement
1410
/* alter_table */
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
1411
1412
static int
1578.4.11 by Brian Aker
PAss through the code removing current_session
1413
copy_data_between_tables(Session *session,
1414
                         Table *from, Table *to,
1216.1.1 by Brian Aker
Move print_error up to Engine.
1415
                         List<CreateField> &create,
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
1416
                         bool ignore,
1892.3.3 by tdavies
struct order_st changed and renamed to c++ class named:Order
1417
                         uint32_t order_num, Order *order,
1216.1.1 by Brian Aker
Move print_error up to Engine.
1418
                         ha_rows *copied,
1419
                         ha_rows *deleted,
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
1420
                         enum enum_enable_or_disable keys_onoff,
1421
                         bool error_if_not_empty)
1422
{
1273.1.3 by Jay Pipes
Removes pointless ha_enable_transaction call. This wasn't used anywhere to any effect.
1423
  int error= 0;
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
1424
  CopyField *copy,*copy_end;
1425
  ulong found_count,delete_count;
1426
  uint32_t length= 0;
1711.6.1 by Brian Aker
Style on structure cleanup
1427
  SortField *sortorder;
1538 by Brian Aker
Code shuffle on ReadRecord
1428
  ReadRecord info;
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
1429
  TableList   tables;
1430
  List<Item>   fields;
1431
  List<Item>   all_fields;
1432
  ha_rows examined_rows;
1433
  bool auto_increment_field_copied= 0;
1434
  uint64_t prev_insert_id;
1435
1436
  /*
1437
    Turn off recovery logging since rollback of an alter table is to
1438
    delete the new table so there is no need to log the changes to it.
1439
1440
    This needs to be done before external_lock
1441
  */
1273.1.2 by Jay Pipes
This patch does not change any algorithms or code paths,
1442
  TransactionServices &transaction_services= TransactionServices::singleton();
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
1443
1510.4.2 by Jay Pipes
Fixes Bug #552420. Because the copied-to table in ALTER TABLE is temporary, mysql_lock_tables() is not called, and the automatic StorageEngine::startStatement() is also not called. So, we call it manually to ensure transactional engines have a notification of a new statement/transaction.
1444
  /* 
1445
   * LP Bug #552420 
1446
   *
1910.2.7 by Brian Aker
Rename lock methods to be style + well make sense.
1447
   * Since open_temporary_table() doesn't invoke lockTables(), we
1510.4.2 by Jay Pipes
Fixes Bug #552420. Because the copied-to table in ALTER TABLE is temporary, mysql_lock_tables() is not called, and the automatic StorageEngine::startStatement() is also not called. So, we call it manually to ensure transactional engines have a notification of a new statement/transaction.
1448
   * don't get the usual automatic call to StorageEngine::startStatement(), so
1449
   * we manually call it here...
1450
   */
1827.2.1 by Brian Aker
Encapsulate Table (remove its direct access of the share it contains)
1451
  to->getMutableShare()->getEngine()->startStatement(session);
1510.4.2 by Jay Pipes
Fixes Bug #552420. Because the copied-to table in ALTER TABLE is temporary, mysql_lock_tables() is not called, and the automatic StorageEngine::startStatement() is also not called. So, we call it manually to ensure transactional engines have a notification of a new statement/transaction.
1452
1578.2.10 by Brian Aker
keys and fields partial encapsulation.
1453
  if (!(copy= new CopyField[to->getShare()->sizeFields()]))
971.6.13 by Eric Day
Removed a few more purecov messages missed in merge.
1454
    return -1;
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
1455
1208.3.2 by brian
Update for Cursor renaming.
1456
  if (to->cursor->ha_external_lock(session, F_WRLCK))
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
1457
    return -1;
1458
1459
  /* We need external lock before we can disable/enable keys */
1578.4.11 by Brian Aker
PAss through the code removing current_session
1460
  alter_table_manage_keys(session, to, from->cursor->indexes_are_disabled(), keys_onoff);
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
1461
1462
  /* We can abort alter table for any table type */
1463
  session->abort_on_warning= !ignore;
1464
1208.3.2 by brian
Update for Cursor renaming.
1465
  from->cursor->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
1466
  to->cursor->ha_start_bulk_insert(from->cursor->stats.records);
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
1467
1468
  List_iterator<CreateField> it(create);
1469
  CreateField *def;
1470
  copy_end=copy;
1578.2.16 by Brian Aker
Merge in change to getTable() to private the field objects.
1471
  for (Field **ptr= to->getFields(); *ptr ; ptr++)
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
1472
  {
1473
    def=it++;
1474
    if (def->field)
1475
    {
1476
      if (*ptr == to->next_number_field)
1477
        auto_increment_field_copied= true;
1478
1479
      (copy_end++)->set(*ptr,def->field,0);
1480
    }
1481
1482
  }
1483
1484
  found_count=delete_count=0;
1485
1486
  if (order)
1487
  {
1618 by Brian Aker
This is a rollup set of patches for modifications to TableIdentifier to have
1488
    if (to->getShare()->hasPrimaryKey() && to->cursor->primary_key_is_clustered())
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
1489
    {
1490
      char warn_buff[DRIZZLE_ERRMSG_SIZE];
1491
      snprintf(warn_buff, sizeof(warn_buff),
1492
               _("order_st BY ignored because there is a user-defined clustered "
1493
                 "index in the table '%-.192s'"),
1574 by Brian Aker
Rollup patch for hiding tableshare.
1494
               from->getMutableShare()->getTableName());
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
1495
      push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_UNKNOWN_ERROR,
1496
                   warn_buff);
1497
    }
1498
    else
1499
    {
1905.1.1 by Brian Aker
Adding FileSort class.
1500
      FileSort filesort(*session);
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
1501
      from->sort.io_cache= new internal::IO_CACHE;
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
1502
1503
      memset(&tables, 0, sizeof(tables));
1504
      tables.table= from;
1874.1.2 by Brian Aker
Encapsulate table_name from table_list.
1505
      tables.setTableName(const_cast<char *>(from->getMutableShare()->getTableName()));
1506
      tables.alias= const_cast<char *>(tables.getTableName());
1874.1.1 by Brian Aker
Encapsulate schema_name it table_list.
1507
      tables.setSchemaName(const_cast<char *>(from->getMutableShare()->getSchemaName()));
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
1508
      error= 1;
1509
1510
      if (session->lex->select_lex.setup_ref_array(session, order_num) ||
1511
          setup_order(session, session->lex->select_lex.ref_pointer_array,
1512
                      &tables, fields, all_fields, order) ||
1513
          !(sortorder= make_unireg_sortorder(order, &length, NULL)) ||
1905.1.1 by Brian Aker
Adding FileSort class.
1514
          (from->sort.found_records= filesort.run(from, sortorder, length,
1515
                                                  (optimizer::SqlSelect *) 0, HA_POS_ERROR,
1908.1.1 by Brian Aker
Merge in encapsulations in filesort.
1516
                                                  1, examined_rows)) == HA_POS_ERROR)
1395.1.4 by Brian Aker
Last of the goto are gone.
1517
      {
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
1518
        goto err;
1395.1.4 by Brian Aker
Last of the goto are gone.
1519
      }
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
1520
    }
1395.1.4 by Brian Aker
Last of the goto are gone.
1521
  }
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
1522
1523
  /* Tell handler that we have values for all columns in the to table */
1524
  to->use_all_columns();
1538 by Brian Aker
Code shuffle on ReadRecord
1525
  info.init_read_record(session, from, (optimizer::SqlSelect *) 0, 1, true);
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
1526
  if (ignore)
1208.3.2 by brian
Update for Cursor renaming.
1527
    to->cursor->extra(HA_EXTRA_IGNORE_DUP_KEY);
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
1528
  session->row_count= 0;
1529
  to->restoreRecordAsDefault();        // Create empty record
1530
  while (!(error=info.read_record(&info)))
1531
  {
1910.2.8 by Brian Aker
Enapsulate Kill.
1532
    if (session->getKilled())
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
1533
    {
1534
      session->send_kill_message();
1535
      error= 1;
1536
      break;
1537
    }
1538
    session->row_count++;
1539
    /* Return error if source table isn't empty. */
1540
    if (error_if_not_empty)
1541
    {
1542
      error= 1;
1543
      break;
1544
    }
1545
    if (to->next_number_field)
1546
    {
1547
      if (auto_increment_field_copied)
1548
        to->auto_increment_field_not_null= true;
1549
      else
1550
        to->next_number_field->reset();
1551
    }
1552
1976.6.1 by Brian Aker
This is a fix for bug lp:686197
1553
    for (CopyField *copy_ptr= copy; copy_ptr != copy_end ; copy_ptr++)
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
1554
    {
1976.6.1 by Brian Aker
This is a fix for bug lp:686197
1555
      if (not copy->to_field->hasDefault() and copy->from_null_ptr and  *copy->from_null_ptr & copy->from_bit)
1556
      {
1557
        copy->to_field->set_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN,
1558
                                    ER_WARN_DATA_TRUNCATED, 1);
1559
        copy->to_field->reset();
1560
        error= 1;
1561
        break;
1562
      }
1563
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
1564
      copy_ptr->do_copy(copy_ptr);
1565
    }
1976.6.1 by Brian Aker
This is a fix for bug lp:686197
1566
1567
    if (error)
1568
    {
1569
      break;
1570
    }
1571
1208.3.2 by brian
Update for Cursor renaming.
1572
    prev_insert_id= to->cursor->next_insert_id;
1491.1.2 by Jay Pipes
Cursor::write_row() -> Cursor::doInsertRecord(). Cursor::ha_write_row() -> Cursor::insertRecord()
1573
    error= to->cursor->insertRecord(to->record[0]);
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
1574
    to->auto_increment_field_not_null= false;
1552.1.3 by Brian Aker
Fixes the assertion bug on handling of auto increment (sort of worthless,
1575
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
1576
    if (error)
1216.1.1 by Brian Aker
Move print_error up to Engine.
1577
    { 
1976.6.1 by Brian Aker
This is a fix for bug lp:686197
1578
      if (!ignore || to->cursor->is_fatal_error(error, HA_CHECK_DUP))
1216.1.1 by Brian Aker
Move print_error up to Engine.
1579
      { 
1580
        to->print_error(error, MYF(0));
1208.3.2 by brian
Update for Cursor renaming.
1581
        break;
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
1582
      }
1208.3.2 by brian
Update for Cursor renaming.
1583
      to->cursor->restore_auto_increment(prev_insert_id);
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
1584
      delete_count++;
1585
    }
1586
    else
1552.1.3 by Brian Aker
Fixes the assertion bug on handling of auto increment (sort of worthless,
1587
    {
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
1588
      found_count++;
1552.1.3 by Brian Aker
Fixes the assertion bug on handling of auto increment (sort of worthless,
1589
    }
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
1590
  }
1552.1.3 by Brian Aker
Fixes the assertion bug on handling of auto increment (sort of worthless,
1591
1538 by Brian Aker
Code shuffle on ReadRecord
1592
  info.end_read_record();
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
1593
  from->free_io_cache();
1594
  delete [] copy;				// This is never 0
1595
1208.3.2 by brian
Update for Cursor renaming.
1596
  if (to->cursor->ha_end_bulk_insert() && error <= 0)
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
1597
  {
1241.9.57 by Monty Taylor
Oy. Bigger change than I normally like - but this stuff is all intertwined.
1598
    to->print_error(errno, MYF(0));
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
1599
    error=1;
1600
  }
1208.3.2 by brian
Update for Cursor renaming.
1601
  to->cursor->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
1602
1603
  /*
1604
    Ensure that the new table is saved properly to disk so that we
1605
    can do a rename
1606
  */
1405.3.5 by Jay Pipes
TransactionServices method names now meet code style guidelines.
1607
  if (transaction_services.autocommitOrRollback(session, false))
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
1608
    error=1;
1609
  if (! session->endActiveTransaction())
1610
    error=1;
1611
1612
 err:
1613
  session->abort_on_warning= 0;
1614
  from->free_io_cache();
1615
  *copied= found_count;
1616
  *deleted=delete_count;
1208.3.2 by brian
Update for Cursor renaming.
1617
  to->cursor->ha_release_auto_increment();
1618
  if (to->cursor->ha_external_lock(session,F_UNLCK))
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
1619
    error=1;
1552.1.3 by Brian Aker
Fixes the assertion bug on handling of auto increment (sort of worthless,
1620
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
1621
  return(error > 0 ? -1 : 0);
1622
}
1623
1624
static int
1625
create_temporary_table(Session *session,
1235.2.1 by Brian Aker
More identifier work.
1626
                       TableIdentifier &identifier,
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
1627
                       HA_CREATE_INFO *create_info,
1320.1.2 by Brian Aker
More reference counting.
1628
                       message::Table &create_proto,
1126.3.3 by Jay Pipes
Moves Alter_info out into its own header and source file, cleans up some related include mess in sql_lex.h, and renames Alter_info to AlterInfo.
1629
                       AlterInfo *alter_info)
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
1630
{
1631
  int error;
1223.4.1 by Brian Aker
Table Identifier patch.
1632
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
1633
  /*
1634
    Create a table with a temporary name.
1635
    We don't log the statement, it will be logged later.
1636
  */
1320.1.2 by Brian Aker
More reference counting.
1637
  create_proto.set_name(identifier.getTableName());
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
1638
1502.1.31 by Brian Aker
Merge engine options for schema/table.
1639
  create_proto.mutable_engine()->set_name(create_info->db_type->getName());
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
1640
1223.4.1 by Brian Aker
Table Identifier patch.
1641
  error= mysql_create_table(session,
1642
                            identifier,
1222.2.3 by Brian Aker
Remove a few more options, from options in HA_CREATE_INFO.
1643
                            create_info, create_proto, alter_info, true, 0, false);
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
1644
1222.2.1 by Brian Aker
Takes the majority usage of parser based HA_CREATE_INFO usage around
1645
  return error;
1126.3.2 by Jay Pipes
Simply moves alter_table specific stuff out of the sql_table.cc grab-bag and into drizzled/statement/alter_table.cc. Next step is to cleanup the code.
1646
}
1647
1395.1.2 by Brian Aker
More logic pulling from ALTER TABLE
1648
static Table *open_alter_table(Session *session, Table *table, TableIdentifier &identifier)
1223.4.13 by Brian Aker
Small shift in alter table (break the baby down...).
1649
{
1650
  Table *new_table;
1651
1652
  /* Open the table so we need to copy the data to it. */
1608.2.3 by Brian Aker
Encapsulate type for TableShare.
1653
  if (table->getShare()->getType())
1223.4.13 by Brian Aker
Small shift in alter table (break the baby down...).
1654
  {
1655
    TableList tbl;
1874.1.1 by Brian Aker
Encapsulate schema_name it table_list.
1656
    tbl.setSchemaName(const_cast<char *>(identifier.getSchemaName().c_str()));
1395.1.2 by Brian Aker
More logic pulling from ALTER TABLE
1657
    tbl.alias= const_cast<char *>(identifier.getTableName().c_str());
1874.1.2 by Brian Aker
Encapsulate table_name from table_list.
1658
    tbl.setTableName(const_cast<char *>(identifier.getTableName().c_str()));
1223.4.13 by Brian Aker
Small shift in alter table (break the baby down...).
1659
1660
    /* Table is in session->temporary_tables */
1661
    new_table= session->openTable(&tbl, (bool*) 0, DRIZZLE_LOCK_IGNORE_FLUSH);
1662
  }
1663
  else
1664
  {
1665
    /* Open our intermediate table */
1395.1.2 by Brian Aker
More logic pulling from ALTER TABLE
1666
    new_table= session->open_temporary_table(identifier, false);
1223.4.13 by Brian Aker
Small shift in alter table (break the baby down...).
1667
  }
1668
1669
  return new_table;
1670
}
1671
1130.3.13 by Monty Taylor
Finished cleaning namespaces in drizzled/statement
1672
} /* namespace drizzled */