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