~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 */
2173.2.1 by Monty Taylor
Fixes incorrect usage of include
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
2159.2.5 by Brian Aker
Merge in move of schema.
28
#include <drizzled/error.h>
538 by Monty Taylor
Moved gettext.h into drizzled in anticipation of the new client lib.
29
#include <drizzled/gettext.h>
2159.2.5 by Brian Aker
Merge in move of schema.
30
#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.
31
#include <drizzled/session.h>
2159.2.5 by Brian Aker
Merge in move of schema.
32
#include <drizzled/schema.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/sql_base.h>
670.2.4 by Monty Taylor
Removed more stuff from the headers.
34
#include <drizzled/lock.h>
722.4.1 by Mark Atwood
integrate errmsg plugin into sql_print_* functions
35
#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.
36
#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.
37
#include <drizzled/message/schema.pb.h>
2159.2.5 by Brian Aker
Merge in move of schema.
38
#include <drizzled/sql_table.h>
39
#include <drizzled/plugin/storage_engine.h>
40
#include <drizzled/plugin/authorization.h>
41
#include <drizzled/pthread_globals.h>
42
#include <drizzled/charset.h>
43
#include <drizzled/internal/my_sys.h>
2241.3.14 by Olaf van der Spek
Refactor
44
#include <drizzled/catalog/instance.h>
1685.2.14 by Brian Aker
Use boost for the main lock we use in schema creation/alteration.
45
#include <boost/thread/mutex.hpp>
46
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
47
using namespace std;
48
2241.3.13 by Olaf van der Spek
Refactor Session
49
namespace drizzled {
50
namespace schema {
820.1.11 by Stewart Smith
re-introduce db.opt, but with parsing it from disk instead of in process cache with mutex.
51
1 by brian
clean slate
52
/*
53
  Create a database
54
55
  SYNOPSIS
2026.2.1 by Monty Taylor
Renamed things prefixed mysql_ or mysqld_
56
  create_db()
520.1.22 by Brian Aker
Second pass of thd cleanup
57
  session		Thread handler
1 by brian
clean slate
58
  db		Name of database to create
59
		Function assumes that this is already validated.
60
  create_info	Database create options (like character set)
61
62
  SIDE-EFFECTS
63
   1. Report back to client that command succeeded (my_ok)
64
   2. Report errors to client
65
   3. Log event to binary log
66
67
  RETURN VALUES
51.1.51 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
68
  false ok
69
  true  Error
1 by brian
clean slate
70
71
*/
72
2159.2.6 by Brian Aker
Finalize interface for schema.
73
bool create(Session &session, const message::Schema &schema_message, const bool is_if_not_exists)
1 by brian
clean slate
74
{
1039.1.3 by Brian Aker
Remove dead bits from db create/rm
75
  bool error= false;
1235.4.14 by Stewart Smith
use message::Schema in mysql_create_db instead of HA_CREATE_INFO
76
1 by brian
clean slate
77
  /*
78
    Do not create database if another thread is holding read lock.
2060.4.2 by Brian Aker
A few small fixes, plus move the schema lock to the actual catalog.
79
    Wait for global read lock before acquiring session->catalog()->schemaLock().
1 by brian
clean slate
80
    After wait_if_global_read_lock() we have protection against another
2060.4.2 by Brian Aker
A few small fixes, plus move the schema lock to the actual catalog.
81
    global read lock. If we would acquire session->catalog()->schemaLock() first,
1 by brian
clean slate
82
    another thread could step in and get the global read lock before we
83
    reach wait_if_global_read_lock(). If this thread tries the same as we
2060.4.2 by Brian Aker
A few small fixes, plus move the schema lock to the actual catalog.
84
    (admin a db), it would then go and wait on session->catalog()->schemaLock()...
1 by brian
clean slate
85
    Furthermore wait_if_global_read_lock() checks if the current thread
86
    has the global read lock and refuses the operation with
87
    ER_CANT_UPDATE_WITH_READLOCK if applicable.
88
  */
2159.2.6 by Brian Aker
Finalize interface for schema.
89
  if (session.wait_if_global_read_lock(false, true))
1 by brian
clean slate
90
  {
1273.19.25 by Brian Aker
createSchema() now works via SE interface.
91
    return false;
1 by brian
clean slate
92
  }
93
1273.19.28 by Brian Aker
More cleanup on ALTER SCHEMA. Hey! MySQL never had errors on half of it...
94
  assert(schema_message.has_name());
95
  assert(schema_message.has_collation());
96
1273.19.25 by Brian Aker
createSchema() now works via SE interface.
97
  // @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.
98
  {
2159.2.6 by Brian Aker
Finalize interface for schema.
99
    boost::mutex::scoped_lock scopedLock(session.catalog().schemaLock());
1 by brian
clean slate
100
1685.2.14 by Brian Aker
Use boost for the main lock we use in schema creation/alteration.
101
    // Check to see if it exists already.  
2087.4.1 by Brian Aker
Merge in schema identifier.
102
    identifier::Schema schema_identifier(schema_message.name());
1685.2.14 by Brian Aker
Use boost for the main lock we use in schema creation/alteration.
103
    if (plugin::StorageEngine::doesSchemaExist(schema_identifier))
104
    {
105
      if (not is_if_not_exists)
106
      {
2041.3.15 by Brian Aker
Cleanup error usage around identifier usage.
107
        my_error(ER_DB_CREATE_EXISTS, schema_identifier);
1685.2.14 by Brian Aker
Use boost for the main lock we use in schema creation/alteration.
108
        error= true;
109
      }
110
      else
111
      {
2159.2.6 by Brian Aker
Finalize interface for schema.
112
        push_warning_printf(&session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
1685.2.14 by Brian Aker
Use boost for the main lock we use in schema creation/alteration.
113
                            ER_DB_CREATE_EXISTS, ER(ER_DB_CREATE_EXISTS),
114
                            schema_message.name().c_str());
2159.2.6 by Brian Aker
Finalize interface for schema.
115
        session.my_ok();
1685.2.14 by Brian Aker
Use boost for the main lock we use in schema creation/alteration.
116
      }
117
    }
1856.2.8 by Joseph Daly
working alter, drop, create schema
118
    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.
119
    {
120
      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.
121
      error= true;
122
    }
1685.2.14 by Brian Aker
Use boost for the main lock we use in schema creation/alteration.
123
    else // Created !
1273.19.25 by Brian Aker
createSchema() now works via SE interface.
124
    {
2318.6.62 by Olaf van der Spek
Refactor
125
      TransactionServices::createSchema(session, schema_message);
2159.2.6 by Brian Aker
Finalize interface for schema.
126
      session.my_ok(1);
1273.19.25 by Brian Aker
createSchema() now works via SE interface.
127
    }
128
  }
2159.2.6 by Brian Aker
Finalize interface for schema.
129
  session.startWaitingGlobalReadLock();
1273.19.25 by Brian Aker
createSchema() now works via SE interface.
130
1039.1.3 by Brian Aker
Remove dead bits from db create/rm
131
  return error;
1 by brian
clean slate
132
}
133
134
135
/* db-name is already validated when we come here */
136
2159.2.6 by Brian Aker
Finalize interface for schema.
137
bool alter(Session &session,
2159.2.5 by Brian Aker
Merge in move of schema.
138
           const message::Schema &schema_message,
2159.2.6 by Brian Aker
Finalize interface for schema.
139
           const message::Schema &original_schema)
1 by brian
clean slate
140
{
141
  /*
142
    Do not alter database if another thread is holding read lock.
2060.4.2 by Brian Aker
A few small fixes, plus move the schema lock to the actual catalog.
143
    Wait for global read lock before acquiring session->catalog()->schemaLock().
1 by brian
clean slate
144
    After wait_if_global_read_lock() we have protection against another
2060.4.2 by Brian Aker
A few small fixes, plus move the schema lock to the actual catalog.
145
    global read lock. If we would acquire session->catalog()->schemaLock() first,
1 by brian
clean slate
146
    another thread could step in and get the global read lock before we
147
    reach wait_if_global_read_lock(). If this thread tries the same as we
2060.4.2 by Brian Aker
A few small fixes, plus move the schema lock to the actual catalog.
148
    (admin a db), it would then go and wait on session->catalog()->schemaLock()...
1 by brian
clean slate
149
    Furthermore wait_if_global_read_lock() checks if the current thread
150
    has the global read lock and refuses the operation with
151
    ER_CANT_UPDATE_WITH_READLOCK if applicable.
152
  */
2159.2.6 by Brian Aker
Finalize interface for schema.
153
  if ((session.wait_if_global_read_lock(false, true)))
1273.19.26 by Brian Aker
Move Alter schema to SE interface.
154
    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.
155
1685.2.14 by Brian Aker
Use boost for the main lock we use in schema creation/alteration.
156
  bool success;
157
  {
2159.2.6 by Brian Aker
Finalize interface for schema.
158
    boost::mutex::scoped_lock scopedLock(session.catalog().schemaLock());
1685.2.14 by Brian Aker
Use boost for the main lock we use in schema creation/alteration.
159
2087.4.1 by Brian Aker
Merge in schema identifier.
160
    identifier::Schema schema_idenifier(schema_message.name());
1685.2.14 by Brian Aker
Use boost for the main lock we use in schema creation/alteration.
161
    if (not plugin::StorageEngine::doesSchemaExist(schema_idenifier))
162
    {
2041.3.15 by Brian Aker
Cleanup error usage around identifier usage.
163
      my_error(ER_SCHEMA_DOES_NOT_EXIST, schema_idenifier);
1685.2.14 by Brian Aker
Use boost for the main lock we use in schema creation/alteration.
164
      return false;
165
    }
166
167
    /* Change options if current database is being altered. */
168
    success= plugin::StorageEngine::alterSchema(schema_message);
169
170
    if (success)
171
    {
2318.6.62 by Olaf van der Spek
Refactor
172
      TransactionServices::alterSchema(session, original_schema, schema_message);
2159.2.6 by Brian Aker
Finalize interface for schema.
173
      session.my_ok(1);
1685.2.14 by Brian Aker
Use boost for the main lock we use in schema creation/alteration.
174
    }
175
    else
176
    {
2041.3.15 by Brian Aker
Cleanup error usage around identifier usage.
177
      my_error(ER_ALTER_SCHEMA, schema_idenifier);
1685.2.14 by Brian Aker
Use boost for the main lock we use in schema creation/alteration.
178
    }
179
  }
2159.2.6 by Brian Aker
Finalize interface for schema.
180
  session.startWaitingGlobalReadLock();
1273.19.26 by Brian Aker
Move Alter schema to SE interface.
181
182
  return success;
1 by brian
clean slate
183
}
184
185
186
/*
187
  Drop all tables in a database and the database itself
188
189
  SYNOPSIS
2026.2.1 by Monty Taylor
Renamed things prefixed mysql_ or mysqld_
190
    rm_db()
520.1.22 by Brian Aker
Second pass of thd cleanup
191
    session			Thread handle
1 by brian
clean slate
192
    db			Database name in the case given by user
193
		        It's already validated and set to lower case
194
                        (if needed) when we come here
195
    if_exists		Don't give error if database doesn't exists
196
    silent		Don't generate errors
197
198
  RETURN
51.1.51 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
199
    false ok (Database dropped)
1 by brian
clean slate
200
    ERROR Error
201
*/
202
2241.3.13 by Olaf van der Spek
Refactor Session
203
bool drop(Session &session, const identifier::Schema &schema_identifier, bool if_exists)
1 by brian
clean slate
204
{
205
  /*
206
    Do not drop database if another thread is holding read lock.
2060.4.2 by Brian Aker
A few small fixes, plus move the schema lock to the actual catalog.
207
    Wait for global read lock before acquiring session->catalog()->schemaLock().
1 by brian
clean slate
208
    After wait_if_global_read_lock() we have protection against another
2060.4.2 by Brian Aker
A few small fixes, plus move the schema lock to the actual catalog.
209
    global read lock. If we would acquire session->catalog()->schemaLock() first,
1 by brian
clean slate
210
    another thread could step in and get the global read lock before we
211
    reach wait_if_global_read_lock(). If this thread tries the same as we
2060.4.2 by Brian Aker
A few small fixes, plus move the schema lock to the actual catalog.
212
    (admin a db), it would then go and wait on session->catalog()->schemaLock()...
1 by brian
clean slate
213
    Furthermore wait_if_global_read_lock() checks if the current thread
214
    has the global read lock and refuses the operation with
215
    ER_CANT_UPDATE_WITH_READLOCK if applicable.
216
  */
2159.2.6 by Brian Aker
Finalize interface for schema.
217
  if (session.wait_if_global_read_lock(false, true))
1 by brian
clean slate
218
  {
2041.3.4 by Brian Aker
remove goto
219
    return true;
1 by brian
clean slate
220
  }
221
2246.4.2 by Olaf van der Spek
Refactor Identifier::getSQLPath()
222
  bool error= false;
1 by brian
clean slate
223
  {
2159.2.6 by Brian Aker
Finalize interface for schema.
224
    boost::mutex::scoped_lock scopedLock(session.catalog().schemaLock());
2246.4.2 by Olaf van der Spek
Refactor Identifier::getSQLPath()
225
    if (message::schema::shared_ptr message= plugin::StorageEngine::getSchemaDefinition(schema_identifier))
2288 by Brian Aker
Merge in Olaf
226
    {
227
      error= plugin::StorageEngine::dropSchema(session, schema_identifier, *message);
228
    }
229
    else if (if_exists)
1309.1.8 by Brian Aker
Modest update to drop schema.
230
    {
2246.4.2 by Olaf van der Spek
Refactor Identifier::getSQLPath()
231
      push_warning_printf(&session, DRIZZLE_ERROR::WARN_LEVEL_NOTE, ER_DB_DROP_EXISTS, ER(ER_DB_DROP_EXISTS),
2288 by Brian Aker
Merge in Olaf
232
                          schema_identifier.getSQLPath().c_str());
1309.1.8 by Brian Aker
Modest update to drop schema.
233
    }
234
    else
1 by brian
clean slate
235
    {
2246.4.2 by Olaf van der Spek
Refactor Identifier::getSQLPath()
236
      error= true;
237
      my_error(ER_DB_DROP_EXISTS, schema_identifier);
1 by brian
clean slate
238
    }
2246.4.2 by Olaf van der Spek
Refactor Identifier::getSQLPath()
239
  };
1685.2.14 by Brian Aker
Use boost for the main lock we use in schema creation/alteration.
240
2041.3.11 by Brian Aker
Only change schemas if we DROP the schema.
241
  /*
242
    If this database was the client's selected database, we silently
243
    change the client's selected database to nothing (to have an empty
244
    SELECT DATABASE() in the future). For this we free() session->db and set
245
    it to 0.
246
  */
2159.2.6 by Brian Aker
Finalize interface for schema.
247
  if (not error and schema_identifier.compare(*session.schema()))
2385.1.7 by Olaf van der Spek
Rename set_db to set_schema
248
    session.set_schema("");
2041.3.11 by Brian Aker
Only change schemas if we DROP the schema.
249
2159.2.6 by Brian Aker
Finalize interface for schema.
250
  session.startWaitingGlobalReadLock();
1309.1.8 by Brian Aker
Modest update to drop schema.
251
1259.3.3 by Monty Taylor
Removed last use of my_dir.
252
  return error;
1 by brian
clean slate
253
}
254
255
/**
256
  @brief Change the current database and its attributes unconditionally.
257
520.1.22 by Brian Aker
Second pass of thd cleanup
258
  @param session          thread handle
1 by brian
clean slate
259
  @param new_db_name  database name
51.1.51 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
260
  @param force_switch if force_switch is false, then the operation will fail if
1 by brian
clean slate
261
262
                        - new_db_name is NULL or empty;
263
264
                        - OR new database name is invalid
265
                          (check_db_name() failed);
266
267
                        - OR user has no privilege on the new database;
268
269
                        - OR new database does not exist;
270
51.1.51 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
271
                      if force_switch is true, then
1 by brian
clean slate
272
273
                        - if new_db_name is NULL or empty, the current
274
                          database will be NULL, @@collation_database will
275
                          be set to @@collation_server, the operation will
276
                          succeed.
277
278
                        - if new database name is invalid
279
                          (check_db_name() failed), the current database
280
                          will be NULL, @@collation_database will be set to
281
                          @@collation_server, but the operation will fail;
282
283
                        - user privileges will not be checked
520.1.21 by Brian Aker
THD -> Session rename
284
                          (Session::db_access however is updated);
1 by brian
clean slate
285
286
                          TODO: is this really the intention?
287
                                (see sp-security.test).
288
289
                        - if new database does not exist,the current database
290
                          will be NULL, @@collation_database will be set to
291
                          @@collation_server, a warning will be thrown, the
292
                          operation will succeed.
293
294
  @details The function checks that the database name corresponds to a
295
  valid and existent database, checks access rights and changes the current
296
  database with database attributes (@@collation_database session variable,
520.1.21 by Brian Aker
THD -> Session rename
297
  Session::db_access).
1 by brian
clean slate
298
299
  This function is not the only way to switch the database that is
300
  currently employed. When the replication slave thread switches the
520.1.22 by Brian Aker
Second pass of thd cleanup
301
  database before executing a query, it calls session->set_db directly.
1 by brian
clean slate
302
  However, if the query, in turn, uses a stored routine, the stored routine
303
  will use this function, even if it's run on the slave.
304
305
  This function allocates the name of the database on the system heap: this
306
  is necessary to be able to uniformly change the database from any module
307
  of the server. Up to 5.0 different modules were using different memory to
308
  store the name of the database, and this led to memory corruption:
309
  a stack pointer set by Stored Procedures was used by replication after
310
  the stack address was long gone.
311
312
  @return Operation status
51.1.51 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
313
    @retval false Success
314
    @retval true  Error
1 by brian
clean slate
315
*/
316
2241.3.13 by Olaf van der Spek
Refactor Session
317
bool change(Session &session, const identifier::Schema &schema_identifier)
1 by brian
clean slate
318
{
319
2159.2.7 by Brian Aker
Merge in shared ptr modification for auth (namely we don't take the hit for
320
  if (not plugin::Authorization::isAuthorized(*session.user(), schema_identifier))
1317.2.2 by Monty Taylor
Prevent unauthorized users from changing schema.
321
  {
322
    /* Error message is set in isAuthorized */
323
    return true;
324
  }
325
2159.2.6 by Brian Aker
Finalize interface for schema.
326
  if (not check(session, schema_identifier))
1 by brian
clean slate
327
  {
2041.3.15 by Brian Aker
Cleanup error usage around identifier usage.
328
    my_error(ER_WRONG_DB_NAME, schema_identifier);
1 by brian
clean slate
329
1014.3.3 by Brian Aker
Formating fix.
330
    return true;
1 by brian
clean slate
331
  }
332
1415 by Brian Aker
Mass overhaul to use schema_identifier.
333
  if (not plugin::StorageEngine::doesSchemaExist(schema_identifier))
1 by brian
clean slate
334
  {
2041.3.15 by Brian Aker
Cleanup error usage around identifier usage.
335
    my_error(ER_BAD_DB_ERROR, schema_identifier);
1309.1.9 by Brian Aker
Baby steps.
336
337
    /* The operation failed. */
338
339
    return true;
1 by brian
clean slate
340
  }
341
2385.1.7 by Olaf van der Spek
Rename set_db to set_schema
342
  session.set_schema(schema_identifier.getSchemaName());
1 by brian
clean slate
343
1014.3.3 by Brian Aker
Formating fix.
344
  return false;
1 by brian
clean slate
345
}
346
1273 by Brian Aker
Revert db patch.
347
/**
348
  @brief Internal implementation: switch current database to a valid one.
349
350
  @param session            Thread context.
351
  @param new_db_name    Name of the database to switch to. The function will
352
                        take ownership of the name (the caller must not free
353
                        the allocated memory). If the name is NULL, we're
354
                        going to switch to NULL db.
355
  @param new_db_charset Character set of the new database.
356
*/
357
2159.2.6 by Brian Aker
Finalize interface for schema.
358
359
/*
360
  Check if database name is valid
361
362
  SYNPOSIS
363
    check()
364
    org_name		Name of database and length
365
366
  RETURN
367
    false error
368
    true ok
369
*/
370
2241.3.13 by Olaf van der Spek
Refactor Session
371
bool check(Session &session, const identifier::Schema &schema_identifier)
2159.2.6 by Brian Aker
Finalize interface for schema.
372
{
2159.2.7 by Brian Aker
Merge in shared ptr modification for auth (namely we don't take the hit for
373
  if (not plugin::Authorization::isAuthorized(*session.user(), schema_identifier))
2159.2.6 by Brian Aker
Finalize interface for schema.
374
    return false;
375
  return schema_identifier.isValid();
1415 by Brian Aker
Mass overhaul to use schema_identifier.
376
}
377
2159.2.5 by Brian Aker
Merge in move of schema.
378
} /* namespace schema */
379
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
380
} /* namespace drizzled */