~drizzle-trunk/drizzle/development

1 by brian
clean slate
1
/* Copyright (C) 2000-2003 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
17
/* create and drop of databases */
1241.9.36 by Monty Taylor
ZOMG. I deleted drizzled/server_includes.h.
18
#include "config.h"
1259.3.7 by Monty Taylor
Fixed OSX build error.
19
20
#include <fcntl.h>
21
#include <sys/stat.h>
22
#include <sys/types.h>
23
24
#include <set>
318 by Brian Aker
Modified sql_db to now use Google Proto buffers instead of MySQL type.
25
#include <string>
26
#include <fstream>
1259.3.7 by Monty Taylor
Fixed OSX build error.
27
988.1.1 by Jay Pipes
Changes libserialize to libdrizzledmessage per ML discussion. All GPB messages are now in the drizzled::message namespace.
28
#include <drizzled/message/schema.pb.h>
1271.5.3 by Tim Penhey
change the include files
29
#include "drizzled/error.h"
538 by Monty Taylor
Moved gettext.h into drizzled in anticipation of the new client lib.
30
#include <drizzled/gettext.h>
1241.9.57 by Monty Taylor
Oy. Bigger change than I normally like - but this stuff is all intertwined.
31
#include <drizzled/my_hash.h>
1241.9.64 by Monty Taylor
Moved remaining non-public portions of mysys and mystrings to drizzled/internal.
32
#include "drizzled/internal/m_string.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.
33
#include <drizzled/session.h>
34
#include <drizzled/db.h>
35
#include <drizzled/sql_base.h>
670.2.4 by Monty Taylor
Removed more stuff from the headers.
36
#include <drizzled/lock.h>
722.4.1 by Mark Atwood
integrate errmsg plugin into sql_print_* functions
37
#include <drizzled/errmsg_print.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.
38
#include <drizzled/transaction_services.h>
1089.10.1 by Stewart Smith
fix SHOW CREATE DATABASE for default collation. Move database metadata reading code around to be a bit more sane.
39
#include <drizzled/message/schema.pb.h>
1241.9.12 by Monty Taylor
Trims more out of server_includes.h.
40
#include "drizzled/sql_table.h"
1273.20.3 by Brian Aker
Fixing charset return.
41
#include "drizzled/plugin/storage_engine.h"
1317.2.1 by Monty Taylor
Removed an unused variable.
42
#include "drizzled/plugin/authorization.h"
1241.9.28 by Monty Taylor
Removed global_charset_info.h from server_includes.h
43
#include "drizzled/global_charset_info.h"
1241.9.31 by Monty Taylor
Moved global pthread variables into their own header.
44
#include "drizzled/pthread_globals.h"
1241.9.57 by Monty Taylor
Oy. Bigger change than I normally like - but this stuff is all intertwined.
45
#include "drizzled/charset.h"
1241.9.28 by Monty Taylor
Removed global_charset_info.h from server_includes.h
46
1685.2.14 by Brian Aker
Use boost for the main lock we use in schema creation/alteration.
47
#include <boost/thread/mutex.hpp>
48
49
boost::mutex LOCK_create_db;
50
1241.9.64 by Monty Taylor
Moved remaining non-public portions of mysys and mystrings to drizzled/internal.
51
#include "drizzled/internal/my_sys.h"
988.1.6 by Jay Pipes
Removed old protobuf_replicator plugin, fixed up db.cc and other files to use new
52
1 by brian
clean slate
53
#define MAX_DROP_TABLE_Q_LEN      1024
54
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
55
using namespace std;
56
57
namespace drizzled
58
{
59
1601 by Brian Aker
Move functions to class methods.
60
static long drop_tables_via_filenames(Session *session,
1415 by Brian Aker
Mass overhaul to use schema_identifier.
61
                                 SchemaIdentifier &schema_identifier,
1663.1.3 by Brian Aker
Remove table names options.
62
                                 TableIdentifiers &dropped_tables);
1415 by Brian Aker
Mass overhaul to use schema_identifier.
63
static void mysql_change_db_impl(Session *session);
64
static void mysql_change_db_impl(Session *session, SchemaIdentifier &schema_identifier);
820.1.11 by Stewart Smith
re-introduce db.opt, but with parsing it from disk instead of in process cache with mutex.
65
1 by brian
clean slate
66
/*
67
  Create a database
68
69
  SYNOPSIS
70
  mysql_create_db()
520.1.22 by Brian Aker
Second pass of thd cleanup
71
  session		Thread handler
1 by brian
clean slate
72
  db		Name of database to create
73
		Function assumes that this is already validated.
74
  create_info	Database create options (like character set)
75
76
  SIDE-EFFECTS
77
   1. Report back to client that command succeeded (my_ok)
78
   2. Report errors to client
79
   3. Log event to binary log
80
81
  RETURN VALUES
51.1.51 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
82
  false ok
83
  true  Error
1 by brian
clean slate
84
85
*/
86
1309.1.9 by Brian Aker
Baby steps.
87
bool mysql_create_db(Session *session, const message::Schema &schema_message, const bool is_if_not_exists)
1 by brian
clean slate
88
{
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.
89
  TransactionServices &transaction_services= TransactionServices::singleton();
1039.1.3 by Brian Aker
Remove dead bits from db create/rm
90
  bool error= false;
1235.4.14 by Stewart Smith
use message::Schema in mysql_create_db instead of HA_CREATE_INFO
91
1 by brian
clean slate
92
  /*
93
    Do not create database if another thread is holding read lock.
971.3.2 by Eric Day
Renamed LOCK_drizzleclient_create_db to LOCK_create_db since this has nothing to do with drizzleclient. I think Monty accidently got this during the drizzleclient rename.
94
    Wait for global read lock before acquiring LOCK_create_db.
1 by brian
clean slate
95
    After wait_if_global_read_lock() we have protection against another
971.3.2 by Eric Day
Renamed LOCK_drizzleclient_create_db to LOCK_create_db since this has nothing to do with drizzleclient. I think Monty accidently got this during the drizzleclient rename.
96
    global read lock. If we would acquire LOCK_create_db first,
1 by brian
clean slate
97
    another thread could step in and get the global read lock before we
98
    reach wait_if_global_read_lock(). If this thread tries the same as we
971.3.2 by Eric Day
Renamed LOCK_drizzleclient_create_db to LOCK_create_db since this has nothing to do with drizzleclient. I think Monty accidently got this during the drizzleclient rename.
99
    (admin a db), it would then go and wait on LOCK_create_db...
1 by brian
clean slate
100
    Furthermore wait_if_global_read_lock() checks if the current thread
101
    has the global read lock and refuses the operation with
102
    ER_CANT_UPDATE_WITH_READLOCK if applicable.
103
  */
520.1.22 by Brian Aker
Second pass of thd cleanup
104
  if (wait_if_global_read_lock(session, 0, 1))
1 by brian
clean slate
105
  {
1273.19.25 by Brian Aker
createSchema() now works via SE interface.
106
    return false;
1 by brian
clean slate
107
  }
108
1273.19.28 by Brian Aker
More cleanup on ALTER SCHEMA. Hey! MySQL never had errors on half of it...
109
  assert(schema_message.has_name());
110
  assert(schema_message.has_collation());
111
1273.19.25 by Brian Aker
createSchema() now works via SE interface.
112
  // @todo push this lock down into the engine
1685.2.14 by Brian Aker
Use boost for the main lock we use in schema creation/alteration.
113
  {
114
    boost::mutex::scoped_lock scopedLock(LOCK_create_db);
1 by brian
clean slate
115
1685.2.14 by Brian Aker
Use boost for the main lock we use in schema creation/alteration.
116
    // Check to see if it exists already.  
117
    SchemaIdentifier schema_identifier(schema_message.name());
118
    if (plugin::StorageEngine::doesSchemaExist(schema_identifier))
119
    {
120
      if (not is_if_not_exists)
121
      {
122
        my_error(ER_DB_CREATE_EXISTS, MYF(0), schema_message.name().c_str());
123
        error= true;
124
      }
125
      else
126
      {
127
        push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
128
                            ER_DB_CREATE_EXISTS, ER(ER_DB_CREATE_EXISTS),
129
                            schema_message.name().c_str());
130
        session->my_ok();
131
      }
132
    }
133
    else if (not plugin::StorageEngine::createSchema(schema_message)) // Try to create it 
134
    {
135
      my_error(ER_CANT_CREATE_DB, MYF(0), schema_message.name().c_str(), errno);
1273.19.25 by Brian Aker
createSchema() now works via SE interface.
136
      error= true;
137
    }
1685.2.14 by Brian Aker
Use boost for the main lock we use in schema creation/alteration.
138
    else // Created !
1273.19.25 by Brian Aker
createSchema() now works via SE interface.
139
    {
1685.2.14 by Brian Aker
Use boost for the main lock we use in schema creation/alteration.
140
      transaction_services.createSchema(session, schema_message);
141
      session->my_ok(1);
1273.19.25 by Brian Aker
createSchema() now works via SE interface.
142
    }
143
  }
520.1.22 by Brian Aker
Second pass of thd cleanup
144
  start_waiting_global_read_lock(session);
1273.19.25 by Brian Aker
createSchema() now works via SE interface.
145
1039.1.3 by Brian Aker
Remove dead bits from db create/rm
146
  return error;
1 by brian
clean slate
147
}
148
149
150
/* db-name is already validated when we come here */
151
1273.19.26 by Brian Aker
Move Alter schema to SE interface.
152
bool mysql_alter_db(Session *session, const message::Schema &schema_message)
1 by brian
clean slate
153
{
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.
154
  TransactionServices &transaction_services= TransactionServices::singleton();
1 by brian
clean slate
155
156
  /*
157
    Do not alter database if another thread is holding read lock.
971.3.2 by Eric Day
Renamed LOCK_drizzleclient_create_db to LOCK_create_db since this has nothing to do with drizzleclient. I think Monty accidently got this during the drizzleclient rename.
158
    Wait for global read lock before acquiring LOCK_create_db.
1 by brian
clean slate
159
    After wait_if_global_read_lock() we have protection against another
971.3.2 by Eric Day
Renamed LOCK_drizzleclient_create_db to LOCK_create_db since this has nothing to do with drizzleclient. I think Monty accidently got this during the drizzleclient rename.
160
    global read lock. If we would acquire LOCK_create_db first,
1 by brian
clean slate
161
    another thread could step in and get the global read lock before we
162
    reach wait_if_global_read_lock(). If this thread tries the same as we
971.3.2 by Eric Day
Renamed LOCK_drizzleclient_create_db to LOCK_create_db since this has nothing to do with drizzleclient. I think Monty accidently got this during the drizzleclient rename.
163
    (admin a db), it would then go and wait on LOCK_create_db...
1 by brian
clean slate
164
    Furthermore wait_if_global_read_lock() checks if the current thread
165
    has the global read lock and refuses the operation with
166
    ER_CANT_UPDATE_WITH_READLOCK if applicable.
167
  */
1273.19.26 by Brian Aker
Move Alter schema to SE interface.
168
  if ((wait_if_global_read_lock(session, 0, 1)))
169
    return false;
1235.4.16 by Stewart Smith
use Schema proto for ALTER DATABASE/SCHEMA as well. Fix 'ALTER DATABASE COLLATE = foo'. Remove now obsolete fill_schema_message. HA_CREATE_INFO is no longer used in CREATE or ALTER SCHEMA.
170
1685.2.14 by Brian Aker
Use boost for the main lock we use in schema creation/alteration.
171
  bool success;
172
  {
173
    boost::mutex::scoped_lock scopedLock(LOCK_create_db);
174
175
    SchemaIdentifier schema_idenifier(schema_message.name());
176
    if (not plugin::StorageEngine::doesSchemaExist(schema_idenifier))
177
    {
178
      my_error(ER_SCHEMA_DOES_NOT_EXIST, MYF(0), schema_message.name().c_str());
179
      return false;
180
    }
181
182
    /* Change options if current database is being altered. */
183
    success= plugin::StorageEngine::alterSchema(schema_message);
184
185
    if (success)
186
    {
187
      transaction_services.rawStatement(session, session->getQueryString());
188
      session->my_ok(1);
189
    }
190
    else
191
    {
192
      my_error(ER_ALTER_SCHEMA, MYF(0), schema_message.name().c_str());
193
    }
194
  }
520.1.22 by Brian Aker
Second pass of thd cleanup
195
  start_waiting_global_read_lock(session);
1273.19.26 by Brian Aker
Move Alter schema to SE interface.
196
197
  return success;
1 by brian
clean slate
198
}
199
200
201
/*
202
  Drop all tables in a database and the database itself
203
204
  SYNOPSIS
205
    mysql_rm_db()
520.1.22 by Brian Aker
Second pass of thd cleanup
206
    session			Thread handle
1 by brian
clean slate
207
    db			Database name in the case given by user
208
		        It's already validated and set to lower case
209
                        (if needed) when we come here
210
    if_exists		Don't give error if database doesn't exists
211
    silent		Don't generate errors
212
213
  RETURN
51.1.51 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
214
    false ok (Database dropped)
1 by brian
clean slate
215
    ERROR Error
216
*/
217
1415 by Brian Aker
Mass overhaul to use schema_identifier.
218
bool mysql_rm_db(Session *session, SchemaIdentifier &schema_identifier, const bool if_exists)
1 by brian
clean slate
219
{
220
  long deleted=0;
253 by Brian Aker
Removed final my_bool from sql_db.
221
  int error= false;
1663.1.3 by Brian Aker
Remove table names options.
222
  TableIdentifiers dropped_tables;
1309.1.8 by Brian Aker
Modest update to drop schema.
223
  message::Schema schema_proto;
1 by brian
clean slate
224
225
  /*
226
    Do not drop database if another thread is holding read lock.
971.3.2 by Eric Day
Renamed LOCK_drizzleclient_create_db to LOCK_create_db since this has nothing to do with drizzleclient. I think Monty accidently got this during the drizzleclient rename.
227
    Wait for global read lock before acquiring LOCK_create_db.
1 by brian
clean slate
228
    After wait_if_global_read_lock() we have protection against another
971.3.2 by Eric Day
Renamed LOCK_drizzleclient_create_db to LOCK_create_db since this has nothing to do with drizzleclient. I think Monty accidently got this during the drizzleclient rename.
229
    global read lock. If we would acquire LOCK_create_db first,
1 by brian
clean slate
230
    another thread could step in and get the global read lock before we
231
    reach wait_if_global_read_lock(). If this thread tries the same as we
971.3.2 by Eric Day
Renamed LOCK_drizzleclient_create_db to LOCK_create_db since this has nothing to do with drizzleclient. I think Monty accidently got this during the drizzleclient rename.
232
    (admin a db), it would then go and wait on LOCK_create_db...
1 by brian
clean slate
233
    Furthermore wait_if_global_read_lock() checks if the current thread
234
    has the global read lock and refuses the operation with
235
    ER_CANT_UPDATE_WITH_READLOCK if applicable.
236
  */
520.1.22 by Brian Aker
Second pass of thd cleanup
237
  if (wait_if_global_read_lock(session, 0, 1))
1 by brian
clean slate
238
  {
1259.3.3 by Monty Taylor
Removed last use of my_dir.
239
    return -1;
1 by brian
clean slate
240
  }
241
1387 by Brian Aker
Fix for cases where not all files are removed during a deletion of a schema.
242
  // Lets delete the temporary tables first outside of locks.  
243
  set<string> set_of_names;
1415 by Brian Aker
Mass overhaul to use schema_identifier.
244
  session->doGetTableNames(schema_identifier, set_of_names);
1387 by Brian Aker
Fix for cases where not all files are removed during a deletion of a schema.
245
246
  for (set<string>::iterator iter= set_of_names.begin(); iter != set_of_names.end(); iter++)
247
  {
1415 by Brian Aker
Mass overhaul to use schema_identifier.
248
    TableIdentifier identifier(schema_identifier, *iter, message::Table::TEMPORARY);
1387 by Brian Aker
Fix for cases where not all files are removed during a deletion of a schema.
249
    Table *table= session->find_temporary_table(identifier);
250
    session->close_temporary_table(table);
251
  }
252
1 by brian
clean slate
253
  {
1685.2.14 by Brian Aker
Use boost for the main lock we use in schema creation/alteration.
254
    boost::mutex::scoped_lock scopedLock(LOCK_create_db);
255
256
    /* See if the schema exists */
257
    if (not plugin::StorageEngine::doesSchemaExist(schema_identifier))
1309.1.8 by Brian Aker
Modest update to drop schema.
258
    {
1685.2.14 by Brian Aker
Use boost for the main lock we use in schema creation/alteration.
259
      if (if_exists)
260
      {
261
        push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
262
                            ER_DB_DROP_EXISTS, ER(ER_DB_DROP_EXISTS),
263
                            schema_identifier.getSQLPath().c_str());
264
      }
265
      else
266
      {
267
        error= -1;
268
        my_error(ER_DB_DROP_EXISTS, MYF(0), schema_identifier.getSQLPath().c_str());
269
        goto exit;
270
      }
1309.1.8 by Brian Aker
Modest update to drop schema.
271
    }
272
    else
1 by brian
clean slate
273
    {
1689.2.7 by Brian Aker
LOCK_open to boost.
274
      LOCK_open.lock(); /* After deleting database, remove all cache entries related to schema */
1685.2.14 by Brian Aker
Use boost for the main lock we use in schema creation/alteration.
275
      remove_db_from_cache(schema_identifier);
1689.2.7 by Brian Aker
LOCK_open to boost.
276
      LOCK_open.unlock();
1685.2.14 by Brian Aker
Use boost for the main lock we use in schema creation/alteration.
277
278
1 by brian
clean slate
279
      error= -1;
1685.2.14 by Brian Aker
Use boost for the main lock we use in schema creation/alteration.
280
      deleted= drop_tables_via_filenames(session, schema_identifier, dropped_tables);
281
      if (deleted >= 0)
282
      {
283
        error= 0;
284
      }
1 by brian
clean slate
285
    }
1259.3.3 by Monty Taylor
Removed last use of my_dir.
286
    if (deleted >= 0)
1 by brian
clean slate
287
    {
1685.2.14 by Brian Aker
Use boost for the main lock we use in schema creation/alteration.
288
      assert(! session->query.empty());
289
290
      TransactionServices &transaction_services= TransactionServices::singleton();
291
      transaction_services.dropSchema(session, schema_identifier.getSchemaName());
292
      session->clear_error();
293
      session->server_status|= SERVER_STATUS_DB_DROPPED;
294
      session->my_ok((uint32_t) deleted);
295
      session->server_status&= ~SERVER_STATUS_DB_DROPPED;
1 by brian
clean slate
296
    }
1685.2.14 by Brian Aker
Use boost for the main lock we use in schema creation/alteration.
297
    else
1 by brian
clean slate
298
    {
1685.2.14 by Brian Aker
Use boost for the main lock we use in schema creation/alteration.
299
      char *query, *query_pos, *query_end, *query_data_start;
300
301
      if (!(query= (char*) session->alloc(MAX_DROP_TABLE_Q_LEN)))
302
        goto exit; /* not much else we can do */
303
      query_pos= query_data_start= strcpy(query,"drop table ")+11;
304
      query_end= query + MAX_DROP_TABLE_Q_LEN;
305
306
      TransactionServices &transaction_services= TransactionServices::singleton();
307
      for (TableIdentifiers::iterator it= dropped_tables.begin();
308
           it != dropped_tables.end();
309
           it++)
310
      {
311
        uint32_t tbl_name_len;
312
313
        /* 3 for the quotes and the comma*/
314
        tbl_name_len= (*it).getTableName().length() + 3;
315
        if (query_pos + tbl_name_len + 1 >= query_end)
316
        {
317
          /* These DDL methods and logging protected with LOCK_create_db */
318
          transaction_services.rawStatement(session, query);
319
          query_pos= query_data_start;
320
        }
321
322
        *query_pos++ = '`';
323
        query_pos= strcpy(query_pos, (*it).getTableName().c_str()) + (tbl_name_len-3);
324
        *query_pos++ = '`';
325
        *query_pos++ = ',';
326
      }
327
328
      if (query_pos != query_data_start)
1 by brian
clean slate
329
      {
971.3.2 by Eric Day
Renamed LOCK_drizzleclient_create_db to LOCK_create_db since this has nothing to do with drizzleclient. I think Monty accidently got this during the drizzleclient rename.
330
        /* These DDL methods and logging protected with LOCK_create_db */
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.
331
        transaction_services.rawStatement(session, query);
1 by brian
clean slate
332
      }
1685.2.14 by Brian Aker
Use boost for the main lock we use in schema creation/alteration.
333
    }
1 by brian
clean slate
334
335
exit:
1685.2.14 by Brian Aker
Use boost for the main lock we use in schema creation/alteration.
336
    /*
337
      If this database was the client's selected database, we silently
338
      change the client's selected database to nothing (to have an empty
339
      SELECT DATABASE() in the future). For this we free() session->db and set
340
      it to 0.
341
    */
342
    if (schema_identifier.compare(session->db))
343
      mysql_change_db_impl(session);
344
  }
345
520.1.22 by Brian Aker
Second pass of thd cleanup
346
  start_waiting_global_read_lock(session);
1309.1.8 by Brian Aker
Modest update to drop schema.
347
1259.3.3 by Monty Taylor
Removed last use of my_dir.
348
  return error;
1 by brian
clean slate
349
}
350
1223.4.10 by Brian Aker
Split remove table into 2 parts. The piece for dropDatabase() needs to be
351
352
static int rm_table_part2(Session *session, TableList *tables)
353
{
1736.2.1 by Joseph Daly
remove write_bin_log_drop_table and use transaction_services
354
  TransactionServices &transaction_services= TransactionServices::singleton();
355
1223.4.10 by Brian Aker
Split remove table into 2 parts. The piece for dropDatabase() needs to be
356
  TableList *table;
357
  String wrong_tables;
358
  int error= 0;
359
  bool foreign_key_error= false;
360
1689.2.7 by Brian Aker
LOCK_open to boost.
361
  LOCK_open.lock(); /* Part 2 of rm a table */
1223.4.10 by Brian Aker
Split remove table into 2 parts. The piece for dropDatabase() needs to be
362
363
  /*
364
    If we have the table in the definition cache, we don't have to check the
365
    .frm cursor to find if the table is a normal table (not view) and what
366
    engine to use.
367
  */
368
369
  for (table= tables; table; table= table->next_local)
370
  {
1371 by Brian Aker
Small corrections.
371
    TableIdentifier identifier(table->db, table->table_name);
1223.4.10 by Brian Aker
Split remove table into 2 parts. The piece for dropDatabase() needs to be
372
    TableShare *share;
1637.2.6 by Vijay Samuel
Merge encapsulate TableList-1.
373
    table->setDbType(NULL);
1371 by Brian Aker
Small corrections.
374
    if ((share= TableShare::getShare(identifier)))
375
    {
1637.2.6 by Vijay Samuel
Merge encapsulate TableList-1.
376
      table->setDbType(share->db_type());
1371 by Brian Aker
Small corrections.
377
    }
1223.4.10 by Brian Aker
Split remove table into 2 parts. The piece for dropDatabase() needs to be
378
  }
379
380
  if (lock_table_names_exclusively(session, tables))
381
  {
1689.2.7 by Brian Aker
LOCK_open to boost.
382
    LOCK_open.unlock();
1223.4.10 by Brian Aker
Split remove table into 2 parts. The piece for dropDatabase() needs to be
383
    return 1;
384
  }
385
386
  /* Don't give warnings for not found errors, as we already generate notes */
387
  session->no_warnings_for_error= 1;
388
389
  for (table= tables; table; table= table->next_local)
390
  {
391
    char *db=table->db;
392
    plugin::StorageEngine *table_type;
393
394
    error= session->drop_temporary_table(table);
395
396
    switch (error) {
397
    case  0:
398
      // removed temporary table
399
      continue;
400
    case -1:
401
      error= 1;
1680.6.2 by Brian Aker
Remove goto within locking code.
402
      unlock_table_names(tables, NULL);
1689.2.7 by Brian Aker
LOCK_open to boost.
403
      LOCK_open.unlock();
1680.6.2 by Brian Aker
Remove goto within locking code.
404
      session->no_warnings_for_error= 0;
405
406
      return(error);
1223.4.10 by Brian Aker
Split remove table into 2 parts. The piece for dropDatabase() needs to be
407
    default:
408
      // temporary table not found
409
      error= 0;
410
    }
411
1637.2.6 by Vijay Samuel
Merge encapsulate TableList-1.
412
    table_type= table->getDbType();
1223.4.10 by Brian Aker
Split remove table into 2 parts. The piece for dropDatabase() needs to be
413
1618 by Brian Aker
This is a rollup set of patches for modifications to TableIdentifier to have
414
    TableIdentifier identifier(db, table->table_name);
415
1223.4.10 by Brian Aker
Split remove table into 2 parts. The piece for dropDatabase() needs to be
416
    {
417
      Table *locked_table;
1669 by Brian Aker
This patch turns the table_cache into boost::unordered_multimap.
418
      abort_locked_tables(session, identifier);
1618 by Brian Aker
This is a rollup set of patches for modifications to TableIdentifier to have
419
      remove_table_from_cache(session, identifier,
1223.4.10 by Brian Aker
Split remove table into 2 parts. The piece for dropDatabase() needs to be
420
                              RTFC_WAIT_OTHER_THREAD_FLAG |
421
                              RTFC_CHECK_KILLED_FLAG);
422
      /*
423
        If the table was used in lock tables, remember it so that
424
        unlock_table_names can free it
425
      */
1669 by Brian Aker
This patch turns the table_cache into boost::unordered_multimap.
426
      if ((locked_table= drop_locked_tables(session, identifier)))
1223.4.10 by Brian Aker
Split remove table into 2 parts. The piece for dropDatabase() needs to be
427
        table->table= locked_table;
428
429
      if (session->killed)
430
      {
431
        error= -1;
1680.6.2 by Brian Aker
Remove goto within locking code.
432
        unlock_table_names(tables, NULL);
1689.2.7 by Brian Aker
LOCK_open to boost.
433
        LOCK_open.unlock();
1680.6.2 by Brian Aker
Remove goto within locking code.
434
        session->no_warnings_for_error= 0;
435
436
        return(error);
1223.4.10 by Brian Aker
Split remove table into 2 parts. The piece for dropDatabase() needs to be
437
      }
438
    }
1415 by Brian Aker
Mass overhaul to use schema_identifier.
439
    identifier.getPath();
1223.4.11 by Brian Aker
Modifications to use mysql_rm_table
440
1309.1.26 by Brian Aker
Small conversion for does()
441
    if (table_type == NULL && not plugin::StorageEngine::doesTableExist(*session, identifier))
1223.4.10 by Brian Aker
Split remove table into 2 parts. The piece for dropDatabase() needs to be
442
    {
443
      // Table was not found on disk and table can't be created from engine
444
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
445
                          ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR),
446
                          table->table_name);
447
    }
448
    else
449
    {
1309.1.29 by Brian Aker
We must walk, before we can run.
450
      error= plugin::StorageEngine::dropTable(*session, identifier);
1223.4.11 by Brian Aker
Modifications to use mysql_rm_table
451
1223.4.10 by Brian Aker
Split remove table into 2 parts. The piece for dropDatabase() needs to be
452
      if ((error == ENOENT || error == HA_ERR_NO_SUCH_TABLE))
453
      {
454
	error= 0;
455
        session->clear_error();
456
      }
457
458
      if (error == HA_ERR_ROW_IS_REFERENCED)
459
      {
460
        /* the table is referenced by a foreign key constraint */
461
        foreign_key_error= true;
462
      }
463
    }
464
465
    if (error == 0 || (foreign_key_error == false))
1736.2.1 by Joseph Daly
remove write_bin_log_drop_table and use transaction_services
466
    {
467
      transaction_services.dropTable(session, string(db), string(table->table_name), true);
468
    }
1223.4.10 by Brian Aker
Split remove table into 2 parts. The piece for dropDatabase() needs to be
469
470
    if (error)
471
    {
472
      if (wrong_tables.length())
473
        wrong_tables.append(',');
474
      wrong_tables.append(String(table->table_name,system_charset_info));
475
    }
476
  }
477
  /*
478
    It's safe to unlock LOCK_open: we have an exclusive lock
479
    on the table name.
480
  */
1689.2.7 by Brian Aker
LOCK_open to boost.
481
  LOCK_open.unlock();
1223.4.10 by Brian Aker
Split remove table into 2 parts. The piece for dropDatabase() needs to be
482
  error= 0;
483
  if (wrong_tables.length())
484
  {
1309.2.19 by Brian Aker
Removing cerr call, and fixed bug where tables might not be dropped if there
485
    if (not foreign_key_error)
1223.4.10 by Brian Aker
Split remove table into 2 parts. The piece for dropDatabase() needs to be
486
      my_printf_error(ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR), MYF(0),
487
                      wrong_tables.c_ptr());
488
    else
489
    {
490
      my_message(ER_ROW_IS_REFERENCED, ER(ER_ROW_IS_REFERENCED), MYF(0));
491
    }
492
    error= 1;
493
  }
494
1689.2.7 by Brian Aker
LOCK_open to boost.
495
  LOCK_open.lock(); /* final bit in rm table lock */
1223.4.10 by Brian Aker
Split remove table into 2 parts. The piece for dropDatabase() needs to be
496
  unlock_table_names(tables, NULL);
1689.2.7 by Brian Aker
LOCK_open to boost.
497
  LOCK_open.unlock();
1223.4.10 by Brian Aker
Split remove table into 2 parts. The piece for dropDatabase() needs to be
498
  session->no_warnings_for_error= 0;
499
500
  return(error);
501
}
502
1 by brian
clean slate
503
/*
255 by Brian Aker
Removed RAID table delete point.
504
  Removes files with known extensions plus.
520.1.22 by Brian Aker
Second pass of thd cleanup
505
  session MUST be set when calling this function!
1 by brian
clean slate
506
*/
507
1601 by Brian Aker
Move functions to class methods.
508
static long drop_tables_via_filenames(Session *session,
509
                                      SchemaIdentifier &schema_identifier,
1663.1.3 by Brian Aker
Remove table names options.
510
                                      TableIdentifiers &dropped_tables)
1 by brian
clean slate
511
{
1039.1.3 by Brian Aker
Remove dead bits from db create/rm
512
  long deleted= 0;
513
  TableList *tot_list= NULL, **tot_list_next;
1 by brian
clean slate
514
515
  tot_list_next= &tot_list;
516
1663.1.4 by Brian Aker
Removed identifier bit
517
  plugin::StorageEngine::getIdentifiers(*session, schema_identifier, dropped_tables);
1309.1.10 by Brian Aker
Partial pass through replication code.
518
1663.1.3 by Brian Aker
Remove table names options.
519
  for (TableIdentifiers::iterator it= dropped_tables.begin();
1309.1.12 by Brian Aker
Cleanup of rm schema;
520
       it != dropped_tables.end();
521
       it++)
1 by brian
clean slate
522
  {
1415 by Brian Aker
Mass overhaul to use schema_identifier.
523
    size_t db_len= schema_identifier.getSchemaName().size();
1309.1.12 by Brian Aker
Cleanup of rm schema;
524
525
    /* Drop the table nicely */
526
    TableList *table_list=(TableList*)
527
      session->calloc(sizeof(*table_list) +
528
                      db_len + 1 +
1663.1.3 by Brian Aker
Remove table names options.
529
                      (*it).getTableName().length() + 1);
1309.1.12 by Brian Aker
Cleanup of rm schema;
530
531
    if (not table_list)
532
      return -1;
533
534
    table_list->db= (char*) (table_list+1);
1415 by Brian Aker
Mass overhaul to use schema_identifier.
535
    table_list->table_name= strcpy(table_list->db, schema_identifier.getSchemaName().c_str()) + db_len + 1;
1663.1.3 by Brian Aker
Remove table names options.
536
    TableIdentifier::filename_to_tablename((*it).getTableName().c_str(), table_list->table_name, (*it).getTableName().size() + 1);
1309.1.12 by Brian Aker
Cleanup of rm schema;
537
    table_list->alias= table_list->table_name;  // If lower_case_table_names=2
1663.1.3 by Brian Aker
Remove table names options.
538
    table_list->setInternalTmpTable((strncmp((*it).getTableName().c_str(),
1309.1.12 by Brian Aker
Cleanup of rm schema;
539
                                             TMP_FILE_PREFIX,
1637.2.6 by Vijay Samuel
Merge encapsulate TableList-1.
540
                                             strlen(TMP_FILE_PREFIX)) == 0));
1309.1.12 by Brian Aker
Cleanup of rm schema;
541
    /* Link into list */
542
    (*tot_list_next)= table_list;
543
    tot_list_next= &table_list->next_local;
544
    deleted++;
1 by brian
clean slate
545
  }
1223.4.10 by Brian Aker
Split remove table into 2 parts. The piece for dropDatabase() needs to be
546
  if (session->killed)
1259.3.3 by Monty Taylor
Removed last use of my_dir.
547
    return -1;
1 by brian
clean slate
548
1223.4.10 by Brian Aker
Split remove table into 2 parts. The piece for dropDatabase() needs to be
549
  if (tot_list)
550
  {
551
    if (rm_table_part2(session, tot_list))
1259.3.3 by Monty Taylor
Removed last use of my_dir.
552
      return -1;
1223.4.10 by Brian Aker
Split remove table into 2 parts. The piece for dropDatabase() needs to be
553
  }
554
1415 by Brian Aker
Mass overhaul to use schema_identifier.
555
556
  if (not plugin::StorageEngine::dropSchema(schema_identifier))
1060.1.1 by Eric Lambert
-removed rm_dir_w_symlink method call with rmdir since dir should not be a sym link in the first place.
557
  {
1415 by Brian Aker
Mass overhaul to use schema_identifier.
558
    my_error(ER_DROP_SCHEMA, MYF(0), schema_identifier.getSQLPath().c_str());
1034.1.5 by Brian Aker
Small refactor of db.cc
559
    return -1;
1060.1.1 by Eric Lambert
-removed rm_dir_w_symlink method call with rmdir since dir should not be a sym link in the first place.
560
  }
1 by brian
clean slate
561
1039.1.3 by Brian Aker
Remove dead bits from db create/rm
562
  return deleted;
1 by brian
clean slate
563
}
564
565
/**
566
  @brief Change the current database and its attributes unconditionally.
567
520.1.22 by Brian Aker
Second pass of thd cleanup
568
  @param session          thread handle
1 by brian
clean slate
569
  @param new_db_name  database name
51.1.51 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
570
  @param force_switch if force_switch is false, then the operation will fail if
1 by brian
clean slate
571
572
                        - new_db_name is NULL or empty;
573
574
                        - OR new database name is invalid
575
                          (check_db_name() failed);
576
577
                        - OR user has no privilege on the new database;
578
579
                        - OR new database does not exist;
580
51.1.51 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
581
                      if force_switch is true, then
1 by brian
clean slate
582
583
                        - if new_db_name is NULL or empty, the current
584
                          database will be NULL, @@collation_database will
585
                          be set to @@collation_server, the operation will
586
                          succeed.
587
588
                        - if new database name is invalid
589
                          (check_db_name() failed), the current database
590
                          will be NULL, @@collation_database will be set to
591
                          @@collation_server, but the operation will fail;
592
593
                        - user privileges will not be checked
520.1.21 by Brian Aker
THD -> Session rename
594
                          (Session::db_access however is updated);
1 by brian
clean slate
595
596
                          TODO: is this really the intention?
597
                                (see sp-security.test).
598
599
                        - if new database does not exist,the current database
600
                          will be NULL, @@collation_database will be set to
601
                          @@collation_server, a warning will be thrown, the
602
                          operation will succeed.
603
604
  @details The function checks that the database name corresponds to a
605
  valid and existent database, checks access rights and changes the current
606
  database with database attributes (@@collation_database session variable,
520.1.21 by Brian Aker
THD -> Session rename
607
  Session::db_access).
1 by brian
clean slate
608
609
  This function is not the only way to switch the database that is
610
  currently employed. When the replication slave thread switches the
520.1.22 by Brian Aker
Second pass of thd cleanup
611
  database before executing a query, it calls session->set_db directly.
1 by brian
clean slate
612
  However, if the query, in turn, uses a stored routine, the stored routine
613
  will use this function, even if it's run on the slave.
614
615
  This function allocates the name of the database on the system heap: this
616
  is necessary to be able to uniformly change the database from any module
617
  of the server. Up to 5.0 different modules were using different memory to
618
  store the name of the database, and this led to memory corruption:
619
  a stack pointer set by Stored Procedures was used by replication after
620
  the stack address was long gone.
621
622
  @return Operation status
51.1.51 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
623
    @retval false Success
624
    @retval true  Error
1 by brian
clean slate
625
*/
626
1415 by Brian Aker
Mass overhaul to use schema_identifier.
627
bool mysql_change_db(Session *session, SchemaIdentifier &schema_identifier)
1 by brian
clean slate
628
{
629
1415 by Brian Aker
Mass overhaul to use schema_identifier.
630
  if (not plugin::Authorization::isAuthorized(session->getSecurityContext(), schema_identifier))
1317.2.2 by Monty Taylor
Prevent unauthorized users from changing schema.
631
  {
632
    /* Error message is set in isAuthorized */
633
    return true;
634
  }
635
1578.4.11 by Brian Aker
PAss through the code removing current_session
636
  if (not check_db_name(session, schema_identifier))
1 by brian
clean slate
637
  {
1415 by Brian Aker
Mass overhaul to use schema_identifier.
638
    my_error(ER_WRONG_DB_NAME, MYF(0), schema_identifier.getSQLPath().c_str());
1 by brian
clean slate
639
1014.3.3 by Brian Aker
Formating fix.
640
    return true;
1 by brian
clean slate
641
  }
642
1415 by Brian Aker
Mass overhaul to use schema_identifier.
643
  if (not plugin::StorageEngine::doesSchemaExist(schema_identifier))
1 by brian
clean slate
644
  {
1309.1.9 by Brian Aker
Baby steps.
645
    /* Report an error and free new_db_file_name. */
646
1415 by Brian Aker
Mass overhaul to use schema_identifier.
647
    my_error(ER_BAD_DB_ERROR, MYF(0), schema_identifier.getSQLPath().c_str());
1309.1.9 by Brian Aker
Baby steps.
648
649
    /* The operation failed. */
650
651
    return true;
1 by brian
clean slate
652
  }
653
1415 by Brian Aker
Mass overhaul to use schema_identifier.
654
  mysql_change_db_impl(session, schema_identifier);
1 by brian
clean slate
655
1014.3.3 by Brian Aker
Formating fix.
656
  return false;
1 by brian
clean slate
657
}
658
1273 by Brian Aker
Revert db patch.
659
/**
660
  @brief Internal implementation: switch current database to a valid one.
661
662
  @param session            Thread context.
663
  @param new_db_name    Name of the database to switch to. The function will
664
                        take ownership of the name (the caller must not free
665
                        the allocated memory). If the name is NULL, we're
666
                        going to switch to NULL db.
667
  @param new_db_charset Character set of the new database.
668
*/
669
1415 by Brian Aker
Mass overhaul to use schema_identifier.
670
static void mysql_change_db_impl(Session *session, SchemaIdentifier &schema_identifier)
1235.4.18 by Stewart Smith
replace check_db_dir_existence() with class DatabasePathName and a ::exists() method.
671
{
1273 by Brian Aker
Revert db patch.
672
  /* 1. Change current database in Session. */
673
1415 by Brian Aker
Mass overhaul to use schema_identifier.
674
#if 0
1273 by Brian Aker
Revert db patch.
675
  if (new_db_name == NULL)
676
  {
677
    /*
678
      Session::set_db() does all the job -- it frees previous database name and
679
      sets the new one.
680
    */
681
682
    session->set_db(NULL, 0);
683
  }
684
  else
1415 by Brian Aker
Mass overhaul to use schema_identifier.
685
#endif
1273 by Brian Aker
Revert db patch.
686
  {
687
    /*
688
      Here we already have a copy of database name to be used in Session. So,
689
      we just call Session::reset_db(). Since Session::reset_db() does not releases
690
      the previous database name, we should do it explicitly.
691
    */
692
1685.2.12 by Brian Aker
This fixes the lower casing of names from Schema even when we should not.
693
    session->set_db(schema_identifier.getSchemaName());
1273 by Brian Aker
Revert db patch.
694
  }
1235.4.18 by Stewart Smith
replace check_db_dir_existence() with class DatabasePathName and a ::exists() method.
695
}
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
696
1415 by Brian Aker
Mass overhaul to use schema_identifier.
697
static void mysql_change_db_impl(Session *session)
698
{
699
  session->set_db(string());
700
}
701
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
702
} /* namespace drizzled */