~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
1802.10.2 by Monty Taylor
Update all of the copyright headers to include the correct address.
14
   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
1 by brian
clean slate
15
16
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
    }
1856.2.8 by Joseph Daly
working alter, drop, create schema
133
    else if (not plugin::StorageEngine::createSchema(schema_message)) // Try to create it 
1685.2.14 by Brian Aker
Use boost for the main lock we use in schema creation/alteration.
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 */
1877.2.8 by Brian Aker
Additional encapsulation
275
      table::Cache::singleton().removeSchema(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
  if (lock_table_names_exclusively(session, tables))
364
  {
1689.2.7 by Brian Aker
LOCK_open to boost.
365
    LOCK_open.unlock();
1223.4.10 by Brian Aker
Split remove table into 2 parts. The piece for dropDatabase() needs to be
366
    return 1;
367
  }
368
369
  /* Don't give warnings for not found errors, as we already generate notes */
370
  session->no_warnings_for_error= 1;
371
372
  for (table= tables; table; table= table->next_local)
373
  {
1874.1.1 by Brian Aker
Encapsulate schema_name it table_list.
374
    const char *db=table->getSchemaName();
1874.1.2 by Brian Aker
Encapsulate table_name from table_list.
375
    TableIdentifier identifier(table->getSchemaName(), table->getTableName());
1864.3.14 by Brian Aker
Remove cases where we do not use an identifier to find/delete temp tables,
376
1223.4.10 by Brian Aker
Split remove table into 2 parts. The piece for dropDatabase() needs to be
377
    plugin::StorageEngine *table_type;
378
1864.3.14 by Brian Aker
Remove cases where we do not use an identifier to find/delete temp tables,
379
    error= session->drop_temporary_table(identifier);
1223.4.10 by Brian Aker
Split remove table into 2 parts. The piece for dropDatabase() needs to be
380
381
    switch (error) {
382
    case  0:
383
      // removed temporary table
384
      continue;
385
    case -1:
386
      error= 1;
1680.6.2 by Brian Aker
Remove goto within locking code.
387
      unlock_table_names(tables, NULL);
1689.2.7 by Brian Aker
LOCK_open to boost.
388
      LOCK_open.unlock();
1680.6.2 by Brian Aker
Remove goto within locking code.
389
      session->no_warnings_for_error= 0;
390
391
      return(error);
1223.4.10 by Brian Aker
Split remove table into 2 parts. The piece for dropDatabase() needs to be
392
    default:
393
      // temporary table not found
394
      error= 0;
395
    }
396
1637.2.6 by Vijay Samuel
Merge encapsulate TableList-1.
397
    table_type= table->getDbType();
1223.4.10 by Brian Aker
Split remove table into 2 parts. The piece for dropDatabase() needs to be
398
399
    {
400
      Table *locked_table;
1669 by Brian Aker
This patch turns the table_cache into boost::unordered_multimap.
401
      abort_locked_tables(session, identifier);
1877.2.8 by Brian Aker
Additional encapsulation
402
      table::Cache::singleton().removeTable(session, identifier,
403
                                            RTFC_WAIT_OTHER_THREAD_FLAG |
404
                                            RTFC_CHECK_KILLED_FLAG);
1223.4.10 by Brian Aker
Split remove table into 2 parts. The piece for dropDatabase() needs to be
405
      /*
406
        If the table was used in lock tables, remember it so that
407
        unlock_table_names can free it
408
      */
1669 by Brian Aker
This patch turns the table_cache into boost::unordered_multimap.
409
      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
410
        table->table= locked_table;
411
412
      if (session->killed)
413
      {
414
        error= -1;
1680.6.2 by Brian Aker
Remove goto within locking code.
415
        unlock_table_names(tables, NULL);
1689.2.7 by Brian Aker
LOCK_open to boost.
416
        LOCK_open.unlock();
1680.6.2 by Brian Aker
Remove goto within locking code.
417
        session->no_warnings_for_error= 0;
418
419
        return(error);
1223.4.10 by Brian Aker
Split remove table into 2 parts. The piece for dropDatabase() needs to be
420
      }
421
    }
1415 by Brian Aker
Mass overhaul to use schema_identifier.
422
    identifier.getPath();
1223.4.11 by Brian Aker
Modifications to use mysql_rm_table
423
1309.1.26 by Brian Aker
Small conversion for does()
424
    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
425
    {
426
      // Table was not found on disk and table can't be created from engine
427
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
428
                          ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR),
1874.1.2 by Brian Aker
Encapsulate table_name from table_list.
429
                          table->getTableName());
1223.4.10 by Brian Aker
Split remove table into 2 parts. The piece for dropDatabase() needs to be
430
    }
431
    else
432
    {
1309.1.29 by Brian Aker
We must walk, before we can run.
433
      error= plugin::StorageEngine::dropTable(*session, identifier);
1223.4.11 by Brian Aker
Modifications to use mysql_rm_table
434
1223.4.10 by Brian Aker
Split remove table into 2 parts. The piece for dropDatabase() needs to be
435
      if ((error == ENOENT || error == HA_ERR_NO_SUCH_TABLE))
436
      {
437
	error= 0;
438
        session->clear_error();
439
      }
440
441
      if (error == HA_ERR_ROW_IS_REFERENCED)
442
      {
443
        /* the table is referenced by a foreign key constraint */
444
        foreign_key_error= true;
445
      }
446
    }
447
448
    if (error == 0 || (foreign_key_error == false))
1736.2.1 by Joseph Daly
remove write_bin_log_drop_table and use transaction_services
449
    {
1874.1.2 by Brian Aker
Encapsulate table_name from table_list.
450
      transaction_services.dropTable(session, string(db), string(table->getTableName()), true);
1736.2.1 by Joseph Daly
remove write_bin_log_drop_table and use transaction_services
451
    }
1223.4.10 by Brian Aker
Split remove table into 2 parts. The piece for dropDatabase() needs to be
452
453
    if (error)
454
    {
455
      if (wrong_tables.length())
456
        wrong_tables.append(',');
1874.1.2 by Brian Aker
Encapsulate table_name from table_list.
457
      wrong_tables.append(String(table->getTableName(),system_charset_info));
1223.4.10 by Brian Aker
Split remove table into 2 parts. The piece for dropDatabase() needs to be
458
    }
459
  }
460
  /*
461
    It's safe to unlock LOCK_open: we have an exclusive lock
462
    on the table name.
463
  */
1689.2.7 by Brian Aker
LOCK_open to boost.
464
  LOCK_open.unlock();
1223.4.10 by Brian Aker
Split remove table into 2 parts. The piece for dropDatabase() needs to be
465
  error= 0;
466
  if (wrong_tables.length())
467
  {
1309.2.19 by Brian Aker
Removing cerr call, and fixed bug where tables might not be dropped if there
468
    if (not foreign_key_error)
1223.4.10 by Brian Aker
Split remove table into 2 parts. The piece for dropDatabase() needs to be
469
      my_printf_error(ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR), MYF(0),
470
                      wrong_tables.c_ptr());
471
    else
472
    {
473
      my_message(ER_ROW_IS_REFERENCED, ER(ER_ROW_IS_REFERENCED), MYF(0));
474
    }
475
    error= 1;
476
  }
477
1689.2.7 by Brian Aker
LOCK_open to boost.
478
  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
479
  unlock_table_names(tables, NULL);
1689.2.7 by Brian Aker
LOCK_open to boost.
480
  LOCK_open.unlock();
1223.4.10 by Brian Aker
Split remove table into 2 parts. The piece for dropDatabase() needs to be
481
  session->no_warnings_for_error= 0;
482
483
  return(error);
484
}
485
1 by brian
clean slate
486
/*
255 by Brian Aker
Removed RAID table delete point.
487
  Removes files with known extensions plus.
520.1.22 by Brian Aker
Second pass of thd cleanup
488
  session MUST be set when calling this function!
1 by brian
clean slate
489
*/
490
1601 by Brian Aker
Move functions to class methods.
491
static long drop_tables_via_filenames(Session *session,
492
                                      SchemaIdentifier &schema_identifier,
1663.1.3 by Brian Aker
Remove table names options.
493
                                      TableIdentifiers &dropped_tables)
1 by brian
clean slate
494
{
1039.1.3 by Brian Aker
Remove dead bits from db create/rm
495
  long deleted= 0;
496
  TableList *tot_list= NULL, **tot_list_next;
1 by brian
clean slate
497
498
  tot_list_next= &tot_list;
499
1663.1.4 by Brian Aker
Removed identifier bit
500
  plugin::StorageEngine::getIdentifiers(*session, schema_identifier, dropped_tables);
1309.1.10 by Brian Aker
Partial pass through replication code.
501
1663.1.3 by Brian Aker
Remove table names options.
502
  for (TableIdentifiers::iterator it= dropped_tables.begin();
1309.1.12 by Brian Aker
Cleanup of rm schema;
503
       it != dropped_tables.end();
504
       it++)
1 by brian
clean slate
505
  {
1415 by Brian Aker
Mass overhaul to use schema_identifier.
506
    size_t db_len= schema_identifier.getSchemaName().size();
1309.1.12 by Brian Aker
Cleanup of rm schema;
507
508
    /* Drop the table nicely */
509
    TableList *table_list=(TableList*)
510
      session->calloc(sizeof(*table_list) +
511
                      db_len + 1 +
1663.1.3 by Brian Aker
Remove table names options.
512
                      (*it).getTableName().length() + 1);
1309.1.12 by Brian Aker
Cleanup of rm schema;
513
514
    if (not table_list)
515
      return -1;
516
1874.1.1 by Brian Aker
Encapsulate schema_name it table_list.
517
    table_list->setSchemaName((char*) (table_list+1));
1874.1.2 by Brian Aker
Encapsulate table_name from table_list.
518
    table_list->setTableName(strcpy((char*) (table_list+1), schema_identifier.getSchemaName().c_str()) + db_len + 1);
519
    TableIdentifier::filename_to_tablename((*it).getTableName().c_str(), const_cast<char *>(table_list->getTableName()), (*it).getTableName().size() + 1);
520
    table_list->alias= table_list->getTableName();  // If lower_case_table_names=2
1663.1.3 by Brian Aker
Remove table names options.
521
    table_list->setInternalTmpTable((strncmp((*it).getTableName().c_str(),
1309.1.12 by Brian Aker
Cleanup of rm schema;
522
                                             TMP_FILE_PREFIX,
1637.2.6 by Vijay Samuel
Merge encapsulate TableList-1.
523
                                             strlen(TMP_FILE_PREFIX)) == 0));
1309.1.12 by Brian Aker
Cleanup of rm schema;
524
    /* Link into list */
525
    (*tot_list_next)= table_list;
526
    tot_list_next= &table_list->next_local;
527
    deleted++;
1 by brian
clean slate
528
  }
1223.4.10 by Brian Aker
Split remove table into 2 parts. The piece for dropDatabase() needs to be
529
  if (session->killed)
1259.3.3 by Monty Taylor
Removed last use of my_dir.
530
    return -1;
1 by brian
clean slate
531
1223.4.10 by Brian Aker
Split remove table into 2 parts. The piece for dropDatabase() needs to be
532
  if (tot_list)
533
  {
534
    if (rm_table_part2(session, tot_list))
1259.3.3 by Monty Taylor
Removed last use of my_dir.
535
      return -1;
1223.4.10 by Brian Aker
Split remove table into 2 parts. The piece for dropDatabase() needs to be
536
  }
537
1415 by Brian Aker
Mass overhaul to use schema_identifier.
538
539
  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.
540
  {
1415 by Brian Aker
Mass overhaul to use schema_identifier.
541
    my_error(ER_DROP_SCHEMA, MYF(0), schema_identifier.getSQLPath().c_str());
1034.1.5 by Brian Aker
Small refactor of db.cc
542
    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.
543
  }
1 by brian
clean slate
544
1039.1.3 by Brian Aker
Remove dead bits from db create/rm
545
  return deleted;
1 by brian
clean slate
546
}
547
548
/**
549
  @brief Change the current database and its attributes unconditionally.
550
520.1.22 by Brian Aker
Second pass of thd cleanup
551
  @param session          thread handle
1 by brian
clean slate
552
  @param new_db_name  database name
51.1.51 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
553
  @param force_switch if force_switch is false, then the operation will fail if
1 by brian
clean slate
554
555
                        - new_db_name is NULL or empty;
556
557
                        - OR new database name is invalid
558
                          (check_db_name() failed);
559
560
                        - OR user has no privilege on the new database;
561
562
                        - OR new database does not exist;
563
51.1.51 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
564
                      if force_switch is true, then
1 by brian
clean slate
565
566
                        - if new_db_name is NULL or empty, the current
567
                          database will be NULL, @@collation_database will
568
                          be set to @@collation_server, the operation will
569
                          succeed.
570
571
                        - if new database name is invalid
572
                          (check_db_name() failed), the current database
573
                          will be NULL, @@collation_database will be set to
574
                          @@collation_server, but the operation will fail;
575
576
                        - user privileges will not be checked
520.1.21 by Brian Aker
THD -> Session rename
577
                          (Session::db_access however is updated);
1 by brian
clean slate
578
579
                          TODO: is this really the intention?
580
                                (see sp-security.test).
581
582
                        - if new database does not exist,the current database
583
                          will be NULL, @@collation_database will be set to
584
                          @@collation_server, a warning will be thrown, the
585
                          operation will succeed.
586
587
  @details The function checks that the database name corresponds to a
588
  valid and existent database, checks access rights and changes the current
589
  database with database attributes (@@collation_database session variable,
520.1.21 by Brian Aker
THD -> Session rename
590
  Session::db_access).
1 by brian
clean slate
591
592
  This function is not the only way to switch the database that is
593
  currently employed. When the replication slave thread switches the
520.1.22 by Brian Aker
Second pass of thd cleanup
594
  database before executing a query, it calls session->set_db directly.
1 by brian
clean slate
595
  However, if the query, in turn, uses a stored routine, the stored routine
596
  will use this function, even if it's run on the slave.
597
598
  This function allocates the name of the database on the system heap: this
599
  is necessary to be able to uniformly change the database from any module
600
  of the server. Up to 5.0 different modules were using different memory to
601
  store the name of the database, and this led to memory corruption:
602
  a stack pointer set by Stored Procedures was used by replication after
603
  the stack address was long gone.
604
605
  @return Operation status
51.1.51 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
606
    @retval false Success
607
    @retval true  Error
1 by brian
clean slate
608
*/
609
1415 by Brian Aker
Mass overhaul to use schema_identifier.
610
bool mysql_change_db(Session *session, SchemaIdentifier &schema_identifier)
1 by brian
clean slate
611
{
612
1415 by Brian Aker
Mass overhaul to use schema_identifier.
613
  if (not plugin::Authorization::isAuthorized(session->getSecurityContext(), schema_identifier))
1317.2.2 by Monty Taylor
Prevent unauthorized users from changing schema.
614
  {
615
    /* Error message is set in isAuthorized */
616
    return true;
617
  }
618
1578.4.11 by Brian Aker
PAss through the code removing current_session
619
  if (not check_db_name(session, schema_identifier))
1 by brian
clean slate
620
  {
1415 by Brian Aker
Mass overhaul to use schema_identifier.
621
    my_error(ER_WRONG_DB_NAME, MYF(0), schema_identifier.getSQLPath().c_str());
1 by brian
clean slate
622
1014.3.3 by Brian Aker
Formating fix.
623
    return true;
1 by brian
clean slate
624
  }
625
1415 by Brian Aker
Mass overhaul to use schema_identifier.
626
  if (not plugin::StorageEngine::doesSchemaExist(schema_identifier))
1 by brian
clean slate
627
  {
1309.1.9 by Brian Aker
Baby steps.
628
    /* Report an error and free new_db_file_name. */
629
1415 by Brian Aker
Mass overhaul to use schema_identifier.
630
    my_error(ER_BAD_DB_ERROR, MYF(0), schema_identifier.getSQLPath().c_str());
1309.1.9 by Brian Aker
Baby steps.
631
632
    /* The operation failed. */
633
634
    return true;
1 by brian
clean slate
635
  }
636
1415 by Brian Aker
Mass overhaul to use schema_identifier.
637
  mysql_change_db_impl(session, schema_identifier);
1 by brian
clean slate
638
1014.3.3 by Brian Aker
Formating fix.
639
  return false;
1 by brian
clean slate
640
}
641
1273 by Brian Aker
Revert db patch.
642
/**
643
  @brief Internal implementation: switch current database to a valid one.
644
645
  @param session            Thread context.
646
  @param new_db_name    Name of the database to switch to. The function will
647
                        take ownership of the name (the caller must not free
648
                        the allocated memory). If the name is NULL, we're
649
                        going to switch to NULL db.
650
  @param new_db_charset Character set of the new database.
651
*/
652
1415 by Brian Aker
Mass overhaul to use schema_identifier.
653
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.
654
{
1273 by Brian Aker
Revert db patch.
655
  /* 1. Change current database in Session. */
656
1415 by Brian Aker
Mass overhaul to use schema_identifier.
657
#if 0
1273 by Brian Aker
Revert db patch.
658
  if (new_db_name == NULL)
659
  {
660
    /*
661
      Session::set_db() does all the job -- it frees previous database name and
662
      sets the new one.
663
    */
664
665
    session->set_db(NULL, 0);
666
  }
667
  else
1415 by Brian Aker
Mass overhaul to use schema_identifier.
668
#endif
1273 by Brian Aker
Revert db patch.
669
  {
670
    /*
671
      Here we already have a copy of database name to be used in Session. So,
672
      we just call Session::reset_db(). Since Session::reset_db() does not releases
673
      the previous database name, we should do it explicitly.
674
    */
675
1685.2.12 by Brian Aker
This fixes the lower casing of names from Schema even when we should not.
676
    session->set_db(schema_identifier.getSchemaName());
1273 by Brian Aker
Revert db patch.
677
  }
1235.4.18 by Stewart Smith
replace check_db_dir_existence() with class DatabasePathName and a ::exists() method.
678
}
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
679
1415 by Brian Aker
Mass overhaul to use schema_identifier.
680
static void mysql_change_db_impl(Session *session)
681
{
682
  session->set_db(string());
683
}
684
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
685
} /* namespace drizzled */