~drizzle-trunk/drizzle/development

1 by brian
clean slate
1
/* Copyright (C) 2000-2004 MySQL AB
2
3
   This program is free software; you can redistribute it and/or modify
4
   it under the terms of the GNU General Public License as published by
5
   the Free Software Foundation; version 2 of the License.
6
7
   This program is distributed in the hope that it will be useful,
8
   but WITHOUT ANY WARRANTY; without even the implied warranty of
9
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10
   GNU General Public License for more details.
11
12
   You should have received a copy of the GNU General Public License
13
   along with this program; if not, write to the Free Software
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
15
16
/* drop and alter of tables */
17
1241.9.36 by Monty Taylor
ZOMG. I deleted drizzled/server_includes.h.
18
#include "config.h"
992.1.25 by Monty Taylor
Moved myisam to new plugin system.
19
#include <plugin/myisam/myisam.h>
575.4.7 by Monty Taylor
More header cleanup.
20
#include <drizzled/show.h>
549 by Monty Taylor
Took gettext.h out of header files.
21
#include <drizzled/error.h>
538 by Monty Taylor
Moved gettext.h into drizzled in anticipation of the new client lib.
22
#include <drizzled/gettext.h>
520.6.7 by Monty Taylor
Moved a bunch of crap out of common_includes.
23
#include <drizzled/data_home.h>
520.8.2 by Monty Taylor
Moved sql_parse.h and sql_error.h out of common_includes.
24
#include <drizzled/sql_parse.h>
1241.9.57 by Monty Taylor
Oy. Bigger change than I normally like - but this stuff is all intertwined.
25
#include <drizzled/my_hash.h>
584.1.15 by Monty Taylor
The mega-patch from hell. Renamed sql_class to session (since that's what it is) and removed it and field and table from common_includes.
26
#include <drizzled/sql_lex.h>
27
#include <drizzled/session.h>
28
#include <drizzled/sql_base.h>
1241.9.12 by Monty Taylor
Trims more out of server_includes.h.
29
#include "drizzled/strfunc.h"
584.1.15 by Monty Taylor
The mega-patch from hell. Renamed sql_class to session (since that's what it is) and removed it and field and table from common_includes.
30
#include <drizzled/db.h>
670.2.4 by Monty Taylor
Removed more stuff from the headers.
31
#include <drizzled/lock.h>
32
#include <drizzled/unireg.h>
642.1.21 by Lee
header file clean up
33
#include <drizzled/item/int.h>
675 by Brian Aker
Cleanup around item includes.
34
#include <drizzled/item/empty_string.h>
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
35
#include <drizzled/transaction_services.h>
1273.1.2 by Jay Pipes
This patch does not change any algorithms or code paths,
36
#include "drizzled/transaction_services.h"
1095.3.2 by Stewart Smith
remove copy_table_proto_file and replace with read and write proto calls. affects CREATE TABLE LIKE
37
#include <drizzled/table_proto.h>
971.6.1 by Eric Day
Renamed Protocol to Client, cleaned up some unnecessary methods along the way.
38
#include <drizzled/plugin/client.h>
1223.4.1 by Brian Aker
Table Identifier patch.
39
#include <drizzled/table_identifier.h>
1241.9.64 by Monty Taylor
Moved remaining non-public portions of mysys and mystrings to drizzled/internal.
40
#include "drizzled/internal/m_string.h"
1241.9.28 by Monty Taylor
Removed global_charset_info.h from server_includes.h
41
#include "drizzled/global_charset_info.h"
1241.9.57 by Monty Taylor
Oy. Bigger change than I normally like - but this stuff is all intertwined.
42
#include "drizzled/charset.h"
1241.9.28 by Monty Taylor
Removed global_charset_info.h from server_includes.h
43
988.1.6 by Jay Pipes
Removed old protobuf_replicator plugin, fixed up db.cc and other files to use new
44
1225.1.4 by Padraig O'Sullivan
The alter_table header file still needs to be included by sql_table
45
#include "drizzled/statement/alter_table.h"
1241.9.23 by Monty Taylor
Removed sql_table.h from server_includes.h.
46
#include "drizzled/sql_table.h"
1241.9.31 by Monty Taylor
Moved global pthread variables into their own header.
47
#include "drizzled/pthread_globals.h"
1225.1.4 by Padraig O'Sullivan
The alter_table header file still needs to be included by sql_table
48
1067.4.4 by Nathan Williams
The rest of the files in the drizzled directory were purged of the cmin macro and replace with std::min (except for the definition in globals.h and 1 usage in stacktrace.cc).
49
#include <algorithm>
1241.9.17 by Monty Taylor
Removed more bits from server_includes.
50
#include <sstream>
1001.1.3 by Andrew Ettinger
Revert bad spacing
51
670.3.3 by Toru Maesaka
Added namespacing for std to .cc files that needed it
52
using namespace std;
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
53
54
namespace drizzled
55
{
590.1.1 by Stewart Smith
begin moving from global const char* primary_key_name to methods is_primary_key() and is_primary_key_name()
56
1308.2.11 by Jay Pipes
* Adds CREATE TABLE as a specific CreateTableStatement message in the
57
extern plugin::StorageEngine *myisam_engine;
1241.9.31 by Monty Taylor
Moved global pthread variables into their own header.
58
extern pid_t current_pid;
59
590.1.1 by Stewart Smith
begin moving from global const char* primary_key_name to methods is_primary_key() and is_primary_key_name()
60
bool is_primary_key(KEY *key_info)
61
{
62
  static const char * primary_key_name="PRIMARY";
63
  return (strcmp(key_info->name, primary_key_name)==0);
64
}
65
66
const char* is_primary_key_name(const char* key_name)
67
{
68
  static const char * primary_key_name="PRIMARY";
69
  if (strcmp(key_name, primary_key_name)==0)
70
    return key_name;
71
  else
72
    return NULL;
73
}
1 by brian
clean slate
74
75
static bool check_if_keyname_exists(const char *name,KEY *start, KEY *end);
76
static char *make_unique_key_name(const char *field_name,KEY *start,KEY *end);
77
1052.2.3 by Nathan Williams
No actual code changes. Changed Create_field to CreateField to be consistent with coding standards.
78
static bool prepare_blob_field(Session *session, CreateField *sql_field);
1 by brian
clean slate
79
1223.4.3 by Brian Aker
More identifier work.
80
void set_table_default_charset(HA_CREATE_INFO *create_info, const char *db)
820.1.11 by Stewart Smith
re-introduce db.opt, but with parsing it from disk instead of in process cache with mutex.
81
{
82
  /*
83
    If the table character set was not given explicitly,
84
    let's fetch the database default character set and
85
    apply it to the table.
86
  */
1014.3.1 by Brian Aker
Simplify the calling stack for getting schema collation. We need to extend
87
  if (create_info->default_table_charset == NULL)
1273.20.3 by Brian Aker
Fixing charset return.
88
    create_info->default_table_charset= plugin::StorageEngine::getSchemaCollation(db);
820.1.11 by Stewart Smith
re-introduce db.opt, but with parsing it from disk instead of in process cache with mutex.
89
}
90
1 by brian
clean slate
91
/*
92
  SYNOPSIS
93
    write_bin_log()
520.1.22 by Brian Aker
Second pass of thd cleanup
94
    session                           Thread object
1 by brian
clean slate
95
    query                         Query to log
96
    query_length                  Length of query
97
98
  RETURN VALUES
99
    NONE
100
101
  DESCRIPTION
102
    Write the binlog if open, routine used in multiple places in this
1208.3.2 by brian
Update for Cursor renaming.
103
    cursor
1 by brian
clean slate
104
*/
105
1172 by Brian Aker
Update to delete table to centralize the replication logic.
106
void write_bin_log(Session *session,
1280.3.11 by Padraig O'Sullivan
Changed the query member of Session to be std::string
107
                   char const *query)
1 by brian
clean slate
108
{
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
109
  TransactionServices &transaction_services= TransactionServices::singleton();
110
  transaction_services.rawStatement(session, query);
1 by brian
clean slate
111
}
112
113
1172 by Brian Aker
Update to delete table to centralize the replication logic.
114
/* Should should be refactored to go away */
1223.4.10 by Brian Aker
Split remove table into 2 parts. The piece for dropDatabase() needs to be
115
void write_bin_log_drop_table(Session *session, bool if_exists, const char *db_name, const char *table_name)
1172 by Brian Aker
Update to delete table to centralize the replication logic.
116
{
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
117
  TransactionServices &transaction_services= TransactionServices::singleton();
1172 by Brian Aker
Update to delete table to centralize the replication logic.
118
  string built_query;
119
120
  if (if_exists)
1143.2.18 by Jay Pipes
Merge trunk and resolve conflicts.
121
    built_query.append("DROP TABLE IF EXISTS ");
1172 by Brian Aker
Update to delete table to centralize the replication logic.
122
  else
1143.2.18 by Jay Pipes
Merge trunk and resolve conflicts.
123
    built_query.append("DROP TABLE ");
1172 by Brian Aker
Update to delete table to centralize the replication logic.
124
125
  built_query.append("`");
1220.1.9 by Brian Aker
Remove char *db from session, and replaces it with std::string.
126
  if (session->db.empty() || strcmp(db_name, session->db.c_str()) != 0)
1172 by Brian Aker
Update to delete table to centralize the replication logic.
127
  {
128
    built_query.append(db_name);
129
    built_query.append("`.`");
130
  }
131
132
  built_query.append(table_name);
133
  built_query.append("`");
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
134
  transaction_services.rawStatement(session, built_query);
1172 by Brian Aker
Update to delete table to centralize the replication logic.
135
}
136
1 by brian
clean slate
137
/*
138
  Execute the drop of a normal or temporary table
139
140
  SYNOPSIS
141
    mysql_rm_table_part2()
1183.1.2 by Brian Aker
Rename of handler to Cursor. You would not believe how long I have wanted
142
    session			Thread Cursor
1 by brian
clean slate
143
    tables		Tables to drop
144
    if_exists		If set, don't give an error if table doesn't exists.
145
			In this case we give an warning of level 'NOTE'
146
    drop_temporary	Only drop temporary tables
147
148
  TODO:
149
    When logging to the binary log, we should log
150
    tmp_tables and transactional tables as separate statements if we
151
    are in a transaction;  This is needed to get these tables into the
152
    cached binary log that is only written on COMMIT.
153
154
   The current code only writes DROP statements that only uses temporary
155
   tables to the cache binary log.  This should be ok on most cases, but
156
   not all.
157
158
 RETURN
159
   0	ok
160
   1	Error
161
   -1	Thread was killed
162
*/
163
520.1.22 by Brian Aker
Second pass of thd cleanup
164
int mysql_rm_table_part2(Session *session, TableList *tables, bool if_exists,
1223.4.10 by Brian Aker
Split remove table into 2 parts. The piece for dropDatabase() needs to be
165
                         bool drop_temporary)
1 by brian
clean slate
166
{
327.2.4 by Brian Aker
Refactoring table.h
167
  TableList *table;
1 by brian
clean slate
168
  String wrong_tables;
169
  int error= 0;
1172 by Brian Aker
Update to delete table to centralize the replication logic.
170
  bool foreign_key_error= false;
1 by brian
clean slate
171
1046.1.2 by Brian Aker
Comments on LOCK_open
172
  pthread_mutex_lock(&LOCK_open); /* Part 2 of rm a table */
1 by brian
clean slate
173
174
  /*
175
    If we have the table in the definition cache, we don't have to check the
1208.3.2 by brian
Update for Cursor renaming.
176
    .frm cursor to find if the table is a normal table (not view) and what
1 by brian
clean slate
177
    engine to use.
178
  */
179
180
  for (table= tables; table; table= table->next_local)
181
  {
1000.1.3 by Brian Aker
Renamed TABLE_SHARE to TableShare
182
    TableShare *share;
1 by brian
clean slate
183
    table->db_type= NULL;
1093.6.1 by Brian Aker
Refactor TableShare has to be behind class.
184
    if ((share= TableShare::getShare(table->db, table->table_name)))
1 by brian
clean slate
185
      table->db_type= share->db_type();
186
  }
187
1309.2.19 by Brian Aker
Removing cerr call, and fixed bug where tables might not be dropped if there
188
  if (not drop_temporary && lock_table_names_exclusively(session, tables))
1 by brian
clean slate
189
  {
190
    pthread_mutex_unlock(&LOCK_open);
1046.1.10 by Brian Aker
Formatting around return (style)
191
    return 1;
1 by brian
clean slate
192
  }
193
194
  /* Don't give warnings for not found errors, as we already generate notes */
520.1.22 by Brian Aker
Second pass of thd cleanup
195
  session->no_warnings_for_error= 1;
1 by brian
clean slate
196
197
  for (table= tables; table; table= table->next_local)
198
  {
199
    char *db=table->db;
200
1054.1.9 by Brian Aker
This is a large number of refactors against the Session class for its
201
    error= session->drop_temporary_table(table);
1 by brian
clean slate
202
203
    switch (error) {
204
    case  0:
205
      // removed temporary table
206
      continue;
207
    case -1:
208
      error= 1;
209
      goto err_with_placeholders;
210
    default:
211
      // temporary table not found
212
      error= 0;
213
    }
214
1223.4.9 by Brian Aker
Moved mysql_rm to its statement since it is just used there. Also removed
215
    if (drop_temporary == false)
1 by brian
clean slate
216
    {
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
217
      Table *locked_table;
520.1.22 by Brian Aker
Second pass of thd cleanup
218
      abort_locked_tables(session, db, table->table_name);
219
      remove_table_from_cache(session, db, table->table_name,
1 by brian
clean slate
220
                              RTFC_WAIT_OTHER_THREAD_FLAG |
221
                              RTFC_CHECK_KILLED_FLAG);
222
      /*
223
        If the table was used in lock tables, remember it so that
224
        unlock_table_names can free it
225
      */
520.1.22 by Brian Aker
Second pass of thd cleanup
226
      if ((locked_table= drop_locked_tables(session, db, table->table_name)))
1 by brian
clean slate
227
        table->table= locked_table;
228
520.1.22 by Brian Aker
Second pass of thd cleanup
229
      if (session->killed)
1 by brian
clean slate
230
      {
231
        error= -1;
232
        goto err_with_placeholders;
233
      }
234
    }
1309.2.16 by Brian Aker
Small name change (AKA... I hate reading the NO_**@##@$# logic).
235
    TableIdentifier identifier(db, table->table_name, table->internal_tmp_table ? INTERNAL_TMP_TABLE : STANDARD_TABLE);
1172 by Brian Aker
Update to delete table to centralize the replication logic.
236
1309.1.25 by Brian Aker
Slight cleanup.
237
    if (drop_temporary || not plugin::StorageEngine::doesTableExist(*session, identifier))
1 by brian
clean slate
238
    {
239
      // Table was not found on disk and table can't be created from engine
240
      if (if_exists)
520.1.22 by Brian Aker
Second pass of thd cleanup
241
        push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
1 by brian
clean slate
242
                            ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR),
243
                            table->table_name);
244
      else
245
        error= 1;
246
    }
247
    else
248
    {
1309.1.29 by Brian Aker
We must walk, before we can run.
249
      error= plugin::StorageEngine::dropTable(*session, identifier);
1223.4.11 by Brian Aker
Modifications to use mysql_rm_table
250
1172 by Brian Aker
Update to delete table to centralize the replication logic.
251
      if ((error == ENOENT || error == HA_ERR_NO_SUCH_TABLE) && if_exists)
1 by brian
clean slate
252
      {
1308.2.4 by Jay Pipes
Adds DROP TABLE to the list of non RAW_SQL statements in replication stream
253
        error= 0;
520.1.22 by Brian Aker
Second pass of thd cleanup
254
        session->clear_error();
1 by brian
clean slate
255
      }
1172 by Brian Aker
Update to delete table to centralize the replication logic.
256
1 by brian
clean slate
257
      if (error == HA_ERR_ROW_IS_REFERENCED)
258
      {
259
        /* the table is referenced by a foreign key constraint */
1172 by Brian Aker
Update to delete table to centralize the replication logic.
260
        foreign_key_error= true;
1 by brian
clean slate
261
      }
262
    }
1172 by Brian Aker
Update to delete table to centralize the replication logic.
263
264
    if (error == 0 || (if_exists && foreign_key_error == false))
1308.2.4 by Jay Pipes
Adds DROP TABLE to the list of non RAW_SQL statements in replication stream
265
    {
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
266
      TransactionServices &transaction_services= TransactionServices::singleton();
267
      transaction_services.dropTable(session, string(db), string(table->table_name), if_exists);
1308.2.4 by Jay Pipes
Adds DROP TABLE to the list of non RAW_SQL statements in replication stream
268
    }
1172 by Brian Aker
Update to delete table to centralize the replication logic.
269
1 by brian
clean slate
270
    if (error)
271
    {
272
      if (wrong_tables.length())
273
        wrong_tables.append(',');
274
      wrong_tables.append(String(table->table_name,system_charset_info));
275
    }
276
  }
277
  /*
278
    It's safe to unlock LOCK_open: we have an exclusive lock
279
    on the table name.
280
  */
281
  pthread_mutex_unlock(&LOCK_open);
282
  error= 0;
283
  if (wrong_tables.length())
284
  {
285
    if (!foreign_key_error)
286
      my_printf_error(ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR), MYF(0),
287
                      wrong_tables.c_ptr());
288
    else
186 by Brian Aker
Partial fix for alter table
289
    {
1 by brian
clean slate
290
      my_message(ER_ROW_IS_REFERENCED, ER(ER_ROW_IS_REFERENCED), MYF(0));
186 by Brian Aker
Partial fix for alter table
291
    }
1 by brian
clean slate
292
    error= 1;
293
  }
294
1046.1.2 by Brian Aker
Comments on LOCK_open
295
  pthread_mutex_lock(&LOCK_open); /* final bit in rm table lock */
1 by brian
clean slate
296
err_with_placeholders:
1034.1.7 by Brian Aker
Remove dead bits to the end of functions.
297
  unlock_table_names(tables, NULL);
1 by brian
clean slate
298
  pthread_mutex_unlock(&LOCK_open);
520.1.22 by Brian Aker
Second pass of thd cleanup
299
  session->no_warnings_for_error= 0;
1034.1.7 by Brian Aker
Remove dead bits to the end of functions.
300
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
301
  return(error);
1 by brian
clean slate
302
}
303
304
305
/*
306
  Quickly remove a table.
307
308
  SYNOPSIS
309
    quick_rm_table()
1130.1.4 by Monty Taylor
Moved StorageEngine into plugin namespace.
310
      base                      The plugin::StorageEngine handle.
1 by brian
clean slate
311
      db                        The database name.
312
      table_name                The table name.
1039.1.6 by Brian Aker
Refactor for build_table_filename()
313
      is_tmp                    If the table is temp.
1 by brian
clean slate
314
315
  RETURN
316
    0           OK
317
    != 0        Error
318
*/
1235.2.1 by Brian Aker
More identifier work.
319
bool quick_rm_table(Session& session,
320
                    TableIdentifier &identifier)
1 by brian
clean slate
321
{
1309.1.29 by Brian Aker
We must walk, before we can run.
322
  return (plugin::StorageEngine::dropTable(session, identifier));
1 by brian
clean slate
323
}
324
325
/*
326
  Sort keys in the following order:
327
  - PRIMARY KEY
328
  - UNIQUE keys where all column are NOT NULL
329
  - UNIQUE keys that don't contain partial segments
330
  - Other UNIQUE keys
331
  - Normal keys
332
  - Fulltext keys
333
334
  This will make checking for duplicated keys faster and ensure that
335
  PRIMARY keys are prioritized.
336
*/
337
338
static int sort_keys(KEY *a, KEY *b)
339
{
340
  ulong a_flags= a->flags, b_flags= b->flags;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
341
1 by brian
clean slate
342
  if (a_flags & HA_NOSAME)
343
  {
344
    if (!(b_flags & HA_NOSAME))
345
      return -1;
53.2.14 by Monty Taylor
Removed HA_END_SPACE_KEY and references to it. It was _supposed_ to be gone anyway, but the ifdef around it was broken (MYSQL_VERSION_ID was actually undefined.)
346
    if ((a_flags ^ b_flags) & (HA_NULL_PART_KEY))
1 by brian
clean slate
347
    {
348
      /* Sort NOT NULL keys before other keys */
53.2.14 by Monty Taylor
Removed HA_END_SPACE_KEY and references to it. It was _supposed_ to be gone anyway, but the ifdef around it was broken (MYSQL_VERSION_ID was actually undefined.)
349
      return (a_flags & (HA_NULL_PART_KEY)) ? 1 : -1;
1 by brian
clean slate
350
    }
590.1.1 by Stewart Smith
begin moving from global const char* primary_key_name to methods is_primary_key() and is_primary_key_name()
351
    if (is_primary_key(a))
1 by brian
clean slate
352
      return -1;
590.1.1 by Stewart Smith
begin moving from global const char* primary_key_name to methods is_primary_key() and is_primary_key_name()
353
    if (is_primary_key(b))
1 by brian
clean slate
354
      return 1;
355
    /* Sort keys don't containing partial segments before others */
356
    if ((a_flags ^ b_flags) & HA_KEY_HAS_PART_KEY_SEG)
357
      return (a_flags & HA_KEY_HAS_PART_KEY_SEG) ? 1 : -1;
358
  }
359
  else if (b_flags & HA_NOSAME)
360
    return 1;					// Prefer b
361
362
  /*
363
    Prefer original key order.	usable_key_parts contains here
364
    the original key position.
365
  */
366
  return ((a->usable_key_parts < b->usable_key_parts) ? -1 :
367
          (a->usable_key_parts > b->usable_key_parts) ? 1 :
368
          0);
369
}
370
371
/*
372
  Check TYPELIB (set or enum) for duplicates
373
374
  SYNOPSIS
375
    check_duplicates_in_interval()
376
    set_or_name   "SET" or "ENUM" string for warning message
377
    name	  name of the checked column
378
    typelib	  list of values for the column
379
    dup_val_count  returns count of duplicate elements
380
381
  DESCRIPTION
382
    This function prints an warning for each value in list
383
    which has some duplicates on its right
384
385
  RETURN VALUES
386
    0             ok
387
    1             Error
388
*/
389
1085.1.2 by Monty Taylor
Fixed -Wmissing-declarations
390
static bool check_duplicates_in_interval(const char *set_or_name,
391
                                         const char *name, TYPELIB *typelib,
392
                                         const CHARSET_INFO * const cs,
393
                                         unsigned int *dup_val_count)
1 by brian
clean slate
394
{
395
  TYPELIB tmp= *typelib;
396
  const char **cur_value= typelib->type_names;
397
  unsigned int *cur_length= typelib->type_lengths;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
398
  *dup_val_count= 0;
399
1 by brian
clean slate
400
  for ( ; tmp.count > 1; cur_value++, cur_length++)
401
  {
402
    tmp.type_names++;
403
    tmp.type_lengths++;
404
    tmp.count--;
405
    if (find_type2(&tmp, (const char*)*cur_value, *cur_length, cs))
406
    {
407
      my_error(ER_DUPLICATED_VALUE_IN_TYPE, MYF(0),
408
               name,*cur_value,set_or_name);
409
      return 1;
410
    }
411
  }
412
  return 0;
413
}
414
415
416
/*
417
  Check TYPELIB (set or enum) max and total lengths
418
419
  SYNOPSIS
420
    calculate_interval_lengths()
421
    cs            charset+collation pair of the interval
422
    typelib       list of values for the column
423
    max_length    length of the longest item
424
    tot_length    sum of the item lengths
425
426
  DESCRIPTION
427
    After this function call:
428
    - ENUM uses max_length
429
    - SET uses tot_length.
430
431
  RETURN VALUES
432
    void
433
*/
1085.1.2 by Monty Taylor
Fixed -Wmissing-declarations
434
static void calculate_interval_lengths(const CHARSET_INFO * const cs,
435
                                       TYPELIB *interval,
436
                                       uint32_t *max_length,
437
                                       uint32_t *tot_length)
1 by brian
clean slate
438
{
439
  const char **pos;
482 by Brian Aker
Remove uint.
440
  uint32_t *len;
1 by brian
clean slate
441
  *max_length= *tot_length= 0;
442
  for (pos= interval->type_names, len= interval->type_lengths;
443
       *pos ; pos++, len++)
444
  {
482 by Brian Aker
Remove uint.
445
    uint32_t length= cs->cset->numchars(cs, *pos, *pos + *len);
1 by brian
clean slate
446
    *tot_length+= length;
205 by Brian Aker
uint32 -> uin32_t
447
    set_if_bigger(*max_length, (uint32_t)length);
1 by brian
clean slate
448
  }
449
}
450
451
/*
452
  Prepare a create_table instance for packing
453
454
  SYNOPSIS
455
    prepare_create_field()
456
    sql_field     field to prepare for packing
457
    blob_columns  count for BLOBs
458
    timestamps    count for timestamps
459
460
  DESCRIPTION
1052.2.3 by Nathan Williams
No actual code changes. Changed Create_field to CreateField to be consistent with coding standards.
461
    This function prepares a CreateField instance.
1 by brian
clean slate
462
    Fields such as pack_flag are valid after this call.
463
464
  RETURN VALUES
465
   0	ok
466
   1	Error
467
*/
1052.2.3 by Nathan Williams
No actual code changes. Changed Create_field to CreateField to be consistent with coding standards.
468
int prepare_create_field(CreateField *sql_field,
482 by Brian Aker
Remove uint.
469
                         uint32_t *blob_columns,
1233.1.8 by Brian Aker
Final removal table_flag().
470
                         int *timestamps,
471
                         int *timestamps_with_niladic)
1 by brian
clean slate
472
{
473
  unsigned int dup_val_count;
474
475
  /*
476
    This code came from mysql_prepare_create_table.
477
    Indent preserved to make patching easier
478
  */
51.2.1 by Patrick Galbraith
Removed DBUG_PRINTs, DBUG_ASSERTs, DBUG_EXECUTE_IFs from
479
  assert(sql_field->charset);
1 by brian
clean slate
480
481
  switch (sql_field->sql_type) {
212.2.2 by Patrick Galbraith
Renamed FIELD_TYPE to DRIZZLE_TYPE
482
  case DRIZZLE_TYPE_BLOB:
1119.9.2 by Jay Pipes
Phase I removal of FIELDFLAG_BLOB. This is a piece of poop.
483
    sql_field->pack_flag= pack_length_to_packflag(sql_field->pack_length - portable_sizeof_char_ptr);
484
    sql_field->length= 8; // Unireg field length
1 by brian
clean slate
485
    (*blob_columns)++;
486
    break;
212.2.2 by Patrick Galbraith
Renamed FIELD_TYPE to DRIZZLE_TYPE
487
  case DRIZZLE_TYPE_VARCHAR:
1 by brian
clean slate
488
    sql_field->pack_flag=0;
489
    break;
212.2.2 by Patrick Galbraith
Renamed FIELD_TYPE to DRIZZLE_TYPE
490
  case DRIZZLE_TYPE_ENUM:
1119.9.1 by Jay Pipes
Removes ENUM FIELDFLAG (interval), the unused f_is_equ poop, and the FIELDFLAG_HEX_CHAR unused flag
491
    sql_field->pack_flag=pack_length_to_packflag(sql_field->pack_length);
492
    if (check_duplicates_in_interval("ENUM",
493
                                     sql_field->field_name,
494
                                     sql_field->interval,
495
                                     sql_field->charset,
496
                                     &dup_val_count))
1046.1.10 by Brian Aker
Formatting around return (style)
497
      return 1;
1 by brian
clean slate
498
    break;
575.5.1 by David Axmark
Changed NEWDATE to DATE. One failing test but I think its somewhere else in the code
499
  case DRIZZLE_TYPE_DATE:  // Rest of string types
212.2.2 by Patrick Galbraith
Renamed FIELD_TYPE to DRIZZLE_TYPE
500
  case DRIZZLE_TYPE_DATETIME:
501
  case DRIZZLE_TYPE_NULL:
895 by Brian Aker
Completion (?) of uint conversion.
502
    sql_field->pack_flag=f_settype((uint32_t) sql_field->sql_type);
1 by brian
clean slate
503
    break;
1211.1.1 by Brian Aker
Updating with my change to to DECIMAL from NEWDECIMAL and Stewart's update
504
  case DRIZZLE_TYPE_DECIMAL:
1119.9.19 by Stewart Smith
remove DECIMAL_FLAG, FIELDFLAG_DECIMAL_POSITION and f_is_decimal_precision all related to pack_flag and all effectively unused.
505
    sql_field->pack_flag= 0;
1 by brian
clean slate
506
    break;
212.2.2 by Patrick Galbraith
Renamed FIELD_TYPE to DRIZZLE_TYPE
507
  case DRIZZLE_TYPE_TIMESTAMP:
1 by brian
clean slate
508
    /* We should replace old TIMESTAMP fields with their newer analogs */
509
    if (sql_field->unireg_check == Field::TIMESTAMP_OLD_FIELD)
510
    {
511
      if (!*timestamps)
512
      {
513
        sql_field->unireg_check= Field::TIMESTAMP_DNUN_FIELD;
514
        (*timestamps_with_niladic)++;
515
      }
516
      else
517
        sql_field->unireg_check= Field::NONE;
518
    }
519
    else if (sql_field->unireg_check != Field::NONE)
520
      (*timestamps_with_niladic)++;
521
522
    (*timestamps)++;
523
    /* fall-through */
524
  default:
1119.9.6 by Jay Pipes
Removes the FIELDFLAG_DECIMAL, the f_is_dec() macro, and unscrews the unsigned flag in various places.
525
    sql_field->pack_flag=(0 |
1119.9.16 by Stewart Smith
don't store decimal/double scale in pack_flag, instead use the numeric option scale field in the table proto. This removes f_decimals() macro and the bits in the pack_flag for scale.
526
                          f_settype((uint32_t) sql_field->sql_type));
1 by brian
clean slate
527
    break;
528
  }
1046.1.10 by Brian Aker
Formatting around return (style)
529
  return 0;
1 by brian
clean slate
530
}
531
1320.1.3 by Brian Aker
More reference cleanup.
532
static int mysql_prepare_create_table(Session *session,
533
                                      HA_CREATE_INFO *create_info,
534
                                      message::Table &create_proto,
535
                                      AlterInfo *alter_info,
536
                                      bool tmp_table,
537
                                      uint32_t *db_options,
538
                                      KEY **key_info_buffer,
539
                                      uint32_t *key_count,
540
                                      int select_field_count)
1 by brian
clean slate
541
{
542
  const char	*key_name;
1052.2.3 by Nathan Williams
No actual code changes. Changed Create_field to CreateField to be consistent with coding standards.
543
  CreateField	*sql_field,*dup_field;
1 by brian
clean slate
544
  uint		field,null_fields,blob_columns,max_key_length;
545
  ulong		record_offset= 0;
546
  KEY		*key_info;
547
  KEY_PART_INFO *key_part_info;
548
  int		timestamps= 0, timestamps_with_niladic= 0;
549
  int		field_no,dup_no;
550
  int		select_field_pos,auto_increment=0;
1052.2.3 by Nathan Williams
No actual code changes. Changed Create_field to CreateField to be consistent with coding standards.
551
  List_iterator<CreateField> it(alter_info->create_list);
552
  List_iterator<CreateField> it2(alter_info->create_list);
482 by Brian Aker
Remove uint.
553
  uint32_t total_uneven_bit_length= 0;
1 by brian
clean slate
554
1320.1.15 by Brian Aker
Remove old need for Cursor in creating table.
555
  plugin::StorageEngine *engine= plugin::StorageEngine::findByName(create_proto.engine().name());
556
1 by brian
clean slate
557
  select_field_pos= alter_info->create_list.elements - select_field_count;
558
  null_fields=blob_columns=0;
1320.1.15 by Brian Aker
Remove old need for Cursor in creating table.
559
  max_key_length= engine->max_key_length();
1 by brian
clean slate
560
561
  for (field_no=0; (sql_field=it++) ; field_no++)
562
  {
264.2.6 by Andrey Hristov
Constify the usage of CHARSET_INFO almost to the last place in the code.
563
    const CHARSET_INFO *save_cs;
1 by brian
clean slate
564
565
    /*
566
      Initialize length from its original value (number of characters),
567
      which was set in the parser. This is necessary if we're
568
      executing a prepared statement for the second time.
569
    */
570
    sql_field->length= sql_field->char_length;
571
    if (!sql_field->charset)
572
      sql_field->charset= create_info->default_table_charset;
573
    /*
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
574
      table_charset is set in ALTER Table if we want change character set
1 by brian
clean slate
575
      for all varchar/char columns.
576
      But the table charset must not affect the BLOB fields, so don't
577
      allow to change my_charset_bin to somethig else.
578
    */
579
    if (create_info->table_charset && sql_field->charset != &my_charset_bin)
580
      sql_field->charset= create_info->table_charset;
581
582
    save_cs= sql_field->charset;
583
    if ((sql_field->flags & BINCMP_FLAG) &&
862 by Brian Aker
Remove charset directory code.
584
        !(sql_field->charset= get_charset_by_csname(sql_field->charset->csname, MY_CS_BINSORT)))
1 by brian
clean slate
585
    {
586
      char tmp[64];
629.5.3 by Toru Maesaka
Third pass of replacing MySQL's strmake() with libc calls
587
      char *tmp_pos= tmp;
588
      strncpy(tmp_pos, save_cs->csname, sizeof(tmp)-4);
589
      tmp_pos+= strlen(tmp);
590
      strncpy(tmp_pos, STRING_WITH_LEN("_bin"));
1 by brian
clean slate
591
      my_error(ER_UNKNOWN_COLLATION, MYF(0), tmp);
51.1.8 by Jay Pipes
Resolving conflicts for a few files regarding FALSE=>false
592
      return(true);
1 by brian
clean slate
593
    }
594
595
    /*
596
      Convert the default value from client character
597
      set into the column character set if necessary.
598
    */
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
599
    if (sql_field->def &&
1 by brian
clean slate
600
        save_cs != sql_field->def->collation.collation &&
325 by Brian Aker
Remove SET
601
        (sql_field->sql_type == DRIZZLE_TYPE_ENUM))
1 by brian
clean slate
602
    {
603
      /*
1052.2.3 by Nathan Williams
No actual code changes. Changed Create_field to CreateField to be consistent with coding standards.
604
        Starting from 5.1 we work here with a copy of CreateField
1 by brian
clean slate
605
        created by the caller, not with the instance that was
606
        originally created during parsing. It's OK to create
607
        a temporary item and initialize with it a member of the
608
        copy -- this item will be thrown away along with the copy
609
        at the end of execution, and thus not introduce a dangling
610
        pointer in the parsed tree of a prepared statement or a
611
        stored procedure statement.
612
      */
613
      sql_field->def= sql_field->def->safe_charset_converter(save_cs);
614
615
      if (sql_field->def == NULL)
616
      {
617
        /* Could not convert */
618
        my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name);
51.1.8 by Jay Pipes
Resolving conflicts for a few files regarding FALSE=>false
619
        return(true);
1 by brian
clean slate
620
      }
621
    }
622
325 by Brian Aker
Remove SET
623
    if (sql_field->sql_type == DRIZZLE_TYPE_ENUM)
1 by brian
clean slate
624
    {
205 by Brian Aker
uint32 -> uin32_t
625
      uint32_t dummy;
264.2.6 by Andrey Hristov
Constify the usage of CHARSET_INFO almost to the last place in the code.
626
      const CHARSET_INFO * const cs= sql_field->charset;
1 by brian
clean slate
627
      TYPELIB *interval= sql_field->interval;
628
629
      /*
630
        Create typelib from interval_list, and if necessary
631
        convert strings from client character set to the
632
        column character set.
633
      */
634
      if (!interval)
635
      {
636
        /*
637
          Create the typelib in runtime memory - we will free the
638
          occupied memory at the same time when we free this
639
          sql_field -- at the end of execution.
640
        */
520.1.22 by Brian Aker
Second pass of thd cleanup
641
        interval= sql_field->interval= typelib(session->mem_root,
1101.1.24 by Monty Taylor
Reverted my change to interval_list
642
                                               sql_field->interval_list);
1101.3.1 by Nathan Williams
Reverted CreateField::interval_list to a List<String>. Fixes memory leaks I introduced by converting it to a vector in branch listed below.
643
644
        List_iterator<String> int_it(sql_field->interval_list);
645
        String conv, *tmp;
1 by brian
clean slate
646
        char comma_buf[4];
481 by Brian Aker
Remove all of uchar.
647
        int comma_length= cs->cset->wc_mb(cs, ',', (unsigned char*) comma_buf,
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
648
                                          (unsigned char*) comma_buf +
1 by brian
clean slate
649
                                          sizeof(comma_buf));
51.2.1 by Patrick Galbraith
Removed DBUG_PRINTs, DBUG_ASSERTs, DBUG_EXECUTE_IFs from
650
        assert(comma_length > 0);
1052.2.1 by Nathan Williams
Converted Create_field::interval_list to a std::list<String*>.
651
1101.3.1 by Nathan Williams
Reverted CreateField::interval_list to a List<String>. Fixes memory leaks I introduced by converting it to a vector in branch listed below.
652
        for (uint32_t i= 0; (tmp= int_it++); i++)
1 by brian
clean slate
653
        {
1101.3.1 by Nathan Williams
Reverted CreateField::interval_list to a List<String>. Fixes memory leaks I introduced by converting it to a vector in branch listed below.
654
          uint32_t lengthsp;
1 by brian
clean slate
655
          if (String::needs_conversion(tmp->length(), tmp->charset(),
656
                                       cs, &dummy))
657
          {
482 by Brian Aker
Remove uint.
658
            uint32_t cnv_errs;
1 by brian
clean slate
659
            conv.copy(tmp->ptr(), tmp->length(), tmp->charset(), cs, &cnv_errs);
520.1.22 by Brian Aker
Second pass of thd cleanup
660
            interval->type_names[i]= strmake_root(session->mem_root, conv.ptr(),
1 by brian
clean slate
661
                                                  conv.length());
662
            interval->type_lengths[i]= conv.length();
663
          }
664
665
          // Strip trailing spaces.
1101.3.1 by Nathan Williams
Reverted CreateField::interval_list to a List<String>. Fixes memory leaks I introduced by converting it to a vector in branch listed below.
666
          lengthsp= cs->cset->lengthsp(cs, interval->type_names[i],
667
                                       interval->type_lengths[i]);
1 by brian
clean slate
668
          interval->type_lengths[i]= lengthsp;
481 by Brian Aker
Remove all of uchar.
669
          ((unsigned char *)interval->type_names[i])[lengthsp]= '\0';
1 by brian
clean slate
670
        }
1101.1.24 by Monty Taylor
Reverted my change to interval_list
671
        sql_field->interval_list.empty(); // Don't need interval_list anymore
1 by brian
clean slate
672
      }
673
325 by Brian Aker
Remove SET
674
      /* DRIZZLE_TYPE_ENUM */
1 by brian
clean slate
675
      {
205 by Brian Aker
uint32 -> uin32_t
676
        uint32_t field_length;
212.2.2 by Patrick Galbraith
Renamed FIELD_TYPE to DRIZZLE_TYPE
677
        assert(sql_field->sql_type == DRIZZLE_TYPE_ENUM);
1 by brian
clean slate
678
        if (sql_field->def != NULL)
679
        {
680
          String str, *def= sql_field->def->val_str(&str);
681
          if (def == NULL) /* SQL "NULL" maps to NULL */
682
          {
683
            if ((sql_field->flags & NOT_NULL_FLAG) != 0)
684
            {
685
              my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name);
51.1.8 by Jay Pipes
Resolving conflicts for a few files regarding FALSE=>false
686
              return(true);
1 by brian
clean slate
687
            }
688
689
            /* else, the defaults yield the correct length for NULLs. */
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
690
          }
1 by brian
clean slate
691
          else /* not NULL */
692
          {
693
            def->length(cs->cset->lengthsp(cs, def->ptr(), def->length()));
694
            if (find_type2(interval, def->ptr(), def->length(), cs) == 0) /* not found */
695
            {
696
              my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name);
51.1.8 by Jay Pipes
Resolving conflicts for a few files regarding FALSE=>false
697
              return(true);
1 by brian
clean slate
698
            }
699
          }
700
        }
701
        calculate_interval_lengths(cs, interval, &field_length, &dummy);
702
        sql_field->length= field_length;
703
      }
937.2.6 by Stewart Smith
make set_if_bigger typesafe for C and C++. Fix up everywhere.
704
      set_if_smaller(sql_field->length, (uint32_t)MAX_FIELD_WIDTH-1);
1 by brian
clean slate
705
    }
706
707
    sql_field->create_length_to_internal_length();
520.1.22 by Brian Aker
Second pass of thd cleanup
708
    if (prepare_blob_field(session, sql_field))
51.1.8 by Jay Pipes
Resolving conflicts for a few files regarding FALSE=>false
709
      return(true);
1 by brian
clean slate
710
711
    if (!(sql_field->flags & NOT_NULL_FLAG))
712
      null_fields++;
713
714
    if (check_column_name(sql_field->field_name))
715
    {
716
      my_error(ER_WRONG_COLUMN_NAME, MYF(0), sql_field->field_name);
51.1.8 by Jay Pipes
Resolving conflicts for a few files regarding FALSE=>false
717
      return(true);
1 by brian
clean slate
718
    }
719
720
    /* Check if we have used the same field name before */
721
    for (dup_no=0; (dup_field=it2++) != sql_field; dup_no++)
722
    {
723
      if (my_strcasecmp(system_charset_info,
724
                        sql_field->field_name,
725
                        dup_field->field_name) == 0)
726
      {
727
	/*
728
	  If this was a CREATE ... SELECT statement, accept a field
729
	  redefinition if we are changing a field in the SELECT part
730
	*/
731
	if (field_no < select_field_pos || dup_no >= select_field_pos)
732
	{
733
	  my_error(ER_DUP_FIELDNAME, MYF(0), sql_field->field_name);
51.1.8 by Jay Pipes
Resolving conflicts for a few files regarding FALSE=>false
734
	  return(true);
1 by brian
clean slate
735
	}
736
	else
737
	{
738
	  /* Field redefined */
739
	  sql_field->def=		dup_field->def;
740
	  sql_field->sql_type=		dup_field->sql_type;
741
	  sql_field->charset=		(dup_field->charset ?
742
					 dup_field->charset :
743
					 create_info->default_table_charset);
744
	  sql_field->length=		dup_field->char_length;
745
          sql_field->pack_length=	dup_field->pack_length;
746
          sql_field->key_length=	dup_field->key_length;
747
	  sql_field->decimals=		dup_field->decimals;
748
	  sql_field->create_length_to_internal_length();
749
	  sql_field->unireg_check=	dup_field->unireg_check;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
750
          /*
1 by brian
clean slate
751
            We're making one field from two, the result field will have
752
            dup_field->flags as flags. If we've incremented null_fields
753
            because of sql_field->flags, decrement it back.
754
          */
755
          if (!(sql_field->flags & NOT_NULL_FLAG))
756
            null_fields--;
757
	  sql_field->flags=		dup_field->flags;
758
          sql_field->interval=          dup_field->interval;
759
	  it2.remove();			// Remove first (create) definition
760
	  select_field_pos--;
761
	  break;
762
	}
763
      }
764
    }
1308.2.11 by Jay Pipes
* Adds CREATE TABLE as a specific CreateTableStatement message in the
765
766
    /** @todo Get rid of this MyISAM-specific crap. */
1320.1.15 by Brian Aker
Remove old need for Cursor in creating table.
767
    if (not create_proto.engine().name().compare("MyISAM") &&
1308.2.11 by Jay Pipes
* Adds CREATE TABLE as a specific CreateTableStatement message in the
768
        ((sql_field->flags & BLOB_FLAG) ||
769
         (sql_field->sql_type == DRIZZLE_TYPE_VARCHAR && create_info->row_type != ROW_TYPE_FIXED)))
1 by brian
clean slate
770
      (*db_options)|= HA_OPTION_PACK_RECORD;
771
    it2.rewind();
772
  }
773
774
  /* record_offset will be increased with 'length-of-null-bits' later */
775
  record_offset= 0;
776
  null_fields+= total_uneven_bit_length;
777
778
  it.rewind();
779
  while ((sql_field=it++))
780
  {
51.2.1 by Patrick Galbraith
Removed DBUG_PRINTs, DBUG_ASSERTs, DBUG_EXECUTE_IFs from
781
    assert(sql_field->charset != 0);
1 by brian
clean slate
782
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
783
    if (prepare_create_field(sql_field, &blob_columns,
1233.1.8 by Brian Aker
Final removal table_flag().
784
			     &timestamps, &timestamps_with_niladic))
51.1.8 by Jay Pipes
Resolving conflicts for a few files regarding FALSE=>false
785
      return(true);
1 by brian
clean slate
786
    sql_field->offset= record_offset;
787
    if (MTYP_TYPENR(sql_field->unireg_check) == Field::NEXT_NUMBER)
788
      auto_increment++;
789
  }
790
  if (timestamps_with_niladic > 1)
791
  {
792
    my_message(ER_TOO_MUCH_AUTO_TIMESTAMP_COLS,
793
               ER(ER_TOO_MUCH_AUTO_TIMESTAMP_COLS), MYF(0));
51.1.8 by Jay Pipes
Resolving conflicts for a few files regarding FALSE=>false
794
    return(true);
1 by brian
clean slate
795
  }
796
  if (auto_increment > 1)
797
  {
798
    my_message(ER_WRONG_AUTO_KEY, ER(ER_WRONG_AUTO_KEY), MYF(0));
51.1.8 by Jay Pipes
Resolving conflicts for a few files regarding FALSE=>false
799
    return(true);
1 by brian
clean slate
800
  }
801
  if (auto_increment &&
1320.1.15 by Brian Aker
Remove old need for Cursor in creating table.
802
      (engine->check_flag(HTON_BIT_NO_AUTO_INCREMENT)))
1 by brian
clean slate
803
  {
804
    my_message(ER_TABLE_CANT_HANDLE_AUTO_INCREMENT,
805
               ER(ER_TABLE_CANT_HANDLE_AUTO_INCREMENT), MYF(0));
51.1.8 by Jay Pipes
Resolving conflicts for a few files regarding FALSE=>false
806
    return(true);
1 by brian
clean slate
807
  }
808
1320.1.15 by Brian Aker
Remove old need for Cursor in creating table.
809
  if (blob_columns && (engine->check_flag(HTON_BIT_NO_BLOBS)))
1 by brian
clean slate
810
  {
811
    my_message(ER_TABLE_CANT_HANDLE_BLOB, ER(ER_TABLE_CANT_HANDLE_BLOB),
812
               MYF(0));
51.1.8 by Jay Pipes
Resolving conflicts for a few files regarding FALSE=>false
813
    return(true);
1 by brian
clean slate
814
  }
815
816
  /* Create keys */
817
818
  List_iterator<Key> key_iterator(alter_info->key_list);
819
  List_iterator<Key> key_iterator2(alter_info->key_list);
482 by Brian Aker
Remove uint.
820
  uint32_t key_parts=0, fk_key_count=0;
1 by brian
clean slate
821
  bool primary_key=0,unique_key=0;
822
  Key *key, *key2;
482 by Brian Aker
Remove uint.
823
  uint32_t tmp, key_number;
1 by brian
clean slate
824
  /* special marker for keys to be ignored */
825
  static char ignore_key[1];
826
827
  /* Calculate number of key segements */
828
  *key_count= 0;
829
830
  while ((key=key_iterator++))
831
  {
832
    if (key->type == Key::FOREIGN_KEY)
833
    {
834
      fk_key_count++;
383.7.1 by Andrey Zhakov
Initial submit of code and tests
835
      if (((Foreign_key *)key)->validate(alter_info->create_list))
836
        return true;
1 by brian
clean slate
837
      Foreign_key *fk_key= (Foreign_key*) key;
838
      if (fk_key->ref_columns.elements &&
839
	  fk_key->ref_columns.elements != fk_key->columns.elements)
840
      {
841
        my_error(ER_WRONG_FK_DEF, MYF(0),
842
                 (fk_key->name.str ? fk_key->name.str :
843
                                     "foreign key without name"),
844
                 ER(ER_KEY_REF_DO_NOT_MATCH_TABLE_REF));
51.1.8 by Jay Pipes
Resolving conflicts for a few files regarding FALSE=>false
845
	return(true);
1 by brian
clean slate
846
      }
847
      continue;
848
    }
849
    (*key_count)++;
1320.1.15 by Brian Aker
Remove old need for Cursor in creating table.
850
    tmp= engine->max_key_parts();
1 by brian
clean slate
851
    if (key->columns.elements > tmp)
852
    {
853
      my_error(ER_TOO_MANY_KEY_PARTS,MYF(0),tmp);
51.1.8 by Jay Pipes
Resolving conflicts for a few files regarding FALSE=>false
854
      return(true);
1 by brian
clean slate
855
    }
856
    if (check_identifier_name(&key->name, ER_TOO_LONG_IDENT))
51.1.8 by Jay Pipes
Resolving conflicts for a few files regarding FALSE=>false
857
      return(true);
1 by brian
clean slate
858
    key_iterator2.rewind ();
859
    if (key->type != Key::FOREIGN_KEY)
860
    {
861
      while ((key2 = key_iterator2++) != key)
862
      {
863
	/*
864
          foreign_key_prefix(key, key2) returns 0 if key or key2, or both, is
865
          'generated', and a generated key is a prefix of the other key.
866
          Then we do not need the generated shorter key.
867
        */
868
        if ((key2->type != Key::FOREIGN_KEY &&
869
             key2->name.str != ignore_key &&
870
             !foreign_key_prefix(key, key2)))
871
        {
872
          /* TODO: issue warning message */
873
          /* mark that the generated key should be ignored */
874
          if (!key2->generated ||
875
              (key->generated && key->columns.elements <
876
               key2->columns.elements))
877
            key->name.str= ignore_key;
878
          else
879
          {
880
            key2->name.str= ignore_key;
881
            key_parts-= key2->columns.elements;
882
            (*key_count)--;
883
          }
884
          break;
885
        }
886
      }
887
    }
888
    if (key->name.str != ignore_key)
889
      key_parts+=key->columns.elements;
890
    else
891
      (*key_count)--;
892
    if (key->name.str && !tmp_table && (key->type != Key::PRIMARY) &&
590.1.1 by Stewart Smith
begin moving from global const char* primary_key_name to methods is_primary_key() and is_primary_key_name()
893
        is_primary_key_name(key->name.str))
1 by brian
clean slate
894
    {
895
      my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0), key->name.str);
51.1.8 by Jay Pipes
Resolving conflicts for a few files regarding FALSE=>false
896
      return(true);
1 by brian
clean slate
897
    }
898
  }
1320.1.15 by Brian Aker
Remove old need for Cursor in creating table.
899
  tmp= engine->max_keys();
1 by brian
clean slate
900
  if (*key_count > tmp)
901
  {
902
    my_error(ER_TOO_MANY_KEYS,MYF(0),tmp);
51.1.8 by Jay Pipes
Resolving conflicts for a few files regarding FALSE=>false
903
    return(true);
1 by brian
clean slate
904
  }
905
1253.1.6 by Monty Taylor
Moved mem_root functions into drizzled::memory:: namespace.
906
  (*key_info_buffer)= key_info= (KEY*) memory::sql_calloc(sizeof(KEY) * (*key_count));
907
  key_part_info=(KEY_PART_INFO*) memory::sql_calloc(sizeof(KEY_PART_INFO)*key_parts);
1 by brian
clean slate
908
  if (!*key_info_buffer || ! key_part_info)
51.1.8 by Jay Pipes
Resolving conflicts for a few files regarding FALSE=>false
909
    return(true);				// Out of memory
1 by brian
clean slate
910
911
  key_iterator.rewind();
912
  key_number=0;
913
  for (; (key=key_iterator++) ; key_number++)
914
  {
482 by Brian Aker
Remove uint.
915
    uint32_t key_length=0;
1 by brian
clean slate
916
    Key_part_spec *column;
917
918
    if (key->name.str == ignore_key)
919
    {
920
      /* ignore redundant keys */
921
      do
922
	key=key_iterator++;
923
      while (key && key->name.str == ignore_key);
924
      if (!key)
925
	break;
926
    }
927
928
    switch (key->type) {
929
    case Key::MULTIPLE:
930
	key_info->flags= 0;
931
	break;
932
    case Key::FOREIGN_KEY:
933
      key_number--;				// Skip this key
934
      continue;
935
    default:
936
      key_info->flags = HA_NOSAME;
937
      break;
938
    }
939
    if (key->generated)
940
      key_info->flags|= HA_GENERATED_KEY;
941
206 by Brian Aker
Removed final uint dead types.
942
    key_info->key_parts=(uint8_t) key->columns.elements;
1 by brian
clean slate
943
    key_info->key_part=key_part_info;
944
    key_info->usable_key_parts= key_number;
945
    key_info->algorithm= key->key_create_info.algorithm;
946
947
    /* Take block size from key part or table part */
948
    /*
949
      TODO: Add warning if block size changes. We can't do it here, as
950
      this may depend on the size of the key
951
    */
952
    key_info->block_size= (key->key_create_info.block_size ?
953
                           key->key_create_info.block_size :
1320.1.3 by Brian Aker
More reference cleanup.
954
                           create_proto.options().key_block_size());
1 by brian
clean slate
955
956
    if (key_info->block_size)
957
      key_info->flags|= HA_USES_BLOCK_SIZE;
958
482 by Brian Aker
Remove uint.
959
    uint32_t tmp_len= system_charset_info->cset->charpos(system_charset_info,
1 by brian
clean slate
960
                                           key->key_create_info.comment.str,
961
                                           key->key_create_info.comment.str +
962
                                           key->key_create_info.comment.length,
963
                                           INDEX_COMMENT_MAXLEN);
964
965
    if (tmp_len < key->key_create_info.comment.length)
966
    {
967
      my_error(ER_WRONG_STRING_LENGTH, MYF(0),
968
               key->key_create_info.comment.str,"INDEX COMMENT",
895 by Brian Aker
Completion (?) of uint conversion.
969
               (uint32_t) INDEX_COMMENT_MAXLEN);
1046.1.10 by Brian Aker
Formatting around return (style)
970
      return -1;
1 by brian
clean slate
971
    }
972
973
    key_info->comment.length= key->key_create_info.comment.length;
974
    if (key_info->comment.length > 0)
975
    {
976
      key_info->flags|= HA_USES_COMMENT;
977
      key_info->comment.str= key->key_create_info.comment.str;
978
    }
979
1215.1.2 by stewart at flamingspork
[patch 02/17] field NULL | NOT NULL in proto in parser. Only for CREATE TABLE. Change default in proto to reflect default in SQL.
980
    message::Table::Field *protofield= NULL;
981
1 by brian
clean slate
982
    List_iterator<Key_part_spec> cols(key->columns), cols2(key->columns);
482 by Brian Aker
Remove uint.
983
    for (uint32_t column_nr=0 ; (column=cols++) ; column_nr++)
1 by brian
clean slate
984
    {
482 by Brian Aker
Remove uint.
985
      uint32_t length;
1 by brian
clean slate
986
      Key_part_spec *dup_column;
1215.1.2 by stewart at flamingspork
[patch 02/17] field NULL | NOT NULL in proto in parser. Only for CREATE TABLE. Change default in proto to reflect default in SQL.
987
      int proto_field_nr= 0;
1 by brian
clean slate
988
989
      it.rewind();
990
      field=0;
1215.1.2 by stewart at flamingspork
[patch 02/17] field NULL | NOT NULL in proto in parser. Only for CREATE TABLE. Change default in proto to reflect default in SQL.
991
      while ((sql_field=it++) && ++proto_field_nr &&
1 by brian
clean slate
992
	     my_strcasecmp(system_charset_info,
993
			   column->field_name.str,
994
			   sql_field->field_name))
995
	field++;
996
      if (!sql_field)
997
      {
998
	my_error(ER_KEY_COLUMN_DOES_NOT_EXITS, MYF(0), column->field_name.str);
51.1.8 by Jay Pipes
Resolving conflicts for a few files regarding FALSE=>false
999
	return(true);
1 by brian
clean slate
1000
      }
1001
      while ((dup_column= cols2++) != column)
1002
      {
1003
        if (!my_strcasecmp(system_charset_info,
1233.1.3 by Brian Aker
Move more of the flags up to engine flags.
1004
                           column->field_name.str, dup_column->field_name.str))
1 by brian
clean slate
1005
	{
1006
	  my_printf_error(ER_DUP_FIELDNAME,
1007
			  ER(ER_DUP_FIELDNAME),MYF(0),
1008
			  column->field_name.str);
51.1.8 by Jay Pipes
Resolving conflicts for a few files regarding FALSE=>false
1009
	  return(true);
1 by brian
clean slate
1010
	}
1011
      }
1012
      cols2.rewind();
1215.1.2 by stewart at flamingspork
[patch 02/17] field NULL | NOT NULL in proto in parser. Only for CREATE TABLE. Change default in proto to reflect default in SQL.
1013
1320.1.3 by Brian Aker
More reference cleanup.
1014
      if (create_proto.field_size() > 0)
1015
        protofield= create_proto.mutable_field(proto_field_nr - 1);
1215.1.2 by stewart at flamingspork
[patch 02/17] field NULL | NOT NULL in proto in parser. Only for CREATE TABLE. Change default in proto to reflect default in SQL.
1016
1 by brian
clean slate
1017
      {
1119.9.10 by Jay Pipes
Removes FIELDFLAG_MAYBE_NULL and f_maybe_null() macro.
1018
        column->length*= sql_field->charset->mbmaxlen;
1 by brian
clean slate
1019
1119.9.10 by Jay Pipes
Removes FIELDFLAG_MAYBE_NULL and f_maybe_null() macro.
1020
        if (sql_field->sql_type == DRIZZLE_TYPE_BLOB)
1021
        {
1320.1.15 by Brian Aker
Remove old need for Cursor in creating table.
1022
          if (! (engine->check_flag(HTON_BIT_CAN_INDEX_BLOBS)))
1119.9.10 by Jay Pipes
Removes FIELDFLAG_MAYBE_NULL and f_maybe_null() macro.
1023
          {
1024
            my_error(ER_BLOB_USED_AS_KEY, MYF(0), column->field_name.str);
1025
            return true;
1026
          }
1027
          if (! column->length)
1028
          {
1029
            my_error(ER_BLOB_KEY_WITHOUT_LENGTH, MYF(0), column->field_name.str);
1030
            return true;
1031
          }
1032
        }
1033
        if (! (sql_field->flags & NOT_NULL_FLAG))
1034
        {
1035
          if (key->type == Key::PRIMARY)
1036
          {
1037
            /* Implicitly set primary key fields to NOT NULL for ISO conf. */
1038
            sql_field->flags|= NOT_NULL_FLAG;
1 by brian
clean slate
1039
            null_fields--;
1215.1.2 by stewart at flamingspork
[patch 02/17] field NULL | NOT NULL in proto in parser. Only for CREATE TABLE. Change default in proto to reflect default in SQL.
1040
1041
            if (protofield)
1042
            {
1043
              message::Table::Field::FieldConstraints *constraints;
1044
              constraints= protofield->mutable_constraints();
1045
              constraints->set_is_nullable(false);
1046
            }
1047
1119.9.10 by Jay Pipes
Removes FIELDFLAG_MAYBE_NULL and f_maybe_null() macro.
1048
          }
1049
          else
1 by brian
clean slate
1050
          {
1051
            key_info->flags|= HA_NULL_PART_KEY;
1320.1.15 by Brian Aker
Remove old need for Cursor in creating table.
1052
            if (! (engine->check_flag(HTON_BIT_NULL_IN_KEY)))
1 by brian
clean slate
1053
            {
1054
              my_error(ER_NULL_COLUMN_IN_INDEX, MYF(0), column->field_name.str);
1119.9.10 by Jay Pipes
Removes FIELDFLAG_MAYBE_NULL and f_maybe_null() macro.
1055
              return true;
1 by brian
clean slate
1056
            }
1057
          }
1119.9.10 by Jay Pipes
Removes FIELDFLAG_MAYBE_NULL and f_maybe_null() macro.
1058
        }
1059
        if (MTYP_TYPENR(sql_field->unireg_check) == Field::NEXT_NUMBER)
1060
        {
1320.1.15 by Brian Aker
Remove old need for Cursor in creating table.
1061
          if (column_nr == 0 || (engine->check_flag(HTON_BIT_AUTO_PART_KEY)))
1119.9.10 by Jay Pipes
Removes FIELDFLAG_MAYBE_NULL and f_maybe_null() macro.
1062
            auto_increment--;			// Field is used
1063
        }
1 by brian
clean slate
1064
      }
1065
1066
      key_part_info->fieldnr= field;
206 by Brian Aker
Removed final uint dead types.
1067
      key_part_info->offset=  (uint16_t) sql_field->offset;
1 by brian
clean slate
1068
      key_part_info->key_type=sql_field->pack_flag;
1069
      length= sql_field->key_length;
1070
1071
      if (column->length)
1072
      {
1119.9.2 by Jay Pipes
Phase I removal of FIELDFLAG_BLOB. This is a piece of poop.
1073
	if (sql_field->sql_type == DRIZZLE_TYPE_BLOB)
1 by brian
clean slate
1074
	{
1075
	  if ((length=column->length) > max_key_length ||
1320.1.15 by Brian Aker
Remove old need for Cursor in creating table.
1076
	      length > engine->max_key_part_length())
1 by brian
clean slate
1077
	  {
1320.1.15 by Brian Aker
Remove old need for Cursor in creating table.
1078
	    length= min(max_key_length, engine->max_key_part_length());
1 by brian
clean slate
1079
	    if (key->type == Key::MULTIPLE)
1080
	    {
1081
	      /* not a critical problem */
261.4.1 by Felipe
- Renamed MYSQL_ERROR to DRIZZLE_ERROR.
1082
	      char warn_buff[DRIZZLE_ERRMSG_SIZE];
77.1.18 by Monty Taylor
Removed my_vsnprintf and my_snprintf.
1083
	      snprintf(warn_buff, sizeof(warn_buff), ER(ER_TOO_LONG_KEY),
1084
                       length);
520.1.22 by Brian Aker
Second pass of thd cleanup
1085
	      push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
1 by brian
clean slate
1086
			   ER_TOO_LONG_KEY, warn_buff);
1087
              /* Align key length to multibyte char boundary */
1088
              length-= length % sql_field->charset->mbmaxlen;
1089
	    }
1090
	    else
1091
	    {
1092
	      my_error(ER_TOO_LONG_KEY,MYF(0),length);
51.1.8 by Jay Pipes
Resolving conflicts for a few files regarding FALSE=>false
1093
	      return(true);
1 by brian
clean slate
1094
	    }
1095
	  }
1096
	}
1097
	else if ((column->length > length ||
1119.9.11 by Jay Pipes
Removes f_is_packed() macro and FIELDFLAG_PACK
1098
            ! Field::type_can_have_key_part(sql_field->sql_type)))
1 by brian
clean slate
1099
	{
1100
	  my_message(ER_WRONG_SUB_KEY, ER(ER_WRONG_SUB_KEY), MYF(0));
51.1.8 by Jay Pipes
Resolving conflicts for a few files regarding FALSE=>false
1101
	  return(true);
1 by brian
clean slate
1102
	}
1320.1.15 by Brian Aker
Remove old need for Cursor in creating table.
1103
	else if (! (engine->check_flag(HTON_BIT_NO_PREFIX_CHAR_KEYS)))
1233.1.7 by Brian Aker
Final table flag removal.
1104
        {
1 by brian
clean slate
1105
	  length=column->length;
1233.1.7 by Brian Aker
Final table flag removal.
1106
        }
1 by brian
clean slate
1107
      }
1108
      else if (length == 0)
1109
      {
1110
	my_error(ER_WRONG_KEY_COLUMN, MYF(0), column->field_name.str);
51.1.8 by Jay Pipes
Resolving conflicts for a few files regarding FALSE=>false
1111
	  return(true);
1 by brian
clean slate
1112
      }
1320.1.15 by Brian Aker
Remove old need for Cursor in creating table.
1113
      if (length > engine->max_key_part_length())
1 by brian
clean slate
1114
      {
1320.1.15 by Brian Aker
Remove old need for Cursor in creating table.
1115
        length= engine->max_key_part_length();
1 by brian
clean slate
1116
	if (key->type == Key::MULTIPLE)
1117
	{
1118
	  /* not a critical problem */
261.4.1 by Felipe
- Renamed MYSQL_ERROR to DRIZZLE_ERROR.
1119
	  char warn_buff[DRIZZLE_ERRMSG_SIZE];
77.1.18 by Monty Taylor
Removed my_vsnprintf and my_snprintf.
1120
	  snprintf(warn_buff, sizeof(warn_buff), ER(ER_TOO_LONG_KEY),
1121
                   length);
520.1.22 by Brian Aker
Second pass of thd cleanup
1122
	  push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
1 by brian
clean slate
1123
		       ER_TOO_LONG_KEY, warn_buff);
1124
          /* Align key length to multibyte char boundary */
1125
          length-= length % sql_field->charset->mbmaxlen;
1126
	}
1127
	else
1128
	{
1129
	  my_error(ER_TOO_LONG_KEY,MYF(0),length);
51.1.8 by Jay Pipes
Resolving conflicts for a few files regarding FALSE=>false
1130
	  return(true);
1 by brian
clean slate
1131
	}
1132
      }
206 by Brian Aker
Removed final uint dead types.
1133
      key_part_info->length=(uint16_t) length;
1 by brian
clean slate
1134
      /* Use packed keys for long strings on the first column */
1135
      if (!((*db_options) & HA_OPTION_NO_PACK_KEYS) &&
1136
	  (length >= KEY_DEFAULT_PACK_LENGTH &&
241 by Brian Aker
First pass of CHAR removal.
1137
	   (sql_field->sql_type == DRIZZLE_TYPE_VARCHAR ||
1119.9.2 by Jay Pipes
Phase I removal of FIELDFLAG_BLOB. This is a piece of poop.
1138
      sql_field->sql_type == DRIZZLE_TYPE_BLOB)))
1 by brian
clean slate
1139
      {
1119.9.2 by Jay Pipes
Phase I removal of FIELDFLAG_BLOB. This is a piece of poop.
1140
        if ((column_nr == 0 && sql_field->sql_type == DRIZZLE_TYPE_BLOB) ||
212.2.2 by Patrick Galbraith
Renamed FIELD_TYPE to DRIZZLE_TYPE
1141
            sql_field->sql_type == DRIZZLE_TYPE_VARCHAR)
1119.9.2 by Jay Pipes
Phase I removal of FIELDFLAG_BLOB. This is a piece of poop.
1142
          key_info->flags|= HA_BINARY_PACK_KEY | HA_VAR_LENGTH_KEY;
1143
        else
1144
          key_info->flags|= HA_PACK_KEY;
1 by brian
clean slate
1145
      }
1146
      /* Check if the key segment is partial, set the key flag accordingly */
1147
      if (length != sql_field->key_length)
1148
        key_info->flags|= HA_KEY_HAS_PART_KEY_SEG;
1149
1150
      key_length+=length;
1151
      key_part_info++;
1152
1153
      /* Create the key name based on the first column (if not given) */
1154
      if (column_nr == 0)
1155
      {
1156
	if (key->type == Key::PRIMARY)
1157
	{
1158
	  if (primary_key)
1159
	  {
1160
	    my_message(ER_MULTIPLE_PRI_KEY, ER(ER_MULTIPLE_PRI_KEY),
1161
                       MYF(0));
51.1.8 by Jay Pipes
Resolving conflicts for a few files regarding FALSE=>false
1162
	    return(true);
1 by brian
clean slate
1163
	  }
590.1.1 by Stewart Smith
begin moving from global const char* primary_key_name to methods is_primary_key() and is_primary_key_name()
1164
          static const char pkey_name[]= "PRIMARY";
1165
	  key_name=pkey_name;
1 by brian
clean slate
1166
	  primary_key=1;
1167
	}
1168
	else if (!(key_name= key->name.str))
1169
	  key_name=make_unique_key_name(sql_field->field_name,
1170
					*key_info_buffer, key_info);
1171
	if (check_if_keyname_exists(key_name, *key_info_buffer, key_info))
1172
	{
1173
	  my_error(ER_DUP_KEYNAME, MYF(0), key_name);
51.1.8 by Jay Pipes
Resolving conflicts for a few files regarding FALSE=>false
1174
	  return(true);
1 by brian
clean slate
1175
	}
1176
	key_info->name=(char*) key_name;
1177
      }
1178
    }
1179
    if (!key_info->name || check_column_name(key_info->name))
1180
    {
1181
      my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0), key_info->name);
51.1.8 by Jay Pipes
Resolving conflicts for a few files regarding FALSE=>false
1182
      return(true);
1 by brian
clean slate
1183
    }
1184
    if (!(key_info->flags & HA_NULL_PART_KEY))
1185
      unique_key=1;
206 by Brian Aker
Removed final uint dead types.
1186
    key_info->key_length=(uint16_t) key_length;
1 by brian
clean slate
1187
    if (key_length > max_key_length)
1188
    {
1189
      my_error(ER_TOO_LONG_KEY,MYF(0),max_key_length);
51.1.8 by Jay Pipes
Resolving conflicts for a few files regarding FALSE=>false
1190
      return(true);
1 by brian
clean slate
1191
    }
1192
    key_info++;
1193
  }
1194
  if (!unique_key && !primary_key &&
1320.1.15 by Brian Aker
Remove old need for Cursor in creating table.
1195
      (engine->check_flag(HTON_BIT_REQUIRE_PRIMARY_KEY)))
1 by brian
clean slate
1196
  {
1197
    my_message(ER_REQUIRES_PRIMARY_KEY, ER(ER_REQUIRES_PRIMARY_KEY), MYF(0));
51.1.8 by Jay Pipes
Resolving conflicts for a few files regarding FALSE=>false
1198
    return(true);
1 by brian
clean slate
1199
  }
1200
  if (auto_increment > 0)
1201
  {
1202
    my_message(ER_WRONG_AUTO_KEY, ER(ER_WRONG_AUTO_KEY), MYF(0));
51.1.8 by Jay Pipes
Resolving conflicts for a few files regarding FALSE=>false
1203
    return(true);
1 by brian
clean slate
1204
  }
1205
  /* Sort keys in optimized order */
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
1206
  internal::my_qsort((unsigned char*) *key_info_buffer, *key_count, sizeof(KEY),
1207
	             (qsort_cmp) sort_keys);
1 by brian
clean slate
1208
1209
  /* Check fields. */
1210
  it.rewind();
1211
  while ((sql_field=it++))
1212
  {
1213
    Field::utype type= (Field::utype) MTYP_TYPENR(sql_field->unireg_check);
1214
520.1.22 by Brian Aker
Second pass of thd cleanup
1215
    if (session->variables.sql_mode & MODE_NO_ZERO_DATE &&
1 by brian
clean slate
1216
        !sql_field->def &&
212.2.2 by Patrick Galbraith
Renamed FIELD_TYPE to DRIZZLE_TYPE
1217
        sql_field->sql_type == DRIZZLE_TYPE_TIMESTAMP &&
1 by brian
clean slate
1218
        (sql_field->flags & NOT_NULL_FLAG) &&
1219
        (type == Field::NONE || type == Field::TIMESTAMP_UN_FIELD))
1220
    {
1221
      /*
1222
        An error should be reported if:
1223
          - NO_ZERO_DATE SQL mode is active;
1224
          - there is no explicit DEFAULT clause (default column value);
1225
          - this is a TIMESTAMP column;
1226
          - the column is not NULL;
1227
          - this is not the DEFAULT CURRENT_TIMESTAMP column.
1228
1229
        In other words, an error should be reported if
1230
          - NO_ZERO_DATE SQL mode is active;
1231
          - the column definition is equivalent to
1232
            'column_name TIMESTAMP DEFAULT 0'.
1233
      */
1234
1235
      my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name);
51.1.8 by Jay Pipes
Resolving conflicts for a few files regarding FALSE=>false
1236
      return(true);
1 by brian
clean slate
1237
    }
1238
  }
1239
51.1.8 by Jay Pipes
Resolving conflicts for a few files regarding FALSE=>false
1240
  return(false);
1 by brian
clean slate
1241
}
1242
1243
/*
1244
  Extend long VARCHAR fields to blob & prepare field if it's a blob
1245
1246
  SYNOPSIS
1247
    prepare_blob_field()
1248
    sql_field		Field to check
1249
1250
  RETURN
1251
    0	ok
1252
    1	Error (sql_field can't be converted to blob)
1253
        In this case the error is given
1254
*/
1255
779.1.27 by Monty Taylor
Got rid of __attribute__((unused)) and the like from the .cc files.
1256
static bool prepare_blob_field(Session *,
1052.2.3 by Nathan Williams
No actual code changes. Changed Create_field to CreateField to be consistent with coding standards.
1257
                               CreateField *sql_field)
1 by brian
clean slate
1258
{
1259
1260
  if (sql_field->length > MAX_FIELD_VARCHARLENGTH &&
1261
      !(sql_field->flags & BLOB_FLAG))
1262
  {
1263
    my_error(ER_TOO_BIG_FIELDLENGTH, MYF(0), sql_field->field_name,
1264
             MAX_FIELD_VARCHARLENGTH / sql_field->charset->mbmaxlen);
1046.1.10 by Brian Aker
Formatting around return (style)
1265
    return 1;
1 by brian
clean slate
1266
  }
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1267
1 by brian
clean slate
1268
  if ((sql_field->flags & BLOB_FLAG) && sql_field->length)
1269
  {
212.2.2 by Patrick Galbraith
Renamed FIELD_TYPE to DRIZZLE_TYPE
1270
    if (sql_field->sql_type == DRIZZLE_TYPE_BLOB)
1 by brian
clean slate
1271
    {
1272
      /* The user has given a length to the blob column */
1273
      sql_field->pack_length= calc_pack_length(sql_field->sql_type, 0);
1274
    }
1275
    sql_field->length= 0;
1276
  }
1046.1.10 by Brian Aker
Formatting around return (style)
1277
  return 0;
1 by brian
clean slate
1278
}
1279
1280
1281
/*
1039.1.11 by Brian Aker
Refactor function to make sense.
1282
  Ignore the name of this function... it locks :(
1283
1 by brian
clean slate
1284
  Create a table
1285
1286
  SYNOPSIS
1287
    mysql_create_table_no_lock()
520.1.22 by Brian Aker
Second pass of thd cleanup
1288
    session			Thread object
1 by brian
clean slate
1289
    db			Database
1290
    table_name		Table name
1291
    create_info	        Create information (like MAX_ROWS)
1292
    fields		List of fields to create
1293
    keys		List of keys to create
1294
    internal_tmp_table  Set to 1 if this is an internal temporary table
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
1295
			(From ALTER Table)
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1296
    select_field_count
1 by brian
clean slate
1297
1298
  DESCRIPTION
1299
    If one creates a temporary table, this is automatically opened
1300
1301
    Note that this function assumes that caller already have taken
1302
    name-lock on table being created or used some other way to ensure
1303
    that concurrent operations won't intervene. mysql_create_table()
1304
    is a wrapper that can be used for this.
1305
1306
  RETURN VALUES
55 by brian
Update for using real bool types.
1307
    false OK
1308
    true  error
1 by brian
clean slate
1309
*/
1310
520.1.22 by Brian Aker
Second pass of thd cleanup
1311
bool mysql_create_table_no_lock(Session *session,
1223.4.3 by Brian Aker
More identifier work.
1312
                                TableIdentifier &identifier,
1 by brian
clean slate
1313
                                HA_CREATE_INFO *create_info,
1320.1.1 by Brian Aker
Light cleanup for references.
1314
				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.
1315
                                AlterInfo *alter_info,
1 by brian
clean slate
1316
                                bool internal_tmp_table,
1235.2.1 by Brian Aker
More identifier work.
1317
                                uint32_t select_field_count,
1222.2.3 by Brian Aker
Remove a few more options, from options in HA_CREATE_INFO.
1318
                                bool is_if_not_exists)
1 by brian
clean slate
1319
{
1320
  uint		db_options, key_count;
1321
  KEY		*key_info_buffer;
55 by brian
Update for using real bool types.
1322
  bool		error= true;
1208.3.2 by brian
Update for Cursor renaming.
1323
  TableShare share;
1235.2.1 by Brian Aker
More identifier work.
1324
  bool lex_identified_temp_table=
1320.1.1 by Brian Aker
Light cleanup for references.
1325
    (table_proto.type() == message::Table::TEMPORARY);
1208.3.2 by brian
Update for Cursor renaming.
1326
1 by brian
clean slate
1327
  /* Check for duplicate fields and check type of table to create */
1320.1.8 by Brian Aker
Temporary fix for allowing engines to say "don't do this".
1328
  if (not alter_info->create_list.elements)
1 by brian
clean slate
1329
  {
1330
    my_message(ER_TABLE_MUST_HAVE_COLUMNS, ER(ER_TABLE_MUST_HAVE_COLUMNS),
1331
               MYF(0));
1039.1.11 by Brian Aker
Refactor function to make sense.
1332
    return true;
1 by brian
clean slate
1333
  }
1320.1.1 by Brian Aker
Light cleanup for references.
1334
  assert(strcmp(identifier.getTableName(), table_proto.name().c_str())==0);
1 by brian
clean slate
1335
  db_options= create_info->table_options;
1320.1.15 by Brian Aker
Remove old need for Cursor in creating table.
1336
1 by brian
clean slate
1337
  if (create_info->row_type == ROW_TYPE_DYNAMIC)
1338
    db_options|=HA_OPTION_PACK_RECORD;
1339
1223.4.3 by Brian Aker
More identifier work.
1340
  set_table_default_charset(create_info, identifier.getDBName());
1 by brian
clean slate
1341
1223.4.2 by Brian Aker
Extended mysql_create_table_no_lock to use TableIdentifier
1342
  /* Check if table exists */
1320.1.3 by Brian Aker
More reference cleanup.
1343
  if (mysql_prepare_create_table(session, create_info, table_proto, alter_info,
1 by brian
clean slate
1344
                                 internal_tmp_table,
1320.1.15 by Brian Aker
Remove old need for Cursor in creating table.
1345
                                 &db_options,
1054.1.11 by Brian Aker
Remove dead lock.cc commands.
1346
                                 &key_info_buffer, &key_count,
1347
                                 select_field_count))
1 by brian
clean slate
1348
    goto err;
1349
1350
  /* Check if table already exists */
1222.2.1 by Brian Aker
Takes the majority usage of parser based HA_CREATE_INFO usage around
1351
  if (lex_identified_temp_table &&
1223.4.3 by Brian Aker
More identifier work.
1352
      session->find_temporary_table(identifier.getDBName(), identifier.getTableName()))
1 by brian
clean slate
1353
  {
1222.2.3 by Brian Aker
Remove a few more options, from options in HA_CREATE_INFO.
1354
    if (is_if_not_exists)
1 by brian
clean slate
1355
    {
1356
      create_info->table_existed= 1;		// Mark that table existed
520.1.22 by Brian Aker
Second pass of thd cleanup
1357
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
1 by brian
clean slate
1358
                          ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR),
1223.4.3 by Brian Aker
More identifier work.
1359
                          identifier.getTableName());
1 by brian
clean slate
1360
      error= 0;
1361
      goto err;
1362
    }
1223.4.3 by Brian Aker
More identifier work.
1363
    my_error(ER_TABLE_EXISTS_ERROR, MYF(0), identifier.getTableName());
1 by brian
clean slate
1364
    goto err;
1365
  }
1366
1046.1.2 by Brian Aker
Comments on LOCK_open
1367
  pthread_mutex_lock(&LOCK_open); /* CREATE TABLE (some confussion on naming, double check) */
1273.19.11 by Brian Aker
This restores temporary tables back to being viewable via show/select.
1368
  if (not internal_tmp_table && not lex_identified_temp_table)
1 by brian
clean slate
1369
  {
1273.19.11 by Brian Aker
This restores temporary tables back to being viewable via show/select.
1370
    if (plugin::StorageEngine::doesTableExist(*session,
1371
                                              identifier, false)==EEXIST)
1 by brian
clean slate
1372
    {
1222.2.3 by Brian Aker
Remove a few more options, from options in HA_CREATE_INFO.
1373
      if (is_if_not_exists)
1039.1.11 by Brian Aker
Refactor function to make sense.
1374
      {
1375
        error= false;
1376
        push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
1377
                            ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR),
1223.4.3 by Brian Aker
More identifier work.
1378
                            identifier.getTableName());
1039.1.11 by Brian Aker
Refactor function to make sense.
1379
        create_info->table_existed= 1;		// Mark that table existed
1380
      }
1381
      else 
1273.19.11 by Brian Aker
This restores temporary tables back to being viewable via show/select.
1382
      {
1223.4.3 by Brian Aker
More identifier work.
1383
        my_error(ER_TABLE_EXISTS_ERROR, MYF(0), identifier.getTableName());
1273.19.11 by Brian Aker
This restores temporary tables back to being viewable via show/select.
1384
      }
1039.1.11 by Brian Aker
Refactor function to make sense.
1385
1 by brian
clean slate
1386
      goto unlock_and_end;
1387
    }
1388
    /*
1389
      We don't assert here, but check the result, because the table could be
1390
      in the table definition cache and in the same time the .frm could be
1391
      missing from the disk, in case of manual intervention which deletes
1208.3.2 by brian
Update for Cursor renaming.
1392
      the .frm cursor. The user has to use FLUSH TABLES; to clear the cache.
1 by brian
clean slate
1393
      Then she could create the table. This case is pretty obscure and
1394
      therefore we don't introduce a new error message only for it.
1395
    */
1223.4.3 by Brian Aker
More identifier work.
1396
    if (TableShare::getShare(identifier.getDBName(), identifier.getTableName()))
1 by brian
clean slate
1397
    {
1223.4.3 by Brian Aker
More identifier work.
1398
      my_error(ER_TABLE_EXISTS_ERROR, MYF(0), identifier.getTableName());
1 by brian
clean slate
1399
      goto unlock_and_end;
1400
    }
1401
  }
1402
1403
  /*
1404
    Check that table with given name does not already
1405
    exist in any storage engine. In such a case it should
1406
    be discovered and the error ER_TABLE_EXISTS_ERROR be returned
1407
    unless user specified CREATE TABLE IF EXISTS
1408
    The LOCK_open mutex has been locked to make sure no
1409
    one else is attempting to discover the table. Since
1208.3.2 by brian
Update for Cursor renaming.
1410
    it's not on disk as a frm cursor, no one could be using it!
1 by brian
clean slate
1411
  */
1273.19.11 by Brian Aker
This restores temporary tables back to being viewable via show/select.
1412
  if (not lex_identified_temp_table)
1 by brian
clean slate
1413
  {
1273.19.11 by Brian Aker
This restores temporary tables back to being viewable via show/select.
1414
    bool exists= plugin::StorageEngine::doesTableExist(*session, identifier, false);
1223.4.18 by Brian Aker
More TableIdentifier code.
1415
1273.19.11 by Brian Aker
This restores temporary tables back to being viewable via show/select.
1416
    if (exists)
1 by brian
clean slate
1417
    {
1273.19.11 by Brian Aker
This restores temporary tables back to being viewable via show/select.
1418
      if (is_if_not_exists)
1419
      {
1420
        error= false;
1421
        push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
1422
                            ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR),
1423
                            identifier.getTableName());
1424
        create_info->table_existed= 1;		// Mark that table existed
1425
        goto unlock_and_end;
1426
      }
1427
1428
      my_error(ER_TABLE_EXISTS_ERROR, MYF(0), identifier.getTableName());
1429
      goto unlock_and_end;
1 by brian
clean slate
1430
    }
1431
  }
1432
520.1.22 by Brian Aker
Second pass of thd cleanup
1433
  session->set_proc_info("creating table");
1 by brian
clean slate
1434
  create_info->table_existed= 0;		// Mark that table is created
1435
1237.6.12 by Brian Aker
Adding patch for engine methods for definition files.
1436
  create_info->table_options= db_options;
1 by brian
clean slate
1437
1223.4.8 by Brian Aker
More table identifier love :)
1438
  if (rea_create_table(session, identifier,
1008.3.20 by Stewart Smith
Put table_name into table proto in parser, and use that when creating table proto file.
1439
		       table_proto,
1 by brian
clean slate
1440
                       create_info, alter_info->create_list,
1095.3.8 by Stewart Smith
refactor rea_create_table to only have one call to create_table_proto_file and not have a is_like parameter which was only used in one place
1441
                       key_count, key_info_buffer))
1273.19.11 by Brian Aker
This restores temporary tables back to being viewable via show/select.
1442
  {
1 by brian
clean slate
1443
    goto unlock_and_end;
1273.19.11 by Brian Aker
This restores temporary tables back to being viewable via show/select.
1444
  }
1 by brian
clean slate
1445
1222.2.1 by Brian Aker
Takes the majority usage of parser based HA_CREATE_INFO usage around
1446
  if (lex_identified_temp_table)
1 by brian
clean slate
1447
  {
1448
    /* Open table and put in temporary table list */
1273.19.11 by Brian Aker
This restores temporary tables back to being viewable via show/select.
1449
    if (not (session->open_temporary_table(identifier)))
1 by brian
clean slate
1450
    {
1320.1.10 by Brian Aker
Additional pass through doDropTable()
1451
      (void) session->rm_temporary_table(identifier);
1 by brian
clean slate
1452
      goto unlock_and_end;
1453
    }
1454
  }
1455
1273.19.11 by Brian Aker
This restores temporary tables back to being viewable via show/select.
1456
  if (not internal_tmp_table && not lex_identified_temp_table)
1308.2.11 by Jay Pipes
* Adds CREATE TABLE as a specific CreateTableStatement message in the
1457
  {
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
1458
    TransactionServices &transaction_services= TransactionServices::singleton();
1459
    transaction_services.createTable(session, table_proto);
1308.2.11 by Jay Pipes
* Adds CREATE TABLE as a specific CreateTableStatement message in the
1460
  }
55 by brian
Update for using real bool types.
1461
  error= false;
1 by brian
clean slate
1462
unlock_and_end:
1039.1.11 by Brian Aker
Refactor function to make sense.
1463
  pthread_mutex_unlock(&LOCK_open);
1 by brian
clean slate
1464
1465
err:
520.1.22 by Brian Aker
Second pass of thd cleanup
1466
  session->set_proc_info("After create");
1273.19.11 by Brian Aker
This restores temporary tables back to being viewable via show/select.
1467
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
1468
  return(error);
1 by brian
clean slate
1469
}
1470
1471
1472
/*
1473
  Database locking aware wrapper for mysql_create_table_no_lock(),
1474
*/
1475
1223.4.1 by Brian Aker
Table Identifier patch.
1476
bool mysql_create_table(Session *session,
1477
                        TableIdentifier &identifier,
1 by brian
clean slate
1478
                        HA_CREATE_INFO *create_info,
1320.1.2 by Brian Aker
More reference counting.
1479
			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.
1480
                        AlterInfo *alter_info,
1 by brian
clean slate
1481
                        bool internal_tmp_table,
1222.2.3 by Brian Aker
Remove a few more options, from options in HA_CREATE_INFO.
1482
                        uint32_t select_field_count,
1483
                        bool is_if_not_exists)
1 by brian
clean slate
1484
{
1054.1.11 by Brian Aker
Remove dead lock.cc commands.
1485
  Table *name_lock= NULL;
1 by brian
clean slate
1486
  bool result;
1222.2.1 by Brian Aker
Takes the majority usage of parser based HA_CREATE_INFO usage around
1487
  bool lex_identified_temp_table=
1320.1.2 by Brian Aker
More reference counting.
1488
    (table_proto.type() == message::Table::TEMPORARY);
1 by brian
clean slate
1489
1320.1.2 by Brian Aker
More reference counting.
1490
  if (not lex_identified_temp_table)
1 by brian
clean slate
1491
  {
1223.4.1 by Brian Aker
Table Identifier patch.
1492
    if (session->lock_table_name_if_not_cached(identifier.getDBName(),
1493
                                               identifier.getTableName(),
1494
                                               &name_lock))
1 by brian
clean slate
1495
    {
55 by brian
Update for using real bool types.
1496
      result= true;
1 by brian
clean slate
1497
      goto unlock;
1498
    }
1054.1.11 by Brian Aker
Remove dead lock.cc commands.
1499
    if (name_lock == NULL)
1 by brian
clean slate
1500
    {
1222.2.3 by Brian Aker
Remove a few more options, from options in HA_CREATE_INFO.
1501
      if (is_if_not_exists)
1 by brian
clean slate
1502
      {
520.1.22 by Brian Aker
Second pass of thd cleanup
1503
        push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
1 by brian
clean slate
1504
                            ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR),
1223.4.1 by Brian Aker
Table Identifier patch.
1505
                            identifier.getTableName());
1 by brian
clean slate
1506
        create_info->table_existed= 1;
55 by brian
Update for using real bool types.
1507
        result= false;
1 by brian
clean slate
1508
      }
1509
      else
1510
      {
1223.4.1 by Brian Aker
Table Identifier patch.
1511
        my_error(ER_TABLE_EXISTS_ERROR, MYF(0), identifier.getTableName());
55 by brian
Update for using real bool types.
1512
        result= true;
1 by brian
clean slate
1513
      }
1514
      goto unlock;
1515
    }
1516
  }
1517
1223.4.12 by Brian Aker
Modified internal loop so that identifier is now used from top to bottom.
1518
  result= mysql_create_table_no_lock(session,
1519
                                     identifier,
1520
                                     create_info,
1320.1.2 by Brian Aker
More reference counting.
1521
                                     table_proto,
1223.4.12 by Brian Aker
Modified internal loop so that identifier is now used from top to bottom.
1522
                                     alter_info,
1523
                                     internal_tmp_table,
1524
                                     select_field_count,
1525
                                     is_if_not_exists);
1 by brian
clean slate
1526
1527
unlock:
1528
  if (name_lock)
1529
  {
1046.1.2 by Brian Aker
Comments on LOCK_open
1530
    pthread_mutex_lock(&LOCK_open); /* Lock for removing name_lock during table create */
1054.1.9 by Brian Aker
This is a large number of refactors against the Session class for its
1531
    session->unlink_open_table(name_lock);
1 by brian
clean slate
1532
    pthread_mutex_unlock(&LOCK_open);
1533
  }
1053 by Brian Aker
Merge Stewart, fix LOCK (it was dead, only for dead RENAME SCHEMA code), and
1534
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
1535
  return(result);
1 by brian
clean slate
1536
}
1537
1538
1539
/*
1540
** Give the key name after the first field with an optional '_#' after
1541
**/
1542
1543
static bool
1544
check_if_keyname_exists(const char *name, KEY *start, KEY *end)
1545
{
1546
  for (KEY *key=start ; key != end ; key++)
1547
    if (!my_strcasecmp(system_charset_info,name,key->name))
1548
      return 1;
1549
  return 0;
1550
}
1551
1552
1553
static char *
1554
make_unique_key_name(const char *field_name,KEY *start,KEY *end)
1555
{
1556
  char buff[MAX_FIELD_NAME],*buff_end;
1557
1558
  if (!check_if_keyname_exists(field_name,start,end) &&
590.1.1 by Stewart Smith
begin moving from global const char* primary_key_name to methods is_primary_key() and is_primary_key_name()
1559
      !is_primary_key_name(field_name))
1 by brian
clean slate
1560
    return (char*) field_name;			// Use fieldname
629.5.3 by Toru Maesaka
Third pass of replacing MySQL's strmake() with libc calls
1561
1562
  buff_end= strncpy(buff, field_name, sizeof(buff)-4);
1563
  buff_end+= strlen(buff);
1 by brian
clean slate
1564
1565
  /*
1566
    Only 3 chars + '\0' left, so need to limit to 2 digit
1567
    This is ok as we can't have more than 100 keys anyway
1568
  */
482 by Brian Aker
Remove uint.
1569
  for (uint32_t i=2 ; i< 100; i++)
1 by brian
clean slate
1570
  {
1571
    *buff_end= '_';
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
1572
    internal::int10_to_str(i, buff_end+1, 10);
1 by brian
clean slate
1573
    if (!check_if_keyname_exists(buff,start,end))
1253.1.6 by Monty Taylor
Moved mem_root functions into drizzled::memory:: namespace.
1574
      return memory::sql_strdup(buff);
1 by brian
clean slate
1575
  }
1576
  return (char*) "not_specified";		// Should never happen
1577
}
1578
1579
1580
/****************************************************************************
1581
** Alter a table definition
1582
****************************************************************************/
1583
1584
/*
1585
  Rename a table.
1586
1587
  SYNOPSIS
1588
    mysql_rename_table()
1130.1.4 by Monty Taylor
Moved StorageEngine into plugin namespace.
1589
      base                      The plugin::StorageEngine handle.
1 by brian
clean slate
1590
      old_db                    The old database name.
1591
      old_name                  The old table name.
1592
      new_db                    The new database name.
1593
      new_name                  The new table name.
1594
      flags                     flags for build_table_filename().
1595
                                FN_FROM_IS_TMP old_name is temporary.
1596
                                FN_TO_IS_TMP   new_name is temporary.
1597
1598
  RETURN
55 by brian
Update for using real bool types.
1599
    false   OK
1600
    true    Error
1 by brian
clean slate
1601
*/
1602
1603
bool
1130.1.4 by Monty Taylor
Moved StorageEngine into plugin namespace.
1604
mysql_rename_table(plugin::StorageEngine *base, const char *old_db,
1 by brian
clean slate
1605
                   const char *old_name, const char *new_db,
482 by Brian Aker
Remove uint.
1606
                   const char *new_name, uint32_t flags)
1 by brian
clean slate
1607
{
520.1.22 by Brian Aker
Second pass of thd cleanup
1608
  Session *session= current_session;
1358.1.5 by Brian Aker
Cleans up use of static buffer in TableIdentifier.
1609
  string from;
1610
  string to;
1039.1.11 by Brian Aker
Refactor function to make sense.
1611
  int error= 0;
1 by brian
clean slate
1612
1039.3.10 by Stewart Smith
move ha_rename_table to just be StorageEngine::renameTable with engines implementing renameTableImpl.
1613
  assert(base);
1 by brian
clean slate
1614
1358.1.5 by Brian Aker
Cleans up use of static buffer in TableIdentifier.
1615
  build_table_filename(from, old_db, old_name,
1 by brian
clean slate
1616
                       flags & FN_FROM_IS_TMP);
1358.1.5 by Brian Aker
Cleans up use of static buffer in TableIdentifier.
1617
  build_table_filename(to, new_db, new_name,
1 by brian
clean slate
1618
                       flags & FN_TO_IS_TMP);
1619
1358.1.5 by Brian Aker
Cleans up use of static buffer in TableIdentifier.
1620
  if (!(error= base->renameTable(session, from.c_str(), to.c_str())))
1 by brian
clean slate
1621
  {
1223.4.13 by Brian Aker
Small shift in alter table (break the baby down...).
1622
    if (base->check_flag(HTON_BIT_HAS_DATA_DICTIONARY) == 0
1358.1.5 by Brian Aker
Cleans up use of static buffer in TableIdentifier.
1623
       && rename_table_proto_file(from.c_str(), to.c_str()))
584.2.7 by Stewart Smith
rename and delete tabledefinition protobuf file
1624
    {
1241.9.57 by Monty Taylor
Oy. Bigger change than I normally like - but this stuff is all intertwined.
1625
      error= errno;
1358.1.5 by Brian Aker
Cleans up use of static buffer in TableIdentifier.
1626
      base->renameTable(session, to.c_str(), from.c_str());
584.2.7 by Stewart Smith
rename and delete tabledefinition protobuf file
1627
    }
1 by brian
clean slate
1628
  }
1039.3.11 by Stewart Smith
fix build error in mysql_rename_table: forgot to remove old dead code.
1629
1 by brian
clean slate
1630
  if (error == HA_ERR_WRONG_COMMAND)
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
1631
    my_error(ER_NOT_SUPPORTED_YET, MYF(0), "ALTER Table");
1 by brian
clean slate
1632
  else if (error)
1358.1.5 by Brian Aker
Cleans up use of static buffer in TableIdentifier.
1633
    my_error(ER_ERROR_ON_RENAME, MYF(0), from.c_str(), to.c_str(), error);
1634
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
1635
  return(error != 0);
1 by brian
clean slate
1636
}
1637
1638
1639
/*
1640
  Force all other threads to stop using the table
1641
1642
  SYNOPSIS
1643
    wait_while_table_is_used()
1183.1.2 by Brian Aker
Rename of handler to Cursor. You would not believe how long I have wanted
1644
    session			Thread Cursor
1 by brian
clean slate
1645
    table		Table to remove from cache
1646
    function            HA_EXTRA_PREPARE_FOR_DROP if table is to be deleted
1647
                        HA_EXTRA_FORCE_REOPEN if table is not be used
1648
                        HA_EXTRA_PREPARE_FOR_RENAME if table is to be renamed
1649
  NOTES
1650
   When returning, the table will be unusable for other threads until
1651
   the table is closed.
1652
1653
  PREREQUISITES
1654
    Lock on LOCK_open
1655
    Win32 clients must also have a WRITE LOCK on the table !
1656
*/
1657
520.1.22 by Brian Aker
Second pass of thd cleanup
1658
void wait_while_table_is_used(Session *session, Table *table,
1 by brian
clean slate
1659
                              enum ha_extra_function function)
1660
{
1661
1662
  safe_mutex_assert_owner(&LOCK_open);
1663
1208.3.2 by brian
Update for Cursor renaming.
1664
  table->cursor->extra(function);
1 by brian
clean slate
1665
  /* Mark all tables that are in use as 'old' */
1113.1.1 by Brian Aker
Dead code removal around LCOV finds.
1666
  mysql_lock_abort(session, table);	/* end threads waiting on lock */
1 by brian
clean slate
1667
1668
  /* Wait until all there are no other threads that has this table open */
1340.1.3 by Brian Aker
Lets hide stuff.
1669
  remove_table_from_cache(session, table->s->getSchemaName(),
1 by brian
clean slate
1670
                          table->s->table_name.str,
1671
                          RTFC_WAIT_OTHER_THREAD_FLAG);
1672
}
1673
1674
/*
1675
  Close a cached table
1676
1677
  SYNOPSIS
1678
    close_cached_table()
1183.1.2 by Brian Aker
Rename of handler to Cursor. You would not believe how long I have wanted
1679
    session			Thread Cursor
1 by brian
clean slate
1680
    table		Table to remove from cache
1681
1682
  NOTES
1683
    Function ends by signaling threads waiting for the table to try to
1684
    reopen the table.
1685
1686
  PREREQUISITES
1687
    Lock on LOCK_open
1688
    Win32 clients must also have a WRITE LOCK on the table !
1689
*/
1690
1054.1.11 by Brian Aker
Remove dead lock.cc commands.
1691
void Session::close_cached_table(Table *table)
1 by brian
clean slate
1692
{
1693
1054.1.11 by Brian Aker
Remove dead lock.cc commands.
1694
  wait_while_table_is_used(this, table, HA_EXTRA_FORCE_REOPEN);
1 by brian
clean slate
1695
  /* Close lock if this is not got with LOCK TABLES */
1054.1.11 by Brian Aker
Remove dead lock.cc commands.
1696
  if (lock)
1 by brian
clean slate
1697
  {
1054.1.11 by Brian Aker
Remove dead lock.cc commands.
1698
    mysql_unlock_tables(this, lock);
1699
    lock= NULL;			// Start locked threads
1 by brian
clean slate
1700
  }
1701
  /* Close all copies of 'table'.  This also frees all LOCK TABLES lock */
1054.1.11 by Brian Aker
Remove dead lock.cc commands.
1702
  unlink_open_table(table);
1 by brian
clean slate
1703
1704
  /* When lock on LOCK_open is freed other threads can continue */
1705
  broadcast_refresh();
1706
}
1707
1708
/*
1709
  RETURN VALUES
55 by brian
Update for using real bool types.
1710
    false Message sent to net (admin operation went ok)
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1711
    true  Message should be sent by caller
1 by brian
clean slate
1712
          (admin operation or network communication failed)
1713
*/
520.1.22 by Brian Aker
Second pass of thd cleanup
1714
static bool mysql_admin_table(Session* session, TableList* tables,
1 by brian
clean slate
1715
                              HA_CHECK_OPT* check_opt,
1716
                              const char *operator_name,
1717
                              thr_lock_type lock_type,
1718
                              bool open_for_modify,
1183.1.2 by Brian Aker
Rename of handler to Cursor. You would not believe how long I have wanted
1719
                              int (Cursor::*operator_func)(Session *,
1 by brian
clean slate
1720
                                                            HA_CHECK_OPT *))
1721
{
327.2.4 by Brian Aker
Refactoring table.h
1722
  TableList *table;
846 by Brian Aker
Removing on typedeffed class.
1723
  Select_Lex *select= &session->lex->select_lex;
1 by brian
clean slate
1724
  List<Item> field_list;
1725
  Item *item;
520.1.22 by Brian Aker
Second pass of thd cleanup
1726
  LEX *lex= session->lex;
1 by brian
clean slate
1727
  int result_code= 0;
1273.1.2 by Jay Pipes
This patch does not change any algorithms or code paths,
1728
  TransactionServices &transaction_services= TransactionServices::singleton();
264.2.6 by Andrey Hristov
Constify the usage of CHARSET_INFO almost to the last place in the code.
1729
  const CHARSET_INFO * const cs= system_charset_info;
1 by brian
clean slate
1730
934.2.11 by Jay Pipes
Moves end_trans(), begin_trans(), end_active_trans() out of the parser module and adds startTransaction(), endTransaction(), and endActiveTransaction() member methods of Session object.
1731
  if (! session->endActiveTransaction())
1046.1.10 by Brian Aker
Formatting around return (style)
1732
    return 1;
1 by brian
clean slate
1733
  field_list.push_back(item = new Item_empty_string("Table",
1734
                                                    NAME_CHAR_LEN * 2,
1735
                                                    cs));
1736
  item->maybe_null = 1;
1737
  field_list.push_back(item = new Item_empty_string("Op", 10, cs));
1738
  item->maybe_null = 1;
1739
  field_list.push_back(item = new Item_empty_string("Msg_type", 10, cs));
1740
  item->maybe_null = 1;
1741
  field_list.push_back(item = new Item_empty_string("Msg_text", 255, cs));
1742
  item->maybe_null = 1;
971.6.1 by Eric Day
Renamed Protocol to Client, cleaned up some unnecessary methods along the way.
1743
  if (session->client->sendFields(&field_list))
971.3.63 by Eric Day
Removed protocol field flags.
1744
    return true;
1 by brian
clean slate
1745
1746
  for (table= tables; table; table= table->next_local)
1747
  {
1748
    char table_name[NAME_LEN*2+2];
1749
    char* db = table->db;
1750
    bool fatal_error=0;
1751
673.2.1 by Toru Maesaka
First pass of replacing MySQL's strxmov with libc alternatives
1752
    sprintf(table_name,"%s.%s",db,table->table_name);
1 by brian
clean slate
1753
    table->lock_type= lock_type;
1754
    /* open only one table from local list of command */
1755
    {
327.2.4 by Brian Aker
Refactoring table.h
1756
      TableList *save_next_global, *save_next_local;
1 by brian
clean slate
1757
      save_next_global= table->next_global;
1758
      table->next_global= 0;
1759
      save_next_local= table->next_local;
1760
      table->next_local= 0;
481 by Brian Aker
Remove all of uchar.
1761
      select->table_list.first= (unsigned char*)table;
1 by brian
clean slate
1762
      /*
1763
        Time zone tables and SP tables can be add to lex->query_tables list,
1764
        so it have to be prepared.
1765
        TODO: Investigate if we can put extra tables into argument instead of
1766
        using lex->query_tables
1767
      */
1768
      lex->query_tables= table;
1769
      lex->query_tables_last= &table->next_global;
1770
      lex->query_tables_own_last= 0;
1237.6.2 by Brian Aker
Minor cleanup for dead code.
1771
      session->no_warnings_for_error= 0;
1 by brian
clean slate
1772
1109.1.3 by Brian Aker
Move names around a bit (to align similar methods)
1773
      session->openTablesLock(table);
520.1.22 by Brian Aker
Second pass of thd cleanup
1774
      session->no_warnings_for_error= 0;
1 by brian
clean slate
1775
      table->next_global= save_next_global;
1776
      table->next_local= save_next_local;
1777
    }
1778
1779
    /*
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
1780
      CHECK Table command is only command where VIEW allowed here and this
1 by brian
clean slate
1781
      command use only temporary teble method for VIEWs resolving => there
1782
      can't be VIEW tree substitition of join view => if opening table
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
1783
      succeed then table->table will have real Table pointer as value (in
1 by brian
clean slate
1784
      case of join view substitution table->table can be 0, but here it is
1785
      impossible)
1786
    */
1787
    if (!table->table)
1788
    {
520.1.22 by Brian Aker
Second pass of thd cleanup
1789
      if (!session->warn_list.elements)
1790
        push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
1 by brian
clean slate
1791
                     ER_CHECK_NO_SUCH_TABLE, ER(ER_CHECK_NO_SUCH_TABLE));
1001.1.6 by Andrew Ettinger
Match style guide
1792
      result_code= HA_ADMIN_CORRUPT;
1 by brian
clean slate
1793
      goto send_result;
1794
    }
1795
1796
    if ((table->table->db_stat & HA_READ_ONLY) && open_for_modify)
1797
    {
261.4.1 by Felipe
- Renamed MYSQL_ERROR to DRIZZLE_ERROR.
1798
      char buff[FN_REFLEN + DRIZZLE_ERRMSG_SIZE];
482 by Brian Aker
Remove uint.
1799
      uint32_t length;
971.6.1 by Eric Day
Renamed Protocol to Client, cleaned up some unnecessary methods along the way.
1800
      session->client->store(table_name);
1801
      session->client->store(operator_name);
1802
      session->client->store(STRING_WITH_LEN("error"));
77.1.18 by Monty Taylor
Removed my_vsnprintf and my_snprintf.
1803
      length= snprintf(buff, sizeof(buff), ER(ER_OPEN_AS_READONLY),
1804
                       table_name);
971.6.1 by Eric Day
Renamed Protocol to Client, cleaned up some unnecessary methods along the way.
1805
      session->client->store(buff, length);
1273.1.2 by Jay Pipes
This patch does not change any algorithms or code paths,
1806
      transaction_services.ha_autocommit_or_rollback(session, false);
934.2.11 by Jay Pipes
Moves end_trans(), begin_trans(), end_active_trans() out of the parser module and adds startTransaction(), endTransaction(), and endActiveTransaction() member methods of Session object.
1807
      session->endTransaction(COMMIT);
1039.1.16 by Brian Aker
A lot of little cleanups (most based off lcov)
1808
      session->close_thread_tables();
55 by brian
Update for using real bool types.
1809
      lex->reset_query_tables_list(false);
1 by brian
clean slate
1810
      table->table=0;				// For query cache
971.6.1 by Eric Day
Renamed Protocol to Client, cleaned up some unnecessary methods along the way.
1811
      if (session->client->flush())
1 by brian
clean slate
1812
	goto err;
1813
      continue;
1814
    }
1815
1816
    /* Close all instances of the table to allow repair to rename files */
1817
    if (lock_type == TL_WRITE && table->table->s->version)
1818
    {
1046.1.2 by Brian Aker
Comments on LOCK_open
1819
      pthread_mutex_lock(&LOCK_open); /* Lock type is TL_WRITE and we lock to repair the table */
520.1.22 by Brian Aker
Second pass of thd cleanup
1820
      const char *old_message=session->enter_cond(&COND_refresh, &LOCK_open,
1 by brian
clean slate
1821
					      "Waiting to get writelock");
1113.1.1 by Brian Aker
Dead code removal around LCOV finds.
1822
      mysql_lock_abort(session,table->table);
1340.1.3 by Brian Aker
Lets hide stuff.
1823
      remove_table_from_cache(session, table->table->s->getSchemaName(),
1 by brian
clean slate
1824
                              table->table->s->table_name.str,
1825
                              RTFC_WAIT_OTHER_THREAD_FLAG |
1826
                              RTFC_CHECK_KILLED_FLAG);
520.1.22 by Brian Aker
Second pass of thd cleanup
1827
      session->exit_cond(old_message);
1828
      if (session->killed)
1 by brian
clean slate
1829
	goto err;
1830
      open_for_modify= 0;
1831
    }
1832
1208.3.2 by brian
Update for Cursor renaming.
1833
    result_code = (table->table->cursor->*operator_func)(session, check_opt);
1001.1.3 by Andrew Ettinger
Revert bad spacing
1834
1 by brian
clean slate
1835
send_result:
1836
1837
    lex->cleanup_after_one_table_open();
520.1.22 by Brian Aker
Second pass of thd cleanup
1838
    session->clear_error();  // these errors shouldn't get client
1 by brian
clean slate
1839
    {
520.1.22 by Brian Aker
Second pass of thd cleanup
1840
      List_iterator_fast<DRIZZLE_ERROR> it(session->warn_list);
261.4.1 by Felipe
- Renamed MYSQL_ERROR to DRIZZLE_ERROR.
1841
      DRIZZLE_ERROR *err;
1 by brian
clean slate
1842
      while ((err= it++))
1843
      {
971.6.1 by Eric Day
Renamed Protocol to Client, cleaned up some unnecessary methods along the way.
1844
        session->client->store(table_name);
1845
        session->client->store(operator_name);
1846
        session->client->store(warning_level_names[err->level].str,
1847
                               warning_level_names[err->level].length);
1848
        session->client->store(err->msg);
1849
        if (session->client->flush())
1 by brian
clean slate
1850
          goto err;
1851
      }
520.1.22 by Brian Aker
Second pass of thd cleanup
1852
      drizzle_reset_errors(session, true);
1 by brian
clean slate
1853
    }
971.6.1 by Eric Day
Renamed Protocol to Client, cleaned up some unnecessary methods along the way.
1854
    session->client->store(table_name);
1855
    session->client->store(operator_name);
1 by brian
clean slate
1856
1857
    switch (result_code) {
1858
    case HA_ADMIN_NOT_IMPLEMENTED:
1001.1.3 by Andrew Ettinger
Revert bad spacing
1859
      {
1860
	char buf[ERRMSGSIZE+20];
1861
	uint32_t length=snprintf(buf, ERRMSGSIZE,
1862
                             ER(ER_CHECK_NOT_IMPLEMENTED), operator_name);
971.6.1 by Eric Day
Renamed Protocol to Client, cleaned up some unnecessary methods along the way.
1863
	session->client->store(STRING_WITH_LEN("note"));
1864
	session->client->store(buf, length);
1001.1.3 by Andrew Ettinger
Revert bad spacing
1865
      }
1866
      break;
1 by brian
clean slate
1867
1868
    case HA_ADMIN_OK:
971.6.1 by Eric Day
Renamed Protocol to Client, cleaned up some unnecessary methods along the way.
1869
      session->client->store(STRING_WITH_LEN("status"));
1870
      session->client->store(STRING_WITH_LEN("OK"));
1 by brian
clean slate
1871
      break;
1872
1873
    case HA_ADMIN_FAILED:
971.6.1 by Eric Day
Renamed Protocol to Client, cleaned up some unnecessary methods along the way.
1874
      session->client->store(STRING_WITH_LEN("status"));
1875
      session->client->store(STRING_WITH_LEN("Operation failed"));
1 by brian
clean slate
1876
      break;
1877
1878
    case HA_ADMIN_REJECT:
971.6.1 by Eric Day
Renamed Protocol to Client, cleaned up some unnecessary methods along the way.
1879
      session->client->store(STRING_WITH_LEN("status"));
1880
      session->client->store(STRING_WITH_LEN("Operation need committed state"));
55 by brian
Update for using real bool types.
1881
      open_for_modify= false;
1 by brian
clean slate
1882
      break;
1883
1884
    case HA_ADMIN_ALREADY_DONE:
971.6.1 by Eric Day
Renamed Protocol to Client, cleaned up some unnecessary methods along the way.
1885
      session->client->store(STRING_WITH_LEN("status"));
1886
      session->client->store(STRING_WITH_LEN("Table is already up to date"));
1 by brian
clean slate
1887
      break;
1888
1889
    case HA_ADMIN_CORRUPT:
971.6.1 by Eric Day
Renamed Protocol to Client, cleaned up some unnecessary methods along the way.
1890
      session->client->store(STRING_WITH_LEN("error"));
1891
      session->client->store(STRING_WITH_LEN("Corrupt"));
1 by brian
clean slate
1892
      fatal_error=1;
1893
      break;
1894
1895
    case HA_ADMIN_INVALID:
971.6.1 by Eric Day
Renamed Protocol to Client, cleaned up some unnecessary methods along the way.
1896
      session->client->store(STRING_WITH_LEN("error"));
1897
      session->client->store(STRING_WITH_LEN("Invalid argument"));
1 by brian
clean slate
1898
      break;
1899
1900
    default:				// Probably HA_ADMIN_INTERNAL_ERROR
1901
      {
1902
        char buf[ERRMSGSIZE+20];
482 by Brian Aker
Remove uint.
1903
        uint32_t length=snprintf(buf, ERRMSGSIZE,
338 by Monty Taylor
Tagged more strings.
1904
                             _("Unknown - internal error %d during operation"),
77.1.18 by Monty Taylor
Removed my_vsnprintf and my_snprintf.
1905
                             result_code);
971.6.1 by Eric Day
Renamed Protocol to Client, cleaned up some unnecessary methods along the way.
1906
        session->client->store(STRING_WITH_LEN("error"));
1907
        session->client->store(buf, length);
1 by brian
clean slate
1908
        fatal_error=1;
1909
        break;
1910
      }
1911
    }
1912
    if (table->table)
1913
    {
1914
      if (fatal_error)
1915
        table->table->s->version=0;               // Force close of table
1916
      else if (open_for_modify)
1917
      {
1918
        if (table->table->s->tmp_table)
1208.3.2 by brian
Update for Cursor renaming.
1919
          table->table->cursor->info(HA_STATUS_CONST);
1 by brian
clean slate
1920
        else
1921
        {
1922
          pthread_mutex_lock(&LOCK_open);
1340.1.3 by Brian Aker
Lets hide stuff.
1923
          remove_table_from_cache(session, table->table->s->getSchemaName(),
1 by brian
clean slate
1924
                                  table->table->s->table_name.str, RTFC_NO_FLAG);
1925
          pthread_mutex_unlock(&LOCK_open);
1926
        }
1927
      }
1928
    }
1273.1.2 by Jay Pipes
This patch does not change any algorithms or code paths,
1929
    transaction_services.ha_autocommit_or_rollback(session, false);
934.2.11 by Jay Pipes
Moves end_trans(), begin_trans(), end_active_trans() out of the parser module and adds startTransaction(), endTransaction(), and endActiveTransaction() member methods of Session object.
1930
    session->endTransaction(COMMIT);
1039.1.16 by Brian Aker
A lot of little cleanups (most based off lcov)
1931
    session->close_thread_tables();
1 by brian
clean slate
1932
    table->table=0;				// For query cache
971.6.1 by Eric Day
Renamed Protocol to Client, cleaned up some unnecessary methods along the way.
1933
    if (session->client->flush())
1 by brian
clean slate
1934
      goto err;
1935
  }
1936
836 by Brian Aker
Fixed session call from function to method.
1937
  session->my_eof();
51.1.8 by Jay Pipes
Resolving conflicts for a few files regarding FALSE=>false
1938
  return(false);
1 by brian
clean slate
1939
1940
err:
1273.1.2 by Jay Pipes
This patch does not change any algorithms or code paths,
1941
  transaction_services.ha_autocommit_or_rollback(session, true);
934.2.11 by Jay Pipes
Moves end_trans(), begin_trans(), end_active_trans() out of the parser module and adds startTransaction(), endTransaction(), and endActiveTransaction() member methods of Session object.
1942
  session->endTransaction(ROLLBACK);
1039.1.16 by Brian Aker
A lot of little cleanups (most based off lcov)
1943
  session->close_thread_tables();			// Shouldn't be needed
1 by brian
clean slate
1944
  if (table)
1945
    table->table=0;
51.1.8 by Jay Pipes
Resolving conflicts for a few files regarding FALSE=>false
1946
  return(true);
1 by brian
clean slate
1947
}
1948
1309.2.18 by Brian Aker
Remove a lot of the goto logic from createTable (this will allow me to
1949
/*
1950
  We have to write the query before we unlock the named table.
1951
1952
  Since temporary tables are not replicated under row-based
1953
  replication, CREATE TABLE ... LIKE ... needs special
1954
  treatement.  We have four cases to consider, according to the
1955
  following decision table:
1956
1957
  ==== ========= ========= ==============================
1958
  Case    Target    Source Write to binary log
1959
  ==== ========= ========= ==============================
1960
  1       normal    normal Original statement
1961
  2       normal temporary Generated statement
1962
  3    temporary    normal Nothing
1963
  4    temporary temporary Nothing
1964
  ==== ========= ========= ==============================
1965
*/
1966
static bool replicateCreateTableLike(Session *session, TableList *table, Table *name_lock,
1967
                                     bool is_src_table_tmp, bool is_if_not_exists)
1968
{
1969
  if (is_src_table_tmp)
1970
  {
1971
    char buf[2048];
1972
    String query(buf, sizeof(buf), system_charset_info);
1973
    query.length(0);  // Have to zero it since constructor doesn't
1974
1975
1976
    /*
1977
      Here we open the destination table, on which we already have
1978
      name-lock. This is needed for store_create_info() to work.
1979
      The table will be closed by unlink_open_table() at the end
1980
      of this function.
1981
    */
1982
    table->table= name_lock;
1983
    pthread_mutex_lock(&LOCK_open); /* Open new table we have just acquired */
1984
    if (session->reopen_name_locked_table(table, false))
1985
    {
1986
      pthread_mutex_unlock(&LOCK_open);
1987
      return false;
1988
    }
1989
    pthread_mutex_unlock(&LOCK_open);
1990
1991
    int result= store_create_info(table, &query, is_if_not_exists);
1992
1993
    assert(result == 0); // store_create_info() always return 0
1994
    write_bin_log(session, query.ptr());
1995
  }
1996
  else                                      // Case 1
1997
  {
1998
    write_bin_log(session, session->query.c_str());
1999
  }
2000
2001
  return true;
2002
}
2003
1309.2.17 by Brian Aker
Update to refactor out the inner code in create table.
2004
  /*
2005
    Create a new table by copying from source table
2006
2007
    Altough exclusive name-lock on target table protects us from concurrent
2008
    DML and DDL operations on it we still want to wrap .FRM creation and call
2009
    to plugin::StorageEngine::createTable() in critical section protected by
2010
    LOCK_open in order to provide minimal atomicity against operations which
2011
    disregard name-locks, like I_S implementation, for example. This is a
2012
    temporary and should not be copied. Instead we should fix our code to
2013
    always honor name-locks.
2014
2015
    Also some engines (e.g. NDB cluster) require that LOCK_open should be held
2016
    during the call to plugin::StorageEngine::createTable().
2017
    See bug #28614 for more info.
2018
  */
2019
static bool create_table_wrapper(Session &session, message::Table& create_table_proto,
2020
                                 TableIdentifier &destination_identifier,
2021
                                 TableIdentifier &src_table,
2022
                                 bool lex_identified_temp_table, bool is_engine_set)
2023
{
2024
  int protoerr= EEXIST;
2025
  message::Table new_proto;
2026
  message::Table src_proto;
2027
2028
  protoerr= plugin::StorageEngine::getTableDefinition(session,
2029
                                                      src_table,
1354.1.1 by Brian Aker
Modify ptr to reference.
2030
                                                      src_proto);
1309.2.17 by Brian Aker
Update to refactor out the inner code in create table.
2031
  new_proto.CopyFrom(src_proto);
2032
2033
  if (lex_identified_temp_table)
2034
  {
2035
    new_proto.set_type(message::Table::TEMPORARY);
2036
  }
2037
  else
2038
  {
2039
    new_proto.set_type(message::Table::STANDARD);
2040
  }
2041
2042
  if (is_engine_set)
2043
  {
2044
    message::Table::StorageEngine *protoengine;
2045
2046
    protoengine= new_proto.mutable_engine();
2047
    protoengine->set_name(create_table_proto.engine().name());
2048
  }
2049
1320.1.4 by Brian Aker
Move proto file write into createTable() (where it obviously belongs).
2050
  if (protoerr && protoerr != EEXIST)
1309.2.17 by Brian Aker
Update to refactor out the inner code in create table.
2051
  {
2052
    if (errno == ENOENT)
2053
      my_error(ER_BAD_DB_ERROR,MYF(0), destination_identifier.getSchemaName());
2054
    else
2055
      my_error(ER_CANT_CREATE_FILE, MYF(0), destination_identifier.getPath(), errno);
2056
2057
    return false;
2058
  }
2059
2060
  /*
2061
    As mysql_truncate don't work on a new table at this stage of
2062
    creation, instead create the table directly (for both normal
2063
    and temporary tables).
2064
  */
1309.2.18 by Brian Aker
Remove a lot of the goto logic from createTable (this will allow me to
2065
  int err= plugin::StorageEngine::createTable(session,
2066
                                              destination_identifier,
2067
                                              true, new_proto);
1309.2.17 by Brian Aker
Update to refactor out the inner code in create table.
2068
2069
  return err ? false : true;
2070
}
2071
1 by brian
clean slate
2072
/*
2073
  Create a table identical to the specified table
2074
2075
  SYNOPSIS
2076
    mysql_create_like_table()
520.1.22 by Brian Aker
Second pass of thd cleanup
2077
    session		Thread object
1 by brian
clean slate
2078
    table       Table list element for target table
2079
    src_table   Table list element for source table
2080
    create_info Create info
2081
2082
  RETURN VALUES
55 by brian
Update for using real bool types.
2083
    false OK
2084
    true  error
1 by brian
clean slate
2085
*/
2086
1340.1.1 by Brian Aker
Length usage of identifier down the tree.
2087
bool mysql_create_like_table(Session* session,
2088
                             TableIdentifier &destination_identifier,
2089
                             TableList* table, TableList* src_table,
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
2090
                             message::Table& create_table_proto,
1222.1.3 by Brian Aker
Remove used flag for engine.
2091
                             bool is_if_not_exists,
2092
                             bool is_engine_set)
1 by brian
clean slate
2093
{
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
2094
  Table *name_lock= 0;
1 by brian
clean slate
2095
  char *db= table->db;
2096
  char *table_name= table->table_name;
55 by brian
Update for using real bool types.
2097
  bool res= true;
482 by Brian Aker
Remove uint.
2098
  uint32_t not_used;
1222.2.1 by Brian Aker
Takes the majority usage of parser based HA_CREATE_INFO usage around
2099
  bool lex_identified_temp_table=
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
2100
    (create_table_proto.type() == message::Table::TEMPORARY);
1309.2.17 by Brian Aker
Update to refactor out the inner code in create table.
2101
  bool was_created;
1 by brian
clean slate
2102
2103
  /*
2104
    By opening source table we guarantee that it exists and no concurrent
2105
    DDL operation will mess with it. Later we also take an exclusive
1208.3.2 by brian
Update for Cursor renaming.
2106
    name-lock on target table name, which makes copying of .frm cursor,
1130.3.16 by Monty Taylor
Moved the last three methods from plugin/storage_engine.cc to be static methods on StorageEngine.
2107
    call to plugin::StorageEngine::createTable() and binlogging atomic
2108
    against concurrent DML and DDL operations on target table.
2109
    Thus by holding both these "locks" we ensure that our statement is
2110
    properly isolated from all concurrent operations which matter.
1 by brian
clean slate
2111
  */
1109.1.2 by Brian Aker
More from the table patch
2112
  if (session->open_tables_from_list(&src_table, &not_used))
1054.1.9 by Brian Aker
This is a large number of refactors against the Session class for its
2113
    return true;
1 by brian
clean slate
2114
1340.1.3 by Brian Aker
Lets hide stuff.
2115
  TableIdentifier src_identifier(src_table->table->s->getSchemaName(),
1309.2.17 by Brian Aker
Update to refactor out the inner code in create table.
2116
                                 src_table->table->s->table_name.str, src_table->table->s->tmp_table);
2117
2118
1223.4.6 by Brian Aker
Additional TableIdentifier usage.
2119
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
2120
  /*
1 by brian
clean slate
2121
    Check that destination tables does not exist. Note that its name
2122
    was already checked when it was added to the table list.
2123
  */
1309.2.18 by Brian Aker
Remove a lot of the goto logic from createTable (this will allow me to
2124
  bool table_exists= false;
1222.2.1 by Brian Aker
Takes the majority usage of parser based HA_CREATE_INFO usage around
2125
  if (lex_identified_temp_table)
1 by brian
clean slate
2126
  {
1054.1.9 by Brian Aker
This is a large number of refactors against the Session class for its
2127
    if (session->find_temporary_table(db, table_name))
1309.2.18 by Brian Aker
Remove a lot of the goto logic from createTable (this will allow me to
2128
    {
2129
      table_exists= true;
2130
    }
1 by brian
clean slate
2131
  }
2132
  else
2133
  {
1054.1.9 by Brian Aker
This is a large number of refactors against the Session class for its
2134
    if (session->lock_table_name_if_not_cached(db, table_name, &name_lock))
1309.2.18 by Brian Aker
Remove a lot of the goto logic from createTable (this will allow me to
2135
    {
2136
      if (name_lock)
2137
      {
2138
        pthread_mutex_lock(&LOCK_open); /* unlink open tables for create table like*/
2139
        session->unlink_open_table(name_lock);
2140
        pthread_mutex_unlock(&LOCK_open);
2141
      }
2142
2143
      return res;
2144
    }
1309.2.17 by Brian Aker
Update to refactor out the inner code in create table.
2145
1309.1.27 by Brian Aker
Updating interface around doesTablExist()
2146
    if (not name_lock)
1309.2.18 by Brian Aker
Remove a lot of the goto logic from createTable (this will allow me to
2147
    {
2148
      table_exists= true;
2149
    }
2150
    else if (plugin::StorageEngine::doesTableExist(*session, destination_identifier))
2151
    {
2152
      table_exists= true;
2153
    }
2154
  }
2155
2156
  if (table_exists)
2157
  {
2158
    if (is_if_not_exists)
2159
    {
2160
      char warn_buff[DRIZZLE_ERRMSG_SIZE];
2161
      snprintf(warn_buff, sizeof(warn_buff),
2162
               ER(ER_TABLE_EXISTS_ERROR), table_name);
2163
      push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
2164
                   ER_TABLE_EXISTS_ERROR,warn_buff);
2165
      res= false;
2166
    }
2167
    else
2168
    {
2169
      my_error(ER_TABLE_EXISTS_ERROR, MYF(0), table_name);
2170
    }
2171
  }
2172
  else // Otherwise we create the table
2173
  {
2174
    pthread_mutex_lock(&LOCK_open); /* We lock for CREATE TABLE LIKE to copy table definition */
2175
    was_created= create_table_wrapper(*session, create_table_proto, destination_identifier,
2176
                                      src_identifier, lex_identified_temp_table, is_engine_set);
2177
    pthread_mutex_unlock(&LOCK_open);
2178
2179
    // So we blew the creation of the table, and we scramble to clean up
2180
    // anything that might have been created (read... it is a hack)
2181
    if (not was_created)
2182
    {
2183
      if (lex_identified_temp_table)
2184
      {
1320.1.10 by Brian Aker
Additional pass through doDropTable()
2185
        (void) session->rm_temporary_table(destination_identifier);
1309.2.18 by Brian Aker
Remove a lot of the goto logic from createTable (this will allow me to
2186
      }
2187
      else
2188
      {
1340.1.1 by Brian Aker
Length usage of identifier down the tree.
2189
        quick_rm_table(*session, destination_identifier);
1309.2.18 by Brian Aker
Remove a lot of the goto logic from createTable (this will allow me to
2190
      }
2191
    } 
2192
    else if (lex_identified_temp_table && not session->open_temporary_table(destination_identifier))
2193
    {
2194
      // We created, but we can't open... also, a hack.
1320.1.10 by Brian Aker
Additional pass through doDropTable()
2195
      (void) session->rm_temporary_table(destination_identifier);
1 by brian
clean slate
2196
    }
1309.2.18 by Brian Aker
Remove a lot of the goto logic from createTable (this will allow me to
2197
    else
1 by brian
clean slate
2198
    {
1309.2.18 by Brian Aker
Remove a lot of the goto logic from createTable (this will allow me to
2199
      if (not lex_identified_temp_table)
1 by brian
clean slate
2200
      {
1309.2.18 by Brian Aker
Remove a lot of the goto logic from createTable (this will allow me to
2201
        bool rc= replicateCreateTableLike(session, table, name_lock, (src_table->table->s->tmp_table), is_if_not_exists);
2202
        (void)rc;
1 by brian
clean slate
2203
      }
1309.2.18 by Brian Aker
Remove a lot of the goto logic from createTable (this will allow me to
2204
2205
      res= false;
1 by brian
clean slate
2206
    }
2207
  }
2208
2209
  if (name_lock)
2210
  {
1046.1.2 by Brian Aker
Comments on LOCK_open
2211
    pthread_mutex_lock(&LOCK_open); /* unlink open tables for create table like*/
1054.1.9 by Brian Aker
This is a large number of refactors against the Session class for its
2212
    session->unlink_open_table(name_lock);
1 by brian
clean slate
2213
    pthread_mutex_unlock(&LOCK_open);
2214
  }
1309.2.18 by Brian Aker
Remove a lot of the goto logic from createTable (this will allow me to
2215
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
2216
  return(res);
1 by brian
clean slate
2217
}
2218
2219
520.1.22 by Brian Aker
Second pass of thd cleanup
2220
bool mysql_analyze_table(Session* session, TableList* tables, HA_CHECK_OPT* check_opt)
1 by brian
clean slate
2221
{
2222
  thr_lock_type lock_type = TL_READ_NO_INSERT;
2223
520.1.22 by Brian Aker
Second pass of thd cleanup
2224
  return(mysql_admin_table(session, tables, check_opt,
1237.6.2 by Brian Aker
Minor cleanup for dead code.
2225
				"analyze", lock_type, true,
1183.1.2 by Brian Aker
Rename of handler to Cursor. You would not believe how long I have wanted
2226
				&Cursor::ha_analyze));
1 by brian
clean slate
2227
}
2228
2229
520.1.22 by Brian Aker
Second pass of thd cleanup
2230
bool mysql_check_table(Session* session, TableList* tables,HA_CHECK_OPT* check_opt)
1 by brian
clean slate
2231
{
2232
  thr_lock_type lock_type = TL_READ_NO_INSERT;
2233
520.1.22 by Brian Aker
Second pass of thd cleanup
2234
  return(mysql_admin_table(session, tables, check_opt,
1 by brian
clean slate
2235
				"check", lock_type,
1237.6.2 by Brian Aker
Minor cleanup for dead code.
2236
				false,
1183.1.2 by Brian Aker
Rename of handler to Cursor. You would not believe how long I have wanted
2237
				&Cursor::ha_check));
1 by brian
clean slate
2238
}
2239
2240
520.1.22 by Brian Aker
Second pass of thd cleanup
2241
bool mysql_checksum_table(Session *session, TableList *tables,
1222.1.10 by Brian Aker
Removes options from DDL left in Cursor for admin operations (they were
2242
                          HA_CHECK_OPT *)
1 by brian
clean slate
2243
{
327.2.4 by Brian Aker
Refactoring table.h
2244
  TableList *table;
1 by brian
clean slate
2245
  List<Item> field_list;
2246
  Item *item;
2247
2248
  field_list.push_back(item = new Item_empty_string("Table", NAME_LEN*2));
2249
  item->maybe_null= 1;
152 by Brian Aker
longlong replacement
2250
  field_list.push_back(item= new Item_int("Checksum", (int64_t) 1,
1 by brian
clean slate
2251
                                          MY_INT64_NUM_DECIMAL_DIGITS));
2252
  item->maybe_null= 1;
971.6.1 by Eric Day
Renamed Protocol to Client, cleaned up some unnecessary methods along the way.
2253
  if (session->client->sendFields(&field_list))
971.3.63 by Eric Day
Removed protocol field flags.
2254
    return true;
1 by brian
clean slate
2255
2256
  /* Open one table after the other to keep lock time as short as possible. */
2257
  for (table= tables; table; table= table->next_local)
2258
  {
2259
    char table_name[NAME_LEN*2+2];
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
2260
    Table *t;
1 by brian
clean slate
2261
673.2.1 by Toru Maesaka
First pass of replacing MySQL's strxmov with libc alternatives
2262
    sprintf(table_name,"%s.%s",table->db,table->table_name);
1 by brian
clean slate
2263
1109.1.3 by Brian Aker
Move names around a bit (to align similar methods)
2264
    t= table->table= session->openTableLock(table, TL_READ);
520.1.22 by Brian Aker
Second pass of thd cleanup
2265
    session->clear_error();			// these errors shouldn't get client
1 by brian
clean slate
2266
971.6.1 by Eric Day
Renamed Protocol to Client, cleaned up some unnecessary methods along the way.
2267
    session->client->store(table_name);
1 by brian
clean slate
2268
2269
    if (!t)
2270
    {
2271
      /* Table didn't exist */
971.6.1 by Eric Day
Renamed Protocol to Client, cleaned up some unnecessary methods along the way.
2272
      session->client->store();
520.1.22 by Brian Aker
Second pass of thd cleanup
2273
      session->clear_error();
1 by brian
clean slate
2274
    }
2275
    else
2276
    {
1222.1.10 by Brian Aker
Removes options from DDL left in Cursor for admin operations (they were
2277
      /**
2278
        @note if the engine keeps a checksum then we return the checksum, otherwise we calculate
2279
      */
1233.1.7 by Brian Aker
Final table flag removal.
2280
      if (t->cursor->getEngine()->check_flag(HTON_BIT_HAS_CHECKSUM))
2281
      {
2282
        session->client->store((uint64_t)t->cursor->checksum());
2283
      }
1 by brian
clean slate
2284
      else
2285
      {
2286
	/* calculating table's checksum */
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
2287
	internal::ha_checksum crc= 0;
481 by Brian Aker
Remove all of uchar.
2288
        unsigned char null_mask=256 -  (1 << t->s->last_null_bit_pos);
1 by brian
clean slate
2289
2290
        t->use_all_columns();
2291
1208.3.2 by brian
Update for Cursor renaming.
2292
	if (t->cursor->ha_rnd_init(1))
971.6.1 by Eric Day
Renamed Protocol to Client, cleaned up some unnecessary methods along the way.
2293
	  session->client->store();
1 by brian
clean slate
2294
	else
2295
	{
2296
	  for (;;)
2297
	  {
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
2298
	    internal::ha_checksum row_crc= 0;
1208.3.2 by brian
Update for Cursor renaming.
2299
            int error= t->cursor->rnd_next(t->record[0]);
1 by brian
clean slate
2300
            if (unlikely(error))
2301
            {
2302
              if (error == HA_ERR_RECORD_DELETED)
2303
                continue;
2304
              break;
2305
            }
2306
	    if (t->s->null_bytes)
2307
            {
2308
              /* fix undefined null bits */
2309
              t->record[0][t->s->null_bytes-1] |= null_mask;
2310
              if (!(t->s->db_create_options & HA_OPTION_PACK_RECORD))
2311
                t->record[0][0] |= 1;
2312
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
2313
	      row_crc= internal::my_checksum(row_crc, t->record[0], t->s->null_bytes);
1 by brian
clean slate
2314
            }
2315
482 by Brian Aker
Remove uint.
2316
	    for (uint32_t i= 0; i < t->s->fields; i++ )
1 by brian
clean slate
2317
	    {
2318
	      Field *f= t->field[i];
212.2.2 by Patrick Galbraith
Renamed FIELD_TYPE to DRIZZLE_TYPE
2319
	      if ((f->type() == DRIZZLE_TYPE_BLOB) ||
2320
                  (f->type() == DRIZZLE_TYPE_VARCHAR))
1 by brian
clean slate
2321
	      {
2322
		String tmp;
2323
		f->val_str(&tmp);
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
2324
		row_crc= internal::my_checksum(row_crc, (unsigned char*) tmp.ptr(), tmp.length());
1 by brian
clean slate
2325
	      }
2326
	      else
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
2327
		row_crc= internal::my_checksum(row_crc, f->ptr,
1 by brian
clean slate
2328
				     f->pack_length());
2329
	    }
2330
2331
	    crc+= row_crc;
2332
	  }
971.6.1 by Eric Day
Renamed Protocol to Client, cleaned up some unnecessary methods along the way.
2333
	  session->client->store((uint64_t)crc);
1208.3.2 by brian
Update for Cursor renaming.
2334
          t->cursor->ha_rnd_end();
1 by brian
clean slate
2335
	}
2336
      }
520.1.22 by Brian Aker
Second pass of thd cleanup
2337
      session->clear_error();
1039.1.16 by Brian Aker
A lot of little cleanups (most based off lcov)
2338
      session->close_thread_tables();
1 by brian
clean slate
2339
      table->table=0;				// For query cache
2340
    }
971.6.1 by Eric Day
Renamed Protocol to Client, cleaned up some unnecessary methods along the way.
2341
    if (session->client->flush())
1 by brian
clean slate
2342
      goto err;
2343
  }
2344
836 by Brian Aker
Fixed session call from function to method.
2345
  session->my_eof();
51.1.8 by Jay Pipes
Resolving conflicts for a few files regarding FALSE=>false
2346
  return(false);
1 by brian
clean slate
2347
2348
 err:
1039.1.16 by Brian Aker
A lot of little cleanups (most based off lcov)
2349
  session->close_thread_tables();			// Shouldn't be needed
1 by brian
clean slate
2350
  if (table)
2351
    table->table=0;
51.1.8 by Jay Pipes
Resolving conflicts for a few files regarding FALSE=>false
2352
  return(true);
1 by brian
clean slate
2353
}
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
2354
2355
} /* namespace drizzled */