~drizzle-trunk/drizzle/development

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