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