~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
 *
4
 *  Copyright (C) 2009 Sun Microsystems
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"
1225.1.24 by Padraig O'Sullivan
Resolved issues with drop and alter table statements on tables in the I_S engine.
38
#include "drizzled/plugin/info_schema_table.h"
1237.9.2 by Padraig O'Sullivan
Moved opt_range.[cc,h] into the optimizer directory and namespace and renamed the files to
39
#include "drizzled/optimizer/range.h"
1237.9.8 by Monty Taylor
Fixed solaris build.
40
#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.
41
#include "drizzled/records.h"
1241.9.31 by Monty Taylor
Moved global pthread variables into their own header.
42
#include "drizzled/pthread_globals.h"
43
44
extern pid_t current_pid;
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.
45
1130.3.6 by Monty Taylor
Removed use of using namespace std; from a header.
46
using namespace std;
1100.3.63 by Padraig O'Sullivan
Extracted the ALTER TABLE command into its own class and implementation
47
1130.3.13 by Monty Taylor
Finished cleaning namespaces in drizzled/statement
48
namespace drizzled
49
{
50
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.
51
static int copy_data_between_tables(Table *from,Table *to,
52
                                    List<CreateField> &create,
53
                                    bool ignore,
54
                                    uint32_t order_num,
55
                                    order_st *order,
56
                                    ha_rows *copied,
57
                                    ha_rows *deleted,
58
                                    enum enum_enable_or_disable keys_onoff,
59
                                    bool error_if_not_empty);
1223.4.13 by Brian Aker
Small shift in alter table (break the baby down...).
60
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.
61
static bool mysql_prepare_alter_table(Session *session,
62
                                      Table *table,
63
                                      HA_CREATE_INFO *create_info,
1130.3.13 by Monty Taylor
Finished cleaning namespaces in drizzled/statement
64
                                      message::Table *table_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.
65
                                      AlterInfo *alter_info);
1223.4.13 by Brian Aker
Small shift in alter table (break the baby down...).
66
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.
67
static int create_temporary_table(Session *session,
68
                                  Table *table,
1235.2.1 by Brian Aker
More identifier work.
69
                                  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.
70
                                  HA_CREATE_INFO *create_info,
1130.3.13 by Monty Taylor
Finished cleaning namespaces in drizzled/statement
71
                                  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.
72
                                  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.
73
1223.4.13 by Brian Aker
Small shift in alter table (break the baby down...).
74
static Table *open_alter_table(Session *session, Table *table, char *db, char *table_name);
75
1100.3.63 by Padraig O'Sullivan
Extracted the ALTER TABLE command into its own class and implementation
76
bool statement::AlterTable::execute()
77
{
78
  TableList *first_table= (TableList *) session->lex->select_lex.table_list.first;
79
  TableList *all_tables= session->lex->query_tables;
80
  assert(first_table == all_tables && first_table != 0);
81
  Select_Lex *select_lex= &session->lex->select_lex;
82
  bool need_start_waiting= false;
83
1222.1.3 by Brian Aker
Remove used flag for engine.
84
  if (is_engine_set)
1160.1.5 by Brian Aker
Final parser SE removal.
85
  {
86
    create_info.db_type= 
1183.1.29 by Brian Aker
Clean up interface so that Truncate sets the propper engine when
87
      plugin::StorageEngine::findByName(*session, create_table_proto.engine().name());
1160.1.5 by Brian Aker
Final parser SE removal.
88
89
    if (create_info.db_type == NULL)
90
    {
91
      my_error(ER_UNKNOWN_STORAGE_ENGINE, MYF(0), 
92
               create_table_proto.name().c_str());
93
94
      return true;
95
    }
96
  }
97
1100.3.63 by Padraig O'Sullivan
Extracted the ALTER TABLE command into its own class and implementation
98
  /* Must be set in the parser */
99
  assert(select_lex->db);
100
101
  /* ALTER TABLE ends previous transaction */
102
  if (! session->endActiveTransaction())
103
  {
104
    return true;
105
  }
106
107
  if (! (need_start_waiting= ! wait_if_global_read_lock(session, 0, 1)))
108
  {
109
    return true;
110
  }
111
1130.3.13 by Monty Taylor
Finished cleaning namespaces in drizzled/statement
112
  bool res= alter_table(session, 
113
                        select_lex->db, 
114
                        session->lex->name.str,
115
                        &create_info,
1130.3.14 by Monty Taylor
Merged up with latest plugin-slot-reorg.
116
                        &create_table_proto,
1130.3.13 by Monty Taylor
Finished cleaning namespaces in drizzled/statement
117
                        first_table,
118
                        &alter_info,
119
                        select_lex->order_list.elements,
120
                        (order_st *) select_lex->order_list.first,
121
                        session->lex->ignore);
1100.3.63 by Padraig O'Sullivan
Extracted the ALTER TABLE command into its own class and implementation
122
  /*
123
     Release the protection against the global read lock and wake
124
     everyone, who might want to set a global read lock.
125
   */
126
  start_waiting_global_read_lock(session);
127
  return res;
128
}
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.
129
1130.3.12 by Monty Taylor
using namespace drizzled; to namespace drizzled { in statement/
130
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.
131
/**
132
  Prepare column and key definitions for CREATE TABLE in ALTER Table.
133
134
  This function transforms parse output of ALTER Table - lists of
135
  columns and keys to add, drop or modify into, essentially,
136
  CREATE TABLE definition - a list of columns and keys of the new
137
  table. While doing so, it also performs some (bug not all)
138
  semantic checks.
139
140
  This function is invoked when we know that we're going to
141
  perform ALTER Table via a temporary table -- i.e. fast ALTER Table
142
  is not possible, perhaps because the ALTER statement contains
143
  instructions that require change in table data, not only in
144
  table definition or indexes.
145
146
  @param[in,out]  session         thread handle. Used as a memory pool
147
                              and source of environment information.
148
  @param[in]      table       the source table, open and locked
149
                              Used as an interface to the storage engine
150
                              to acquire additional information about
151
                              the original table.
152
  @param[in,out]  create_info A blob with CREATE/ALTER Table
153
                              parameters
154
  @param[in,out]  alter_info  Another blob with ALTER/CREATE parameters.
155
                              Originally create_info was used only in
156
                              CREATE TABLE and alter_info only in ALTER Table.
157
                              But since ALTER might end-up doing CREATE,
158
                              this distinction is gone and we just carry
159
                              around two structures.
160
161
  @return
162
    Fills various create_info members based on information retrieved
163
    from the storage engine.
164
    Sets create_info->varchar if the table has a VARCHAR column.
165
    Prepares alter_info->create_list and alter_info->key_list with
166
    columns and keys of the new table.
167
  @retval true   error, out of memory or a semantical error in ALTER
168
                 Table instructions
169
  @retval false  success
170
*/
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.
171
static bool mysql_prepare_alter_table(Session *session,
172
                                      Table *table,
173
                                      HA_CREATE_INFO *create_info,
1130.3.13 by Monty Taylor
Finished cleaning namespaces in drizzled/statement
174
                                      message::Table *table_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.
175
                                      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.
176
{
177
  /* New column definitions are added here */
178
  List<CreateField> new_create_list;
179
  /* New key definitions are added here */
180
  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.
181
  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.
182
  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.
183
  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.
184
  List_iterator<Key> key_it(alter_info->key_list);
185
  List_iterator<CreateField> find_it(new_create_list);
186
  List_iterator<CreateField> field_it(new_create_list);
187
  List<Key_part_spec> key_parts;
188
  uint32_t used_fields= create_info->used_fields;
1126.3.5 by Jay Pipes
Clean up the style and spacing in mysql_prepare_alter_table() before I lose my friggin mind.
189
  KEY *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.
190
  bool rc= true;
191
192
  /* Let new create options override the old ones */
1130.3.13 by Monty Taylor
Finished cleaning namespaces in drizzled/statement
193
  message::Table::TableOptions *table_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.
194
  table_options= table_proto->mutable_options();
195
1126.3.5 by Jay Pipes
Clean up the style and spacing in mysql_prepare_alter_table() before I lose my friggin mind.
196
  if (! (used_fields & HA_CREATE_USED_BLOCK_SIZE))
1126.2.5 by Brian Aker
Merge Jay.
197
    table_options->set_block_size(table->s->block_size);
1126.3.5 by Jay Pipes
Clean up the style and spacing in mysql_prepare_alter_table() before I lose my friggin mind.
198
  if (! (used_fields & HA_CREATE_USED_DEFAULT_CHARSET))
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.
199
    create_info->default_table_charset= table->s->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.
200
  if (! (used_fields & HA_CREATE_USED_AUTO) &&
201
      table->found_next_number_field)
202
  {
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.
203
    /* Table has an autoincrement, copy value to new table */
1208.3.2 by brian
Update for Cursor renaming.
204
    table->cursor->info(HA_STATUS_AUTO);
205
    create_info->auto_increment_value= table->cursor->stats.auto_increment_value;
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.
206
  }
1188.2.1 by Stewart Smith
move key_block_size out of table_share and into the table proto. init it in parser
207
  if (! (used_fields & HA_CREATE_USED_KEY_BLOCK_SIZE)
208
      && table->s->hasKeyBlockSize())
209
    table_options->set_key_block_size(table->s->getKeyBlockSize());
210
211
  if ((used_fields & HA_CREATE_USED_KEY_BLOCK_SIZE)
212
      && table_options->key_block_size() == 0)
213
    table_options->clear_key_block_size();
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.
214
1126.3.5 by Jay Pipes
Clean up the style and spacing in mysql_prepare_alter_table() before I lose my friggin mind.
215
  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.
216
  CreateField *def;
217
1126.3.5 by Jay Pipes
Clean up the style and spacing in mysql_prepare_alter_table() before I lose my friggin mind.
218
  /* First collect all fields from table which isn't in drop_list */
219
  Field **f_ptr;
220
  Field *field;
221
  for (f_ptr= table->field; (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.
222
  {
223
    /* 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.
224
    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.
225
    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.
226
    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.
227
    {
1126.3.4 by Jay Pipes
Changes Alter_drop and Alter_column to AlterDrop and AlterColumn. Next up: bye bye List<> in AlterInfo.
228
      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.
229
          ! 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.
230
      {
1126.3.5 by Jay Pipes
Clean up the style and spacing in mysql_prepare_alter_table() before I lose my friggin mind.
231
        /* Reset auto_increment value if it was dropped */
232
        if (MTYP_TYPENR(field->unireg_check) == Field::NEXT_NUMBER &&
233
            ! (used_fields & HA_CREATE_USED_AUTO))
234
        {
235
          create_info->auto_increment_value= 0;
236
          create_info->used_fields|= HA_CREATE_USED_AUTO;
237
        }
238
        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.
239
      }
240
    }
241
    if (drop)
242
    {
243
      drop_it.remove();
244
      continue;
245
    }
246
    
247
    /* Mark that we will read the field */
248
    field->setReadSet();
249
250
    /* Check if field is changed */
251
    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.
252
    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.
253
    {
254
      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.
255
          ! my_strcasecmp(system_charset_info, field->field_name, def->change))
256
	      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.
257
    }
258
    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.
259
    {
260
      /* Field is changed */
261
      def->field= field;
262
      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.
263
      {
1126.3.5 by Jay Pipes
Clean up the style and spacing in mysql_prepare_alter_table() before I lose my friggin mind.
264
        new_create_list.push_back(def);
265
        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.
266
      }
267
    }
268
    else
269
    {
270
      /*
271
        This field was not dropped and not changed, add it to the list
272
        for the new table.
273
      */
274
      def= new CreateField(field, field);
275
      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.
276
      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.
277
      AlterColumn *alter;
1126.3.5 by Jay Pipes
Clean up the style and spacing in mysql_prepare_alter_table() before I lose my friggin mind.
278
      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.
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
        if (! my_strcasecmp(system_charset_info,field->field_name, alter->name))
281
          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.
282
      }
283
      if (alter)
284
      {
1126.3.5 by Jay Pipes
Clean up the style and spacing in mysql_prepare_alter_table() before I lose my friggin mind.
285
        if (def->sql_type == DRIZZLE_TYPE_BLOB)
286
        {
287
          my_error(ER_BLOB_CANT_HAVE_DEFAULT, MYF(0), def->change);
288
                goto err;
289
        }
290
        if ((def->def= alter->def))
291
        {
292
          /* 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.
293
          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.
294
        }
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.
295
        else
296
          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.
297
        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.
298
      }
299
    }
300
  }
301
  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.
302
  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.
303
  {
304
    if (def->change && ! def->field)
305
    {
306
      my_error(ER_BAD_FIELD_ERROR, MYF(0), def->change, table->s->table_name.str);
307
      goto err;
308
    }
309
    /*
310
      Check that the DATE/DATETIME not null field we are going to add is
311
      either has a default value or the '0000-00-00' is allowed by the
312
      set sql mode.
313
      If the '0000-00-00' value isn't allowed then raise the error_if_not_empty
314
      flag to allow ALTER Table only if the table to be altered is empty.
315
    */
316
    if ((def->sql_type == DRIZZLE_TYPE_DATE ||
317
         def->sql_type == DRIZZLE_TYPE_DATETIME) &&
1126.3.5 by Jay Pipes
Clean up the style and spacing in mysql_prepare_alter_table() before I lose my friggin mind.
318
        ! alter_info->datetime_field &&
319
        ! (~def->flags & (NO_DEFAULT_VALUE_FLAG | NOT_NULL_FLAG)) &&
320
        session->variables.sql_mode & MODE_NO_ZERO_DATE)
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.
321
    {
322
      alter_info->datetime_field= def;
323
      alter_info->error_if_not_empty= true;
324
    }
1126.3.5 by Jay Pipes
Clean up the style and spacing in mysql_prepare_alter_table() before I lose my friggin mind.
325
    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.
326
      new_create_list.push_back(def);
327
    else if (def->after == first_keyword)
328
      new_create_list.push_front(def);
329
    else
330
    {
331
      CreateField *find;
332
      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.
333
      while ((find= find_it++)) /* Add new columns */
334
      {
335
        if (! my_strcasecmp(system_charset_info,def->after, find->field_name))
336
          break;
337
      }
338
      if (! find)
339
      {
340
        my_error(ER_BAD_FIELD_ERROR, MYF(0), def->after, table->s->table_name.str);
341
        goto err;
342
      }
343
      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.
344
      /*
345
        XXX: hack for Bug#28427.
346
        If column order has changed, force OFFLINE ALTER Table
347
        without querying engine capabilities.  If we ever have an
348
        engine that supports online ALTER Table CHANGE COLUMN
349
        <name> AFTER <name1> (Falcon?), this fix will effectively
350
        disable the capability.
351
        TODO: detect the situation in compare_tables, behave based
352
        on engine capabilities.
353
      */
354
      if (alter_info->build_method == HA_BUILD_ONLINE)
355
      {
356
        my_error(ER_NOT_SUPPORTED_YET, MYF(0), session->query);
357
        goto err;
358
      }
359
      alter_info->build_method= HA_BUILD_OFFLINE;
360
    }
361
  }
362
  if (alter_info->alter_list.elements)
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
    my_error(ER_BAD_FIELD_ERROR,
365
             MYF(0),
366
             alter_info->alter_list.head()->name,
367
             table->s->table_name.str);
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.
368
    goto err;
369
  }
1126.3.5 by Jay Pipes
Clean up the style and spacing in mysql_prepare_alter_table() before I lose my friggin mind.
370
  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.
371
  {
1126.3.5 by Jay Pipes
Clean up the style and spacing in mysql_prepare_alter_table() before I lose my friggin mind.
372
    my_message(ER_CANT_REMOVE_ALL_FIELDS,
373
               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.
374
               MYF(0));
375
    goto err;
376
  }
377
378
  /*
379
    Collect all keys which isn't in drop list. Add only those
380
    for which some fields exists.
381
  */
1126.3.5 by Jay Pipes
Clean up the style and spacing in mysql_prepare_alter_table() before I lose my friggin mind.
382
  for (uint32_t i= 0; i < table->s->keys; 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.
383
  {
384
    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.
385
    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.
386
    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.
387
    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.
388
    {
1126.3.4 by Jay Pipes
Changes Alter_drop and Alter_column to AlterDrop and AlterColumn. Next up: bye bye List<> in AlterInfo.
389
      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.
390
          ! my_strcasecmp(system_charset_info, key_name, drop->name))
391
        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.
392
    }
393
    if (drop)
394
    {
395
      drop_it.remove();
396
      continue;
397
    }
398
399
    KEY_PART_INFO *key_part= key_info->key_part;
400
    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.
401
    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.
402
    {
1126.3.5 by Jay Pipes
Clean up the style and spacing in mysql_prepare_alter_table() before I lose my friggin mind.
403
      if (! key_part->field)
404
	      continue;	/* Wrong field (from UNIREG) */
405
406
      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.
407
      CreateField *cfield;
408
      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.
409
      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.
410
      {
1126.3.5 by Jay Pipes
Clean up the style and spacing in mysql_prepare_alter_table() before I lose my friggin mind.
411
        if (cfield->change)
412
        {
413
          if (! my_strcasecmp(system_charset_info, key_part_name, cfield->change))
414
            break;
415
        }
416
        else if (! my_strcasecmp(system_charset_info, key_part_name, cfield->field_name))
417
          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.
418
      }
1126.3.5 by Jay Pipes
Clean up the style and spacing in mysql_prepare_alter_table() before I lose my friggin mind.
419
      if (! cfield)
420
	      continue; /* Field is removed */
421
      
422
      uint32_t key_part_length= key_part->length;
423
      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.
424
      {
425
        /*
426
          If the field can't have only a part used in a key according to its
427
          new type, or should not be used partially according to its
428
          previous type, or the field length is less than the key part
429
          length, unset the key part length.
430
431
          We also unset the key part length if it is the same as the
432
          old field's length, so the whole new field will be used.
433
434
          BLOBs may have cfield->length == 0, which is why we test it before
435
          checking whether cfield->length < key_part_length (in chars).
436
         */
1126.3.5 by Jay Pipes
Clean up the style and spacing in mysql_prepare_alter_table() before I lose my friggin mind.
437
        if (! Field::type_can_have_key_part(cfield->field->type()) ||
438
            ! Field::type_can_have_key_part(cfield->sql_type) ||
1119.9.17 by Stewart Smith
merge with trunk
439
            (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.
440
            (cfield->length &&
441
             (cfield->length < key_part_length / key_part->field->charset()->mbmaxlen)))
442
          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.
443
      }
1126.3.5 by Jay Pipes
Clean up the style and spacing in mysql_prepare_alter_table() before I lose my friggin mind.
444
      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.
445
      key_parts.push_back(new Key_part_spec(cfield->field_name,
446
                                            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.
447
                                            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.
448
    }
449
    if (key_parts.elements)
450
    {
451
      KEY_CREATE_INFO key_create_info;
452
      Key *key;
453
      enum Key::Keytype key_type;
454
      memset(&key_create_info, 0, sizeof(key_create_info));
455
456
      key_create_info.algorithm= key_info->algorithm;
457
      if (key_info->flags & HA_USES_BLOCK_SIZE)
458
        key_create_info.block_size= key_info->block_size;
459
      if (key_info->flags & HA_USES_COMMENT)
460
        key_create_info.comment= key_info->comment;
461
462
      if (key_info->flags & HA_NOSAME)
463
      {
464
        if (is_primary_key_name(key_name))
465
          key_type= Key::PRIMARY;
466
        else
467
          key_type= Key::UNIQUE;
468
      }
469
      else
470
        key_type= Key::MULTIPLE;
471
1126.3.5 by Jay Pipes
Clean up the style and spacing in mysql_prepare_alter_table() before I lose my friggin mind.
472
      key= new Key(key_type,
473
                   key_name,
474
                   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.
475
                   &key_create_info,
476
                   test(key_info->flags & HA_GENERATED_KEY),
477
                   key_parts);
478
      new_key_list.push_back(key);
479
    }
480
  }
481
  {
482
    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.
483
    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.
484
    {
485
      if (key->type == Key::FOREIGN_KEY &&
486
          ((Foreign_key *)key)->validate(new_create_list))
487
        goto err;
488
      if (key->type != Key::FOREIGN_KEY)
489
        new_key_list.push_back(key);
490
      if (key->name.str && is_primary_key_name(key->name.str))
491
      {
1126.3.5 by Jay Pipes
Clean up the style and spacing in mysql_prepare_alter_table() before I lose my friggin mind.
492
        my_error(ER_WRONG_NAME_FOR_INDEX,
493
                 MYF(0),
494
                 key->name.str);
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.
495
        goto err;
496
      }
497
    }
498
  }
499
500
  if (alter_info->drop_list.elements)
501
  {
1126.3.5 by Jay Pipes
Clean up the style and spacing in mysql_prepare_alter_table() before I lose my friggin mind.
502
    my_error(ER_CANT_DROP_FIELD_OR_KEY,
503
             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.
504
             alter_info->drop_list.head()->name);
505
    goto err;
506
  }
507
  if (alter_info->alter_list.elements)
508
  {
1126.3.5 by Jay Pipes
Clean up the style and spacing in mysql_prepare_alter_table() before I lose my friggin mind.
509
    my_error(ER_CANT_DROP_FIELD_OR_KEY,
510
             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.
511
             alter_info->alter_list.head()->name);
512
    goto err;
513
  }
514
515
  if (! table_proto->options().has_comment()
516
      && table->s->hasComment())
517
    table_options->set_comment(table->s->getComment());
518
519
  if (table->s->tmp_table)
1222.2.1 by Brian Aker
Takes the majority usage of parser based HA_CREATE_INFO usage around
520
  {
521
    table_proto->set_type(message::Table::TEMPORARY);
522
  }
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.
523
524
  rc= false;
525
  alter_info->create_list.swap(new_create_list);
526
  alter_info->key_list.swap(new_key_list);
527
err:
1126.3.5 by Jay Pipes
Clean up the style and spacing in mysql_prepare_alter_table() before I lose my friggin mind.
528
  return rc;
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.
529
}
530
531
/* 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.
532
static int mysql_discard_or_import_tablespace(Session *session,
533
                                              TableList *table_list,
534
                                              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.
535
{
536
  Table *table;
537
  bool discard;
538
  int error;
539
540
  /*
541
    Note that DISCARD/IMPORT TABLESPACE always is the only operation in an
542
    ALTER Table
543
  */
544
545
  session->set_proc_info("discard_or_import_tablespace");
546
547
  discard= test(tablespace_op == DISCARD_TABLESPACE);
548
549
 /*
550
   We set this flag so that ha_innobase::open and ::external_lock() do
551
   not complain when we lock the table
552
 */
553
  session->tablespace_op= true;
554
  if (!(table= session->openTableLock(table_list, TL_WRITE)))
555
  {
556
    session->tablespace_op= false;
557
    return -1;
558
  }
559
1208.3.2 by brian
Update for Cursor renaming.
560
  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.
561
562
  session->set_proc_info("end");
563
564
  if (error)
565
    goto err;
566
567
  /* The ALTER Table is always in its own transaction */
568
  error = ha_autocommit_or_rollback(session, 0);
569
  if (! session->endActiveTransaction())
570
    error=1;
571
  if (error)
572
    goto err;
1172 by Brian Aker
Update to delete table to centralize the replication logic.
573
  write_bin_log(session, session->query, session->query_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.
574
575
err:
576
  ha_autocommit_or_rollback(session, error);
577
  session->tablespace_op=false;
578
579
  if (error == 0)
580
  {
581
    session->my_ok();
582
    return 0;
583
  }
584
1216.1.1 by Brian Aker
Move print_error up to Engine.
585
  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.
586
587
  return -1;
588
}
589
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.
590
/**
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.
591
  Manages enabling/disabling of indexes for ALTER Table
592
593
  SYNOPSIS
594
    alter_table_manage_keys()
595
      table                  Target table
596
      indexes_were_disabled  Whether the indexes of the from table
597
                             were disabled
598
      keys_onoff             ENABLE | DISABLE | LEAVE_AS_IS
599
600
  RETURN VALUES
601
    false  OK
602
    true   Error
603
*/
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.
604
static bool alter_table_manage_keys(Table *table, int 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.
605
                             enum enum_enable_or_disable keys_onoff)
606
{
607
  int error= 0;
608
  switch (keys_onoff) {
609
  case ENABLE:
1208.3.2 by brian
Update for Cursor renaming.
610
    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.
611
    break;
612
  case LEAVE_AS_IS:
613
    if (!indexes_were_disabled)
614
      break;
615
    /* fall-through: disabled indexes */
616
  case DISABLE:
1208.3.2 by brian
Update for Cursor renaming.
617
    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.
618
  }
619
620
  if (error == HA_ERR_WRONG_COMMAND)
621
  {
622
    push_warning_printf(current_session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
623
                        ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA),
624
                        table->s->table_name.str);
625
    error= 0;
626
  } else if (error)
1216.1.1 by Brian Aker
Move print_error up to Engine.
627
    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.
628
629
  return(error);
630
}
631
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.
632
/**
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
  Alter table
634
635
  SYNOPSIS
1130.3.13 by Monty Taylor
Finished cleaning namespaces in drizzled/statement
636
    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.
637
      session              Thread handle
638
      new_db           If there is a RENAME clause
639
      new_name         If there is a RENAME clause
640
      create_info      Information from the parsing phase about new
641
                       table properties.
642
      table_list       The table to change.
643
      alter_info       Lists of fields, keys to be changed, added
644
                       or dropped.
645
      order_num        How many order_st BY fields has been specified.
646
      order            List of fields to order_st BY.
647
      ignore           Whether we have ALTER IGNORE Table
648
649
  DESCRIPTION
650
    This is a veery long function and is everything but the kitchen sink :)
651
    It is used to alter a table and not only by ALTER Table but also
652
    CREATE|DROP INDEX are mapped on this function.
653
654
    When the ALTER Table statement just does a RENAME or ENABLE|DISABLE KEYS,
655
    or both, then this function short cuts its operation by renaming
656
    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
657
    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.
658
    RENAME + change of a field, or an index, the short cut is not used.
659
    See how `create_list` is used to generate the new FRM regarding the
660
    structure of the fields. The same is done for the indices of the table.
661
662
    Important is the fact, that this function tries to do as little work as
663
    possible, by finding out whether a intermediate table is needed to copy
664
    data into and when finishing the altering to use it as the original table.
665
    For this reason the function compare_tables() is called, which decides
666
    based on all kind of data how similar are the new and the original
667
    tables.
668
669
  RETURN VALUES
670
    false  OK
671
    true   Error
672
*/
1130.3.13 by Monty Taylor
Finished cleaning namespaces in drizzled/statement
673
bool alter_table(Session *session,
674
                 char *new_db,
675
                 char *new_name,
676
                 HA_CREATE_INFO *create_info,
677
                 message::Table *create_proto,
678
                 TableList *table_list,
679
                 AlterInfo *alter_info,
680
                 uint32_t order_num,
681
                 order_st *order,
682
                 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.
683
{
684
  Table *table;
685
  Table *new_table= NULL;
686
  Table *name_lock= NULL;
687
  string new_name_str;
688
  int error= 0;
689
  char tmp_name[80];
690
  char old_name[32];
691
  char new_name_buff[FN_REFLEN];
692
  char new_alias_buff[FN_REFLEN];
693
  char *table_name;
694
  char *db;
695
  const char *new_alias;
696
  ha_rows copied= 0;
697
  ha_rows deleted= 0;
1130.3.13 by Monty Taylor
Finished cleaning namespaces in drizzled/statement
698
  plugin::StorageEngine *old_db_type;
699
  plugin::StorageEngine *new_db_type;
700
  plugin::StorageEngine *save_old_db_type;
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.
701
  bitset<32> tmp;
702
703
  new_name_buff[0]= '\0';
704
1225.1.24 by Padraig O'Sullivan
Resolved issues with drop and alter table statements on tables in the I_S engine.
705
  /**
706
   * @todo this is a result of retaining the behavior that was here before. This should be removed
707
   * and the correct error handling should be done in doDropTable for the I_S engine.
708
   */
709
  plugin::InfoSchemaTable *sch_table= plugin::InfoSchemaTable::getTable(table_list->table_name);
710
  if (sch_table)
711
  {
712
    my_error(ER_DBACCESS_DENIED_ERROR, MYF(0), "", "", INFORMATION_SCHEMA_NAME.c_str());
713
    return true;
714
  }
715
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.
716
  session->set_proc_info("init");
717
718
  /*
719
    Assign variables table_name, new_name, db, new_db, path
720
    to simplify further comparisons: we want to see if it's a RENAME
721
    later just by comparing the pointers, avoiding the need for strcmp.
722
  */
723
  table_name= table_list->table_name;
724
  db= table_list->db;
725
  if (! new_db || ! my_strcasecmp(table_alias_charset, new_db, db))
726
    new_db= db;
727
728
  if (alter_info->tablespace_op != NO_TABLESPACE_OP)
729
  {
730
    /* DISCARD/IMPORT TABLESPACE is always alone in an ALTER Table */
731
    return mysql_discard_or_import_tablespace(session, table_list, alter_info->tablespace_op);
732
  }
733
734
  ostringstream oss;
735
  oss << drizzle_data_home << "/" << db << "/" << table_name;
736
737
  (void) unpack_filename(new_name_buff, oss.str().c_str());
738
739
  /*
740
    If this is just a rename of a view, short cut to the
741
    following scenario: 1) lock LOCK_open 2) do a RENAME
742
    2) unlock LOCK_open.
743
    This is a copy-paste added to make sure
744
    ALTER (sic:) Table .. RENAME works for views. ALTER VIEW is handled
745
    as an independent branch in mysql_execute_command. The need
746
    for a copy-paste arose because the main code flow of ALTER Table
747
    ... RENAME tries to use openTableLock, which does not work for views
748
    (openTableLock was never modified to merge table lists of child tables
749
    into the main table list, like open_tables does).
750
    This code is wrong and will be removed, please do not copy.
751
  */
752
753
  if (!(table= session->openTableLock(table_list, TL_WRITE_ALLOW_READ)))
754
    return true;
755
  
756
  table->use_all_columns();
757
758
  /* Check that we are not trying to rename to an existing table */
759
  if (new_name)
760
  {
761
    strcpy(new_name_buff, new_name);
762
    strcpy(new_alias_buff, new_name);
763
    new_alias= new_alias_buff;
764
765
    my_casedn_str(files_charset_info, new_name_buff);
766
    new_alias= new_name; // Create lower case table name
767
    my_casedn_str(files_charset_info, new_name);
768
769
    if (new_db == db &&
770
        ! my_strcasecmp(table_alias_charset, new_name_buff, table_name))
771
    {
772
      /*
773
        Source and destination table names are equal: make later check
774
        easier.
775
      */
776
      new_alias= new_name= table_name;
777
    }
778
    else
779
    {
780
      if (table->s->tmp_table != NO_TMP_TABLE)
781
      {
782
        if (session->find_temporary_table(new_db, new_name_buff))
783
        {
784
          my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_name_buff);
785
          return true;
786
        }
787
      }
788
      else
789
      {
790
        if (session->lock_table_name_if_not_cached(new_db, new_name, &name_lock))
791
          return true;
792
793
        if (! name_lock)
794
        {
795
          my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_alias);
796
          return true;
797
        }
798
799
        build_table_filename(new_name_buff, sizeof(new_name_buff), new_db, new_name_buff, false);
800
1183.1.29 by Brian Aker
Clean up interface so that Truncate sets the propper engine when
801
        if (plugin::StorageEngine::getTableDefinition(*session, new_name_buff, new_db, new_name_buff, false) == EEXIST)
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.
802
        {
803
          /* Table will be closed by Session::executeCommand() */
804
          my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_alias);
805
          goto err;
806
        }
807
      }
808
    }
809
  }
810
  else
811
  {
812
    new_alias= table_name;
813
    new_name= table_name;
814
  }
815
816
  old_db_type= table->s->db_type();
817
  if (! create_info->db_type)
818
  {
819
    create_info->db_type= old_db_type;
820
  }
821
822
  if (table->s->tmp_table != NO_TMP_TABLE)
1222.2.1 by Brian Aker
Takes the majority usage of parser based HA_CREATE_INFO usage around
823
  {
824
    create_proto->set_type(message::Table::TEMPORARY);
825
  }
826
  else
827
  {
828
    create_proto->set_type(message::Table::STANDARD);
829
  }
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.
830
831
  new_db_type= create_info->db_type;
832
833
  if (new_db_type != old_db_type &&
1208.3.2 by brian
Update for Cursor renaming.
834
      !table->cursor->can_switch_engines())
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.
835
  {
836
    assert(0);
837
    my_error(ER_ROW_IS_REFERENCED, MYF(0));
838
    goto err;
839
  }
840
841
  if (create_info->row_type == ROW_TYPE_NOT_USED)
1222.1.6 by Brian Aker
Fix engines to not rely on HA_CREATE_INFO.
842
  {
843
    message::Table::TableOptions *table_options;
844
    table_options= create_proto->mutable_options();
845
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.
846
    create_info->row_type= table->s->row_type;
1222.1.6 by Brian Aker
Fix engines to not rely on HA_CREATE_INFO.
847
    table_options->set_row_type((drizzled::message::Table_TableOptions_RowType)table->s->row_type);
848
  }
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.
849
850
  if (old_db_type->check_flag(HTON_BIT_ALTER_NOT_SUPPORTED) ||
851
      new_db_type->check_flag(HTON_BIT_ALTER_NOT_SUPPORTED))
852
  {
853
    my_error(ER_ILLEGAL_HA, MYF(0), table_name);
854
    goto err;
855
  }
856
857
  session->set_proc_info("setup");
858
  
859
  /*
860
   * test if no other bits except ALTER_RENAME and ALTER_KEYS_ONOFF are set
861
   */
862
  tmp.set();
863
  tmp.reset(ALTER_RENAME);
864
  tmp.reset(ALTER_KEYS_ONOFF);
865
  tmp&= alter_info->flags;
866
  if (! (tmp.any()) &&
867
      ! table->s->tmp_table) // no need to touch frm
868
  {
869
    switch (alter_info->keys_onoff)
870
    {
871
    case LEAVE_AS_IS:
872
      break;
873
    case ENABLE:
874
      /*
875
        wait_while_table_is_used() ensures that table being altered is
876
        opened only by this thread and that Table::TableShare::version
877
        of Table object corresponding to this table is 0.
878
        The latter guarantees that no DML statement will open this table
879
        until ALTER Table finishes (i.e. until close_thread_tables())
880
        while the fact that the table is still open gives us protection
881
        from concurrent DDL statements.
882
      */
883
      pthread_mutex_lock(&LOCK_open); /* DDL wait for/blocker */
884
      wait_while_table_is_used(session, table, HA_EXTRA_FORCE_REOPEN);
885
      pthread_mutex_unlock(&LOCK_open);
1208.3.2 by brian
Update for Cursor renaming.
886
      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.
887
      /* COND_refresh will be signaled in close_thread_tables() */
888
      break;
889
    case DISABLE:
890
      pthread_mutex_lock(&LOCK_open); /* DDL wait for/blocker */
891
      wait_while_table_is_used(session, table, HA_EXTRA_FORCE_REOPEN);
892
      pthread_mutex_unlock(&LOCK_open);
1208.3.2 by brian
Update for Cursor renaming.
893
      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.
894
      /* COND_refresh will be signaled in close_thread_tables() */
895
      break;
896
    default:
897
      assert(false);
898
      error= 0;
899
      break;
900
    }
901
902
    if (error == HA_ERR_WRONG_COMMAND)
903
    {
904
      error= 0;
905
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
906
			  ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA),
907
			  table->alias);
908
    }
909
910
    pthread_mutex_lock(&LOCK_open); /* Lock to remove all instances of table from table cache before ALTER */
911
    /*
912
      Unlike to the above case close_cached_table() below will remove ALL
913
      instances of Table from table cache (it will also remove table lock
914
      held by this thread). So to make actual table renaming and writing
915
      to binlog atomic we have to put them into the same critical section
916
      protected by LOCK_open mutex. This also removes gap for races between
917
      access() and mysql_rename_table() calls.
918
    */
919
920
    if (error == 0 && 
921
        (new_name != table_name || new_db != db))
922
    {
923
      session->set_proc_info("rename");
924
      /*
925
        Then do a 'simple' rename of the table. First we need to close all
926
        instances of 'source' table.
927
      */
928
      session->close_cached_table(table);
929
      /*
930
        Then, we want check once again that target table does not exist.
931
        Actually the order of these two steps does not matter since
932
        earlier we took name-lock on the target table, so we do them
933
        in this particular order only to be consistent with 5.0, in which
934
        we don't take this name-lock and where this order really matters.
935
        TODO: Investigate if we need this access() check at all.
936
      */
1183.1.29 by Brian Aker
Clean up interface so that Truncate sets the propper engine when
937
      if (plugin::StorageEngine::getTableDefinition(*session, new_name, db, table_name, false) == EEXIST)
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.
938
      {
939
        my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_name);
940
        error= -1;
941
      }
942
      else
943
      {
944
        *fn_ext(new_name)= 0;
945
        if (mysql_rename_table(old_db_type, db, table_name, new_db, new_alias, 0))
946
          error= -1;
947
      }
948
    }
949
950
    if (error == HA_ERR_WRONG_COMMAND)
951
    {
952
      error= 0;
953
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
954
                          ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA),
955
                          table->alias);
956
    }
957
958
    if (error == 0)
959
    {
1172 by Brian Aker
Update to delete table to centralize the replication logic.
960
      write_bin_log(session, session->query, session->query_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.
961
      session->my_ok();
962
    }
963
    else if (error > 0)
964
    {
1216.1.1 by Brian Aker
Move print_error up to Engine.
965
      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.
966
      error= -1;
967
    }
968
969
    if (name_lock)
970
      session->unlink_open_table(name_lock);
971
972
    pthread_mutex_unlock(&LOCK_open);
973
    table_list->table= NULL;
974
    return error;
975
  }
976
977
  /* We have to do full alter table. */
978
  new_db_type= create_info->db_type;
979
980
  if (mysql_prepare_alter_table(session, table, create_info, create_proto,
981
                                alter_info))
982
      goto err;
983
984
  set_table_default_charset(create_info, db);
985
986
  alter_info->build_method= HA_BUILD_OFFLINE;
987
988
  snprintf(tmp_name, sizeof(tmp_name), "%s-%lx_%"PRIx64, TMP_FILE_PREFIX, (unsigned long) current_pid, session->thread_id);
1235.2.1 by Brian Aker
More identifier work.
989
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.
990
  /* Safety fix for innodb */
991
  my_casedn_str(files_charset_info, tmp_name);
992
993
  /* Create a temporary table with the new format */
1235.2.1 by Brian Aker
More identifier work.
994
  {
995
    /**
996
      @note we make an internal temporary table unless the table is a temporary table. In last
997
      case we just use it as is. Neither of these tables require locks in order to  be
998
      filled.
999
    */
1000
    TableIdentifier new_table_temp(new_db,
1001
                                   tmp_name,
1002
                                   create_proto->type() != message::Table::TEMPORARY ? INTERNAL_TMP_TABLE :
1235.1.4 by Brian Aker
Merge of identifier work.
1003
                                   TEMP_TABLE);
1235.2.1 by Brian Aker
More identifier work.
1004
1005
    error= create_temporary_table(session, table, new_table_temp, create_info, create_proto, alter_info);
1006
1007
    if (error != 0)
1008
      goto err;
1009
  }
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.
1010
1011
  /* Open the table so we need to copy the data to it. */
1223.4.13 by Brian Aker
Small shift in alter table (break the baby down...).
1012
  new_table= open_alter_table(session, table, new_db, tmp_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.
1013
1014
  if (new_table == NULL)
1015
    goto err1;
1016
1017
  /* Copy the data if necessary. */
1018
  session->count_cuted_fields= CHECK_FIELD_WARN;	// calc cuted fields
1019
  session->cuted_fields= 0L;
1020
  session->set_proc_info("copy to tmp table");
1021
  copied= deleted= 0;
1022
1023
  assert(new_table);
1024
1025
  /* We don't want update TIMESTAMP fields during ALTER Table. */
1026
  new_table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
1027
  new_table->next_number_field= new_table->found_next_number_field;
1235.2.1 by Brian Aker
More identifier work.
1028
  error= copy_data_between_tables(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.
1029
                                  new_table,
1235.2.1 by Brian Aker
More identifier work.
1030
                                  alter_info->create_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.
1031
                                  ignore,
1235.2.1 by Brian Aker
More identifier work.
1032
                                  order_num,
1033
                                  order,
1034
                                  &copied,
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.
1035
                                  &deleted,
1036
                                  alter_info->keys_onoff,
1037
                                  alter_info->error_if_not_empty);
1038
1039
  /* We must not ignore bad input! */
1040
  session->count_cuted_fields= CHECK_FIELD_ERROR_FOR_NULL;
1041
1042
  if (table->s->tmp_table != NO_TMP_TABLE)
1043
  {
1044
    /* We changed a temporary table */
1045
    if (error)
1046
      goto err1;
1047
1048
    /* Close lock if this is a transactional table */
1049
    if (session->lock)
1050
    {
1051
      mysql_unlock_tables(session, session->lock);
1052
      session->lock= 0;
1053
    }
1054
1055
    /* Remove link to old table and rename the new one */
1216.1.1 by Brian Aker
Move print_error up to Engine.
1056
    session->close_temporary_table(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.
1057
1058
    /* Should pass the 'new_name' as we store table name in the cache */
1059
    if (new_table->rename_temporary_table(new_db, new_name))
1060
      goto err1;
1235.2.1 by Brian Aker
More identifier work.
1061
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.
1062
    goto end_temporary;
1063
  }
1064
1065
  if (new_table)
1066
  {
1067
    /*
1068
      Close the intermediate table that will be the new table.
1069
      Note that MERGE tables do not have their children attached here.
1070
    */
1071
    new_table->intern_close_table();
1072
    free(new_table);
1073
  }
1074
1075
  pthread_mutex_lock(&LOCK_open); /* ALTER TABLE */
1235.2.1 by Brian Aker
More identifier work.
1076
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.
1077
  if (error)
1078
  {
1235.2.1 by Brian Aker
More identifier work.
1079
    TableIdentifier identifier(new_db, tmp_name, INTERNAL_TMP_TABLE);
1080
    quick_rm_table(*session, 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.
1081
    pthread_mutex_unlock(&LOCK_open);
1082
    goto err;
1083
  }
1084
1085
  /*
1086
    Data is copied. Now we:
1087
    1) Wait until all other threads close old version of table.
1088
    2) Close instances of table open by this thread and replace them
1089
       with exclusive name-locks.
1090
    3) Rename the old table to a temp name, rename the new one to the
1091
       old name.
1092
    4) If we are under LOCK TABLES and don't do ALTER Table ... RENAME
1093
       we reopen new version of table.
1094
    5) Write statement to the binary log.
1095
    6) If we are under LOCK TABLES and do ALTER Table ... RENAME we
1096
       remove name-locks from list of open tables and table cache.
1097
    7) If we are not not under LOCK TABLES we rely on close_thread_tables()
1098
       call to remove name-locks from table cache and list of open table.
1099
  */
1100
1101
  session->set_proc_info("rename result table");
1102
1103
  snprintf(old_name, sizeof(old_name), "%s2-%lx-%"PRIx64, TMP_FILE_PREFIX, (unsigned long) current_pid, session->thread_id);
1104
1105
  my_casedn_str(files_charset_info, old_name);
1106
1107
  wait_while_table_is_used(session, table, HA_EXTRA_PREPARE_FOR_RENAME);
1108
  session->close_data_files_and_morph_locks(db, table_name);
1109
1110
  error= 0;
1111
  save_old_db_type= old_db_type;
1112
1113
  /*
1114
    This leads to the storage engine (SE) not being notified for renames in
1115
    mysql_rename_table(), because we just juggle with the FRM and nothing
1116
    more. If we have an intermediate table, then we notify the SE that
1117
    it should become the actual table. Later, we will recycle the old table.
1118
    However, in case of ALTER Table RENAME there might be no intermediate
1119
    table. This is when the old and new tables are compatible, according to
1120
    compare_table(). Then, we need one additional call to
1121
  */
1122
  if (mysql_rename_table(old_db_type, db, table_name, db, old_name, FN_TO_IS_TMP))
1123
  {
1124
    error= 1;
1235.2.1 by Brian Aker
More identifier work.
1125
    TableIdentifier identifier(new_db, tmp_name, INTERNAL_TMP_TABLE);
1126
    quick_rm_table(*session, 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.
1127
  }
1128
  else
1129
  {
1130
    if (mysql_rename_table(new_db_type, new_db, tmp_name, new_db, new_alias, FN_FROM_IS_TMP) != 0)
1131
    {
1132
      /* Try to get everything back. */
1133
      error= 1;
1235.2.1 by Brian Aker
More identifier work.
1134
1135
      TableIdentifier alias_identifier(new_db, new_alias, NO_TMP_TABLE);
1136
      quick_rm_table(*session, alias_identifier);
1137
1138
      TableIdentifier tmp_identifier(new_db, tmp_name, INTERNAL_TMP_TABLE);
1139
      quick_rm_table(*session, tmp_identifier);
1140
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
      mysql_rename_table(old_db_type, db, old_name, db, table_name, FN_FROM_IS_TMP);
1142
    }
1143
  }
1144
1145
  if (error)
1146
  {
1147
    /* This shouldn't happen. But let us play it safe. */
1148
    goto err_with_placeholders;
1149
  }
1150
1235.2.1 by Brian Aker
More identifier work.
1151
  {
1152
    TableIdentifier old_identifier(db, old_name, INTERNAL_TMP_TABLE);
1153
    quick_rm_table(*session, old_identifier);
1154
  }
1155
  
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.
1156
1157
  pthread_mutex_unlock(&LOCK_open);
1158
1159
  session->set_proc_info("end");
1160
1172 by Brian Aker
Update to delete table to centralize the replication logic.
1161
  write_bin_log(session, session->query, session->query_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.
1162
  table_list->table= NULL;
1163
1164
end_temporary:
1165
  /*
1166
   * Field::store() may have called my_error().  If this is 
1167
   * the case, we must not send an ok packet, since 
1168
   * Diagnostics_area::is_set() will fail an assert.
1169
   */
1170
  if (! session->is_error())
1171
  {
1172
    snprintf(tmp_name, sizeof(tmp_name), ER(ER_INSERT_INFO),
1173
            (ulong) (copied + deleted), (ulong) deleted,
1174
            (ulong) session->cuted_fields);
1175
    session->my_ok(copied + deleted, 0, 0L, tmp_name);
1176
    session->some_tables_deleted=0;
1177
    return false;
1178
  }
1179
  else
1180
  {
1181
    /* my_error() was called.  Return true (which means error...) */
1182
    return true;
1183
  }
1184
1185
err1:
1186
  if (new_table)
1187
  {
1188
    /* close_temporary_table() frees the new_table pointer. */
1216.1.1 by Brian Aker
Move print_error up to Engine.
1189
    session->close_temporary_table(new_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.
1190
  }
1191
  else
1235.2.1 by Brian Aker
More identifier work.
1192
  {
1193
    TableIdentifier tmp_identifier(new_db, tmp_name, INTERNAL_TMP_TABLE);
1194
    quick_rm_table(*session, tmp_identifier);
1195
  }
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.
1196
1197
err:
1198
  /*
1199
    No default value was provided for a DATE/DATETIME field, the
1200
    current sql_mode doesn't allow the '0000-00-00' value and
1201
    the table to be altered isn't empty.
1202
    Report error here.
1203
  */
1204
  if (alter_info->error_if_not_empty && session->row_count)
1205
  {
1206
    const char *f_val= 0;
1207
    enum enum_drizzle_timestamp_type t_type= DRIZZLE_TIMESTAMP_DATE;
1208
    switch (alter_info->datetime_field->sql_type)
1209
    {
1210
      case DRIZZLE_TYPE_DATE:
1211
        f_val= "0000-00-00";
1212
        t_type= DRIZZLE_TIMESTAMP_DATE;
1213
        break;
1214
      case DRIZZLE_TYPE_DATETIME:
1215
        f_val= "0000-00-00 00:00:00";
1216
        t_type= DRIZZLE_TIMESTAMP_DATETIME;
1217
        break;
1218
      default:
1219
        /* Shouldn't get here. */
1220
        assert(0);
1221
    }
1222
    bool save_abort_on_warning= session->abort_on_warning;
1223
    session->abort_on_warning= true;
1224
    make_truncated_value_warning(session, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
1225
                                 f_val, strlength(f_val), t_type,
1226
                                 alter_info->datetime_field->field_name);
1227
    session->abort_on_warning= save_abort_on_warning;
1228
  }
1229
  if (name_lock)
1230
  {
1231
    pthread_mutex_lock(&LOCK_open); /* ALTER TABLe */
1232
    session->unlink_open_table(name_lock);
1233
    pthread_mutex_unlock(&LOCK_open);
1234
  }
1235
  return true;
1236
1237
err_with_placeholders:
1238
  /*
1239
    An error happened while we were holding exclusive name-lock on table
1240
    being altered. To be safe under LOCK TABLES we should remove placeholders
1241
    from list of open tables list and table cache.
1242
  */
1243
  session->unlink_open_table(table);
1244
  if (name_lock)
1245
    session->unlink_open_table(name_lock);
1246
  pthread_mutex_unlock(&LOCK_open);
1247
  return true;
1248
}
1130.3.13 by Monty Taylor
Finished cleaning namespaces in drizzled/statement
1249
/* 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.
1250
1251
static int
1216.1.1 by Brian Aker
Move print_error up to Engine.
1252
copy_data_between_tables(Table *from, Table *to,
1253
                         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.
1254
                         bool ignore,
1216.1.1 by Brian Aker
Move print_error up to Engine.
1255
                         uint32_t order_num, order_st *order,
1256
                         ha_rows *copied,
1257
                         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.
1258
                         enum enum_enable_or_disable keys_onoff,
1259
                         bool error_if_not_empty)
1260
{
1261
  int error;
1262
  CopyField *copy,*copy_end;
1263
  ulong found_count,delete_count;
1264
  Session *session= current_session;
1265
  uint32_t length= 0;
1266
  SORT_FIELD *sortorder;
1267
  READ_RECORD info;
1268
  TableList   tables;
1269
  List<Item>   fields;
1270
  List<Item>   all_fields;
1271
  ha_rows examined_rows;
1272
  bool auto_increment_field_copied= 0;
1273
  uint64_t prev_insert_id;
1274
1275
  /*
1276
    Turn off recovery logging since rollback of an alter table is to
1277
    delete the new table so there is no need to log the changes to it.
1278
1279
    This needs to be done before external_lock
1280
  */
1281
  error= ha_enable_transaction(session, false);
1282
  if (error)
1283
    return -1;
1284
1285
  if (!(copy= new CopyField[to->s->fields]))
971.6.13 by Eric Day
Removed a few more purecov messages missed in merge.
1286
    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.
1287
1208.3.2 by brian
Update for Cursor renaming.
1288
  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.
1289
    return -1;
1290
1291
  /* We need external lock before we can disable/enable keys */
1208.3.2 by brian
Update for Cursor renaming.
1292
  alter_table_manage_keys(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.
1293
1294
  /* We can abort alter table for any table type */
1295
  session->abort_on_warning= !ignore;
1296
1208.3.2 by brian
Update for Cursor renaming.
1297
  from->cursor->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
1298
  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.
1299
1300
  List_iterator<CreateField> it(create);
1301
  CreateField *def;
1302
  copy_end=copy;
1303
  for (Field **ptr=to->field ; *ptr ; ptr++)
1304
  {
1305
    def=it++;
1306
    if (def->field)
1307
    {
1308
      if (*ptr == to->next_number_field)
1309
        auto_increment_field_copied= true;
1310
1311
      (copy_end++)->set(*ptr,def->field,0);
1312
    }
1313
1314
  }
1315
1316
  found_count=delete_count=0;
1317
1318
  if (order)
1319
  {
1208.3.2 by brian
Update for Cursor renaming.
1320
    if (to->s->primary_key != MAX_KEY && 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.
1321
    {
1322
      char warn_buff[DRIZZLE_ERRMSG_SIZE];
1323
      snprintf(warn_buff, sizeof(warn_buff),
1324
               _("order_st BY ignored because there is a user-defined clustered "
1325
                 "index in the table '%-.192s'"),
1326
               from->s->table_name.str);
1327
      push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_UNKNOWN_ERROR,
1328
                   warn_buff);
1329
    }
1330
    else
1331
    {
1332
      from->sort.io_cache= new IO_CACHE;
1333
      memset(from->sort.io_cache, 0, sizeof(IO_CACHE));
1334
1335
      memset(&tables, 0, sizeof(tables));
1336
      tables.table= from;
1337
      tables.alias= tables.table_name= from->s->table_name.str;
1338
      tables.db= from->s->db.str;
1339
      error= 1;
1340
1341
      if (session->lex->select_lex.setup_ref_array(session, order_num) ||
1342
          setup_order(session, session->lex->select_lex.ref_pointer_array,
1343
                      &tables, fields, all_fields, order) ||
1344
          !(sortorder= make_unireg_sortorder(order, &length, NULL)) ||
1345
          (from->sort.found_records= filesort(session, from, sortorder, length,
1237.13.3 by Padraig O'Sullivan
Performed numerous style cleanups in range.[cc,h].
1346
                                              (optimizer::SqlSelect *) 0, HA_POS_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.
1347
                                              1, &examined_rows)) ==
1348
          HA_POS_ERROR)
1349
        goto err;
1350
    }
1351
  };
1352
1353
  /* Tell handler that we have values for all columns in the to table */
1354
  to->use_all_columns();
1237.13.3 by Padraig O'Sullivan
Performed numerous style cleanups in range.[cc,h].
1355
  init_read_record(&info, session, from, (optimizer::SqlSelect *) 0, 1,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.
1356
  if (ignore)
1208.3.2 by brian
Update for Cursor renaming.
1357
    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.
1358
  session->row_count= 0;
1359
  to->restoreRecordAsDefault();        // Create empty record
1360
  while (!(error=info.read_record(&info)))
1361
  {
1362
    if (session->killed)
1363
    {
1364
      session->send_kill_message();
1365
      error= 1;
1366
      break;
1367
    }
1368
    session->row_count++;
1369
    /* Return error if source table isn't empty. */
1370
    if (error_if_not_empty)
1371
    {
1372
      error= 1;
1373
      break;
1374
    }
1375
    if (to->next_number_field)
1376
    {
1377
      if (auto_increment_field_copied)
1378
        to->auto_increment_field_not_null= true;
1379
      else
1380
        to->next_number_field->reset();
1381
    }
1382
1383
    for (CopyField *copy_ptr=copy ; copy_ptr != copy_end ; copy_ptr++)
1384
    {
1385
      copy_ptr->do_copy(copy_ptr);
1386
    }
1208.3.2 by brian
Update for Cursor renaming.
1387
    prev_insert_id= to->cursor->next_insert_id;
1388
    error= to->cursor->ha_write_row(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.
1389
    to->auto_increment_field_not_null= false;
1390
    if (error)
1216.1.1 by Brian Aker
Move print_error up to Engine.
1391
    { 
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.
1392
      if (!ignore ||
1208.3.2 by brian
Update for Cursor renaming.
1393
          to->cursor->is_fatal_error(error, HA_CHECK_DUP))
1216.1.1 by Brian Aker
Move print_error up to Engine.
1394
      { 
1395
        to->print_error(error, MYF(0));
1208.3.2 by brian
Update for Cursor renaming.
1396
        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.
1397
      }
1208.3.2 by brian
Update for Cursor renaming.
1398
      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.
1399
      delete_count++;
1400
    }
1401
    else
1402
      found_count++;
1403
  }
1404
  end_read_record(&info);
1405
  from->free_io_cache();
1406
  delete [] copy;				// This is never 0
1407
1208.3.2 by brian
Update for Cursor renaming.
1408
  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.
1409
  {
1216.1.1 by Brian Aker
Move print_error up to Engine.
1410
    to->print_error(my_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.
1411
    error=1;
1412
  }
1208.3.2 by brian
Update for Cursor renaming.
1413
  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.
1414
1415
  if (ha_enable_transaction(session, true))
1416
  {
1417
    error= 1;
1418
    goto err;
1419
  }
1420
1421
  /*
1422
    Ensure that the new table is saved properly to disk so that we
1423
    can do a rename
1424
  */
1425
  if (ha_autocommit_or_rollback(session, 0))
1426
    error=1;
1427
  if (! session->endActiveTransaction())
1428
    error=1;
1429
1430
 err:
1431
  session->abort_on_warning= 0;
1432
  from->free_io_cache();
1433
  *copied= found_count;
1434
  *deleted=delete_count;
1208.3.2 by brian
Update for Cursor renaming.
1435
  to->cursor->ha_release_auto_increment();
1436
  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.
1437
    error=1;
1438
  return(error > 0 ? -1 : 0);
1439
}
1440
1441
static int
1442
create_temporary_table(Session *session,
1443
                       Table *table,
1235.2.1 by Brian Aker
More identifier work.
1444
                       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.
1445
                       HA_CREATE_INFO *create_info,
1130.3.13 by Monty Taylor
Finished cleaning namespaces in drizzled/statement
1446
                       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.
1447
                       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.
1448
{
1449
  int error;
1130.3.13 by Monty Taylor
Finished cleaning namespaces in drizzled/statement
1450
  plugin::StorageEngine *old_db_type, *new_db_type;
1223.4.1 by Brian Aker
Table Identifier patch.
1451
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.
1452
  old_db_type= table->s->db_type();
1453
  new_db_type= create_info->db_type;
1223.4.1 by Brian Aker
Table Identifier patch.
1454
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
  /*
1456
    Create a table with a temporary name.
1457
    We don't log the statement, it will be logged later.
1458
  */
1235.2.1 by Brian Aker
More identifier work.
1459
  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.
1460
1130.3.13 by Monty Taylor
Finished cleaning namespaces in drizzled/statement
1461
  message::Table::StorageEngine *protoengine;
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.
1462
  protoengine= create_proto->mutable_engine();
1463
  protoengine->set_name(new_db_type->getName());
1464
1223.4.1 by Brian Aker
Table Identifier patch.
1465
  error= mysql_create_table(session,
1466
                            identifier,
1222.2.3 by Brian Aker
Remove a few more options, from options in HA_CREATE_INFO.
1467
                            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.
1468
1222.2.1 by Brian Aker
Takes the majority usage of parser based HA_CREATE_INFO usage around
1469
  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.
1470
}
1471
1223.4.13 by Brian Aker
Small shift in alter table (break the baby down...).
1472
static Table *open_alter_table(Session *session, Table *table, char *db, char *table_name)
1473
{
1474
  Table *new_table;
1475
1476
  /* Open the table so we need to copy the data to it. */
1477
  if (table->s->tmp_table)
1478
  {
1479
    TableList tbl;
1480
    tbl.db= db;
1481
    tbl.alias= table_name;
1482
    tbl.table_name= table_name;
1483
1484
    /* Table is in session->temporary_tables */
1485
    new_table= session->openTable(&tbl, (bool*) 0, DRIZZLE_LOCK_IGNORE_FLUSH);
1486
  }
1487
  else
1488
  {
1489
    TableIdentifier new_identifier(db, table_name, INTERNAL_TMP_TABLE);
1490
1491
    /* Open our intermediate table */
1492
    new_table= session->open_temporary_table(new_identifier, false);
1493
  }
1494
1495
  return new_table;
1496
}
1497
1130.3.13 by Monty Taylor
Finished cleaning namespaces in drizzled/statement
1498
} /* namespace drizzled */