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