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