~drizzle-trunk/drizzle/development

575.1.5 by Monty Taylor
Moved stuff to handlerton.cc
1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3
 *
4
 *  Copyright (C) 2008 Sun Microsystems
5
 *
6
 *  This program is free software; you can redistribute it and/or modify
7
 *  it under the terms of the GNU General Public License as published by
8
 *  the Free Software Foundation; version 2 of the License.
9
 *
10
 *  This program is distributed in the hope that it will be useful,
11
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 *  GNU General Public License for more details.
14
 *
15
 *  You should have received a copy of the GNU General Public License
16
 *  along with this program; if not, write to the Free Software
17
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18
 */
19
1241.9.36 by Monty Taylor
ZOMG. I deleted drizzled/server_includes.h.
20
#include "config.h"
1130.1.12 by Monty Taylor
Moved service stuff into plugin/
21
1241.9.1 by Monty Taylor
Removed global.h. Fixed all the headers.
22
#include <fcntl.h>
23
#include <unistd.h>
24
1130.1.12 by Monty Taylor
Moved service stuff into plugin/
25
#include <string>
26
#include <vector>
1183.1.5 by Brian Aker
Reworked getTableNames() interface. Way simpler, less mallocs....
27
#include <set>
1395.1.8 by Brian Aker
Cleanup usage of TI so that the NULL ones no longer exist.
28
#include <fstream>
1130.1.12 by Monty Taylor
Moved service stuff into plugin/
29
#include <algorithm>
30
#include <functional>
31
32
#include <google/protobuf/io/zero_copy_stream.h>
33
#include <google/protobuf/io/zero_copy_stream_impl.h>
34
1241.9.44 by Monty Taylor
Made magic with cached_directory.
35
#include "drizzled/cached_directory.h"
1130.1.12 by Monty Taylor
Moved service stuff into plugin/
36
575.1.5 by Monty Taylor
Moved stuff to handlerton.cc
37
#include <drizzled/definitions.h>
38
#include <drizzled/base.h>
1183.1.2 by Brian Aker
Rename of handler to Cursor. You would not believe how long I have wanted
39
#include <drizzled/cursor.h>
960.2.23 by Monty Taylor
Moved handlerton to plugin/storage_engine.h.
40
#include <drizzled/plugin/storage_engine.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.
41
#include <drizzled/session.h>
575.1.5 by Monty Taylor
Moved stuff to handlerton.cc
42
#include <drizzled/error.h>
43
#include <drizzled/gettext.h>
971.1.37 by Monty Taylor
Another one bites the dust.
44
#include <drizzled/unireg.h>
971.1.38 by Monty Taylor
Moved delete table.
45
#include <drizzled/data_home.h>
1130.1.12 by Monty Taylor
Moved service stuff into plugin/
46
#include "drizzled/errmsg_print.h"
47
#include "drizzled/xid.h"
1241.9.23 by Monty Taylor
Removed sql_table.h from server_includes.h.
48
#include "drizzled/sql_table.h"
1241.9.28 by Monty Taylor
Removed global_charset_info.h from server_includes.h
49
#include "drizzled/global_charset_info.h"
1273.20.3 by Brian Aker
Fixing charset return.
50
#include "drizzled/charset.h"
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"
1273.13.9 by Brian Aker
Updating test cases + added Drizzle specific schema_names and schema_info.
52
#include "drizzled/db.h"
1241.9.28 by Monty Taylor
Removed global_charset_info.h from server_includes.h
53
1095.3.3 by Stewart Smith
move drizzle_proto_exists and drizzle_read_table_proto out of unireg.h and into table_proto.h
54
#include <drizzled/table_proto.h>
1502.5.7 by Barry.Leslie at PrimeBase
Renamed the 'Event' plugin to 'EventObserver' plugin along with some internal class renames to make things clearer.
55
#include <drizzled/plugin/event_observer.h>
1095.3.3 by Stewart Smith
move drizzle_proto_exists and drizzle_read_table_proto out of unireg.h and into table_proto.h
56
1859.2.9 by Brian Aker
We add a "shell" table type, used only during field creation.
57
#include <drizzled/table/shell.h>
58
1910.2.14 by Brian Aker
Check simple cache performance hit.
59
#include "drizzled/message/cache.h"
60
1685.2.10 by Brian Aker
Optimize the string comparison a bit.
61
#include <boost/algorithm/string/compare.hpp>
62
1217.1.3 by Brian Aker
Remove NameMap from Storage Engine. Modified the cleanup code to just do a
63
static bool shutdown_has_begun= false; // Once we put in the container for the vector/etc for engines this will go away.
64
960.2.44 by Monty Taylor
Removed legacy_db_type.
65
using namespace std;
1130.1.12 by Monty Taylor
Moved service stuff into plugin/
66
67
namespace drizzled
68
{
69
1273.1.15 by Jay Pipes
This patch completes the first step in the splitting of
70
namespace plugin
71
{
1217.1.3 by Brian Aker
Remove NameMap from Storage Engine. Modified the cleanup code to just do a
72
73
static EngineVector vector_of_engines;
1273.19.30 by Brian Aker
Performance patch... we now only cycle through engines that actually have
74
static EngineVector vector_of_schema_engines;
1217.1.3 by Brian Aker
Remove NameMap from Storage Engine. Modified the cleanup code to just do a
75
1685.2.10 by Brian Aker
Optimize the string comparison a bit.
76
const std::string DEFAULT_STRING("default");
1273.1.15 by Jay Pipes
This patch completes the first step in the splitting of
77
const std::string UNKNOWN_STRING("UNKNOWN");
78
const std::string DEFAULT_DEFINITION_FILE_EXT(".dfe");
1228.1.3 by Monty Taylor
All of the outstanding plugin loader system cleanups:
79
1183.1.27 by Brian Aker
Fix issue where there are too many files in data directory. We now only
80
static std::set<std::string> set_of_table_definition_ext;
1130.1.12 by Monty Taylor
Moved service stuff into plugin/
81
1415 by Brian Aker
Mass overhaul to use schema_identifier.
82
EngineVector &StorageEngine::getSchemaEngines()
83
{
84
  return vector_of_schema_engines;
85
}
86
1273.1.15 by Jay Pipes
This patch completes the first step in the splitting of
87
StorageEngine::StorageEngine(const string name_arg,
1372.1.4 by Brian Aker
Update to remove cache in enginges for per session (which also means... no
88
                             const bitset<HTON_BIT_SIZE> &flags_arg) :
89
  Plugin(name_arg, "StorageEngine"),
90
  MonitoredInTransaction(), /* This gives the storage engine a "slot" or ID */
91
  flags(flags_arg)
964.1.6 by Monty Taylor
Moved savepoint stuff to protected virtual methods, moved the offset to private, and moved the logic about adding the offset to the passed-in pointer and adding the offset to the global offset inside of the class.
92
{
93
}
94
1273.1.15 by Jay Pipes
This patch completes the first step in the splitting of
95
StorageEngine::~StorageEngine()
964.1.6 by Monty Taylor
Moved savepoint stuff to protected virtual methods, moved the offset to private, and moved the logic about adding the offset to the passed-in pointer and adding the offset to the global offset inside of the class.
96
{
97
}
98
1273.1.15 by Jay Pipes
This patch completes the first step in the splitting of
99
void StorageEngine::setTransactionReadWrite(Session& session)
1039.3.8 by Stewart Smith
Re-introduce marking transaction as read-write for engine on create_table:
100
{
1273.1.15 by Jay Pipes
This patch completes the first step in the splitting of
101
  TransactionContext &statement_ctx= session.transaction.stmt;
102
  statement_ctx.markModifiedNonTransData();
1039.3.8 by Stewart Smith
Re-introduce marking transaction as read-write for engine on create_table:
103
}
104
1389 by Brian Aker
Large reord in ALTER TABLE for RENAME.
105
1618.1.1 by Brian Aker
Modify TableIdentifier to be const
106
int StorageEngine::renameTable(Session &session, const TableIdentifier &from, const TableIdentifier &to)
1039.3.5 by Stewart Smith
move handler::rename_table to StorageEngine
107
{
1502.5.2 by Barry.Leslie at PrimeBase
Changes made to drizzle source when building in the events plugin.
108
  int error;
1389 by Brian Aker
Large reord in ALTER TABLE for RENAME.
109
  setTransactionReadWrite(session);
110
1502.5.8 by Barry.Leslie at PrimeBase
- Changed names to match the drizzle naming convention.
111
  if (unlikely(plugin::EventObserver::beforeRenameTable(session, from, to)))
1502.5.7 by Barry.Leslie at PrimeBase
Renamed the 'Event' plugin to 'EventObserver' plugin along with some internal class renames to make things clearer.
112
  {
113
    error= ER_EVENT_OBSERVER_PLUGIN;
114
  }
1502.5.2 by Barry.Leslie at PrimeBase
Changes made to drizzle source when building in the events plugin.
115
  else
116
  {
117
    error =  doRenameTable(session, from, to);
1502.5.8 by Barry.Leslie at PrimeBase
- Changed names to match the drizzle naming convention.
118
    if (unlikely(plugin::EventObserver::afterRenameTable(session, from, to, error)))
1502.5.7 by Barry.Leslie at PrimeBase
Renamed the 'Event' plugin to 'EventObserver' plugin along with some internal class renames to make things clearer.
119
    {
120
      error= ER_EVENT_OBSERVER_PLUGIN;
121
    }
1502.5.2 by Barry.Leslie at PrimeBase
Changes made to drizzle source when building in the events plugin.
122
  }
123
  
124
  return error;
1039.3.5 by Stewart Smith
move handler::rename_table to StorageEngine
125
}
126
1039.3.2 by Stewart Smith
move delete_table out of handler and up into StorageEngine where it belongs.
127
/**
128
  Delete all files with extension from bas_ext().
129
130
  @param name		Base name of table
131
132
  @note
1183.1.2 by Brian Aker
Rename of handler to Cursor. You would not believe how long I have wanted
133
    We assume that the Cursor may return more extensions than
1039.3.2 by Stewart Smith
move delete_table out of handler and up into StorageEngine where it belongs.
134
    was actually used for the file.
135
136
  @retval
137
    0   If we successfully deleted at least one file from base_ext and
138
    didn't get any other errors than ENOENT
139
  @retval
140
    !0  Error
141
*/
1618.1.1 by Brian Aker
Modify TableIdentifier to be const
142
int StorageEngine::doDropTable(Session&, const TableIdentifier &identifier)
1358.1.3 by Brian Aker
doDropTable() now only uses identifier.
143
                               
1039.3.2 by Stewart Smith
move delete_table out of handler and up into StorageEngine where it belongs.
144
{
145
  int error= 0;
146
  int enoent_or_zero= ENOENT;                   // Error if no file was deleted
147
  char buff[FN_REFLEN];
148
1183.1.21 by Brian Aker
Fixed temp engines to no longer write out DFE. I have two designs right now
149
  for (const char **ext= bas_ext(); *ext ; ext++)
1039.3.2 by Stewart Smith
move delete_table out of handler and up into StorageEngine where it belongs.
150
  {
1358.1.9 by Brian Aker
Update for std::string
151
    internal::fn_format(buff, identifier.getPath().c_str(), "", *ext,
152
                        MY_UNPACK_FILENAME|MY_APPEND_EXT);
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
153
    if (internal::my_delete_with_symlink(buff, MYF(0)))
1039.3.2 by Stewart Smith
move delete_table out of handler and up into StorageEngine where it belongs.
154
    {
1241.9.57 by Monty Taylor
Oy. Bigger change than I normally like - but this stuff is all intertwined.
155
      if ((error= errno) != ENOENT)
1373 by Brian Aker
Simple style cleanup.
156
        break;
1039.3.2 by Stewart Smith
move delete_table out of handler and up into StorageEngine where it belongs.
157
    }
158
    else
1395.1.12 by Brian Aker
Fixes failure related to Heap's hack on deletion. Also cleans up error
159
    {
1039.3.2 by Stewart Smith
move delete_table out of handler and up into StorageEngine where it belongs.
160
      enoent_or_zero= 0;                        // No error for ENOENT
1395.1.12 by Brian Aker
Fixes failure related to Heap's hack on deletion. Also cleans up error
161
    }
162
1039.3.2 by Stewart Smith
move delete_table out of handler and up into StorageEngine where it belongs.
163
    error= enoent_or_zero;
164
  }
165
  return error;
166
}
971.1.38 by Monty Taylor
Moved delete table.
167
1273.1.15 by Jay Pipes
This patch completes the first step in the splitting of
168
bool StorageEngine::addPlugin(StorageEngine *engine)
1130.1.12 by Monty Taylor
Moved service stuff into plugin/
169
{
1217.1.3 by Brian Aker
Remove NameMap from Storage Engine. Modified the cleanup code to just do a
170
1183.1.5 by Brian Aker
Reworked getTableNames() interface. Way simpler, less mallocs....
171
  vector_of_engines.push_back(engine);
172
1213 by Brian Aker
Fixes startup failures when temporary tables were left behind in a crash.
173
  if (engine->getTableDefinitionFileExtension().length())
1183.1.27 by Brian Aker
Fix issue where there are too many files in data directory. We now only
174
  {
1213 by Brian Aker
Fixes startup failures when temporary tables were left behind in a crash.
175
    assert(engine->getTableDefinitionFileExtension().length() == DEFAULT_DEFINITION_FILE_EXT.length());
176
    set_of_table_definition_ext.insert(engine->getTableDefinitionFileExtension());
1183.1.27 by Brian Aker
Fix issue where there are too many files in data directory. We now only
177
  }
178
1273.19.30 by Brian Aker
Performance patch... we now only cycle through engines that actually have
179
  if (engine->check_flag(HTON_BIT_SCHEMA_DICTIONARY))
180
    vector_of_schema_engines.push_back(engine);
181
1130.1.19 by Monty Taylor
Added error reporting to plugin registration.
182
  return false;
1130.1.12 by Monty Taylor
Moved service stuff into plugin/
183
}
184
1273.1.15 by Jay Pipes
This patch completes the first step in the splitting of
185
void StorageEngine::removePlugin(StorageEngine *)
1130.1.12 by Monty Taylor
Moved service stuff into plugin/
186
{
1217.1.3 by Brian Aker
Remove NameMap from Storage Engine. Modified the cleanup code to just do a
187
  if (shutdown_has_begun == false)
188
  {
189
    vector_of_engines.clear();
1273.19.30 by Brian Aker
Performance patch... we now only cycle through engines that actually have
190
    vector_of_schema_engines.clear();
1217.1.3 by Brian Aker
Remove NameMap from Storage Engine. Modified the cleanup code to just do a
191
192
    shutdown_has_begun= true;
193
  }
1130.1.12 by Monty Taylor
Moved service stuff into plugin/
194
}
195
1228.3.2 by Monty Taylor
Removed engine_map - just use vector_of_engines.
196
class FindEngineByName
1273.1.15 by Jay Pipes
This patch completes the first step in the splitting of
197
  : public unary_function<StorageEngine *, bool>
1228.3.2 by Monty Taylor
Removed engine_map - just use vector_of_engines.
198
{
1685.2.10 by Brian Aker
Optimize the string comparison a bit.
199
  const string &predicate;
1384 by Brian Aker
Merge
200
1228.3.2 by Monty Taylor
Removed engine_map - just use vector_of_engines.
201
public:
1384 by Brian Aker
Merge
202
  explicit FindEngineByName(const string &target_arg) :
1685.2.10 by Brian Aker
Optimize the string comparison a bit.
203
    predicate(target_arg)
1384 by Brian Aker
Merge
204
  {
205
  }
1685.2.10 by Brian Aker
Optimize the string comparison a bit.
206
1228.3.2 by Monty Taylor
Removed engine_map - just use vector_of_engines.
207
  result_type operator() (argument_type engine)
208
  {
1685.2.10 by Brian Aker
Optimize the string comparison a bit.
209
    return boost::iequals(engine->getName(), predicate);
1228.3.2 by Monty Taylor
Removed engine_map - just use vector_of_engines.
210
  }
211
};
212
1685.2.10 by Brian Aker
Optimize the string comparison a bit.
213
StorageEngine *StorageEngine::findByName(const string &predicate)
1183.1.29 by Brian Aker
Clean up interface so that Truncate sets the propper engine when
214
{
1228.3.2 by Monty Taylor
Removed engine_map - just use vector_of_engines.
215
  EngineVector::iterator iter= find_if(vector_of_engines.begin(),
216
                                       vector_of_engines.end(),
1685.2.10 by Brian Aker
Optimize the string comparison a bit.
217
                                       FindEngineByName(predicate));
1228.3.2 by Monty Taylor
Removed engine_map - just use vector_of_engines.
218
  if (iter != vector_of_engines.end())
1217.1.3 by Brian Aker
Remove NameMap from Storage Engine. Modified the cleanup code to just do a
219
  {
1228.3.2 by Monty Taylor
Removed engine_map - just use vector_of_engines.
220
    StorageEngine *engine= *iter;
1217.1.3 by Brian Aker
Remove NameMap from Storage Engine. Modified the cleanup code to just do a
221
    if (engine->is_user_selectable())
222
      return engine;
223
  }
1183.1.29 by Brian Aker
Clean up interface so that Truncate sets the propper engine when
224
225
  return NULL;
226
}
227
1685.2.10 by Brian Aker
Optimize the string comparison a bit.
228
StorageEngine *StorageEngine::findByName(Session& session, const string &predicate)
1130.1.12 by Monty Taylor
Moved service stuff into plugin/
229
{
1685.2.10 by Brian Aker
Optimize the string comparison a bit.
230
  if (boost::iequals(predicate, DEFAULT_STRING))
1183.1.29 by Brian Aker
Clean up interface so that Truncate sets the propper engine when
231
    return session.getDefaultStorageEngine();
1130.1.12 by Monty Taylor
Moved service stuff into plugin/
232
1228.3.2 by Monty Taylor
Removed engine_map - just use vector_of_engines.
233
  EngineVector::iterator iter= find_if(vector_of_engines.begin(),
234
                                       vector_of_engines.end(),
1685.2.10 by Brian Aker
Optimize the string comparison a bit.
235
                                       FindEngineByName(predicate));
1228.3.2 by Monty Taylor
Removed engine_map - just use vector_of_engines.
236
  if (iter != vector_of_engines.end())
1217.1.3 by Brian Aker
Remove NameMap from Storage Engine. Modified the cleanup code to just do a
237
  {
1228.3.2 by Monty Taylor
Removed engine_map - just use vector_of_engines.
238
    StorageEngine *engine= *iter;
1217.1.3 by Brian Aker
Remove NameMap from Storage Engine. Modified the cleanup code to just do a
239
    if (engine->is_user_selectable())
240
      return engine;
241
  }
1130.1.12 by Monty Taylor
Moved service stuff into plugin/
242
243
  return NULL;
244
}
245
1384 by Brian Aker
Merge
246
class StorageEngineCloseConnection : public unary_function<StorageEngine *, void>
1130.1.12 by Monty Taylor
Moved service stuff into plugin/
247
{
248
  Session *session;
249
public:
250
  StorageEngineCloseConnection(Session *session_arg) : session(session_arg) {}
251
  /*
252
    there's no need to rollback here as all transactions must
253
    be rolled back already
254
  */
255
  inline result_type operator() (argument_type engine)
256
  {
1273.1.20 by Jay Pipes
Remove StorageEngine::start_consitent_snapshot() and StorageEngine::enable(), disable() and is_enabled(). Unused.
257
    if (*session->getEngineData(engine))
1240.9.6 by Monty Taylor
Removed some casts- also removed a few c-interface functions and made them actual methods on session. Also made the ha_data private. (fancy that)
258
      engine->close_connection(session);
1130.1.12 by Monty Taylor
Moved service stuff into plugin/
259
  }
260
};
261
262
/**
263
  @note
264
    don't bother to rollback here, it's done already
265
*/
1273.1.15 by Jay Pipes
This patch completes the first step in the splitting of
266
void StorageEngine::closeConnection(Session* session)
1130.1.12 by Monty Taylor
Moved service stuff into plugin/
267
{
1183.1.16 by Brian Aker
Switch to using vector over Registry
268
  for_each(vector_of_engines.begin(), vector_of_engines.end(),
1130.1.12 by Monty Taylor
Moved service stuff into plugin/
269
           StorageEngineCloseConnection(session));
270
}
271
1273.1.15 by Jay Pipes
This patch completes the first step in the splitting of
272
bool StorageEngine::flushLogs(StorageEngine *engine)
1130.1.12 by Monty Taylor
Moved service stuff into plugin/
273
{
274
  if (engine == NULL)
275
  {
1217.1.3 by Brian Aker
Remove NameMap from Storage Engine. Modified the cleanup code to just do a
276
    if (find_if(vector_of_engines.begin(), vector_of_engines.end(),
1309.1.3 by Brian Aker
Cache for Schema.
277
                mem_fun(&StorageEngine::flush_logs))
278
        != vector_of_engines.begin())
1130.1.12 by Monty Taylor
Moved service stuff into plugin/
279
      return true;
280
  }
281
  else
282
  {
1273.1.20 by Jay Pipes
Remove StorageEngine::start_consitent_snapshot() and StorageEngine::enable(), disable() and is_enabled(). Unused.
283
    if (engine->flush_logs())
1130.1.12 by Monty Taylor
Moved service stuff into plugin/
284
      return true;
285
  }
286
  return false;
287
}
288
1273.1.15 by Jay Pipes
This patch completes the first step in the splitting of
289
class StorageEngineGetTableDefinition: public unary_function<StorageEngine *,bool>
1130.1.12 by Monty Taylor
Moved service stuff into plugin/
290
{
1183.1.29 by Brian Aker
Clean up interface so that Truncate sets the propper engine when
291
  Session& session;
1618.1.1 by Brian Aker
Modify TableIdentifier to be const
292
  const TableIdentifier &identifier;
1354.1.1 by Brian Aker
Modify ptr to reference.
293
  message::Table &table_message;
1373 by Brian Aker
Simple style cleanup.
294
  int &err;
1183.5.1 by Brian Aker
Extended definition interface (filename building should now be moved
295
1130.1.12 by Monty Taylor
Moved service stuff into plugin/
296
public:
1200 by Brian Aker
Clean up some mispellings
297
  StorageEngineGetTableDefinition(Session& session_arg,
1618.1.1 by Brian Aker
Modify TableIdentifier to be const
298
                                  const TableIdentifier &identifier_arg,
1354.1.1 by Brian Aker
Modify ptr to reference.
299
                                  message::Table &table_message_arg,
1373 by Brian Aker
Simple style cleanup.
300
                                  int &err_arg) :
1183.1.29 by Brian Aker
Clean up interface so that Truncate sets the propper engine when
301
    session(session_arg), 
1358.1.2 by Brian Aker
Long pass through the system to use more of TableIdentifiers.
302
    identifier(identifier_arg),
1320.1.1 by Brian Aker
Light cleanup for references.
303
    table_message(table_message_arg), 
1183.5.1 by Brian Aker
Extended definition interface (filename building should now be moved
304
    err(err_arg) {}
1130.1.12 by Monty Taylor
Moved service stuff into plugin/
305
306
  result_type operator() (argument_type engine)
307
  {
1395.1.12 by Brian Aker
Fixes failure related to Heap's hack on deletion. Also cleans up error
308
    int ret= engine->doGetTableDefinition(session, identifier, table_message);
1130.1.12 by Monty Taylor
Moved service stuff into plugin/
309
310
    if (ret != ENOENT)
1373 by Brian Aker
Simple style cleanup.
311
      err= ret;
1130.1.12 by Monty Taylor
Moved service stuff into plugin/
312
1373 by Brian Aker
Simple style cleanup.
313
    return err == EEXIST || err != ENOENT;
1130.1.12 by Monty Taylor
Moved service stuff into plugin/
314
  }
315
};
316
1358.1.1 by Brian Aker
Fixes regression in performance from Exists patch.
317
class StorageEngineDoesTableExist: public unary_function<StorageEngine *, bool>
318
{
319
  Session& session;
1618.1.1 by Brian Aker
Modify TableIdentifier to be const
320
  const TableIdentifier &identifier;
1358.1.1 by Brian Aker
Fixes regression in performance from Exists patch.
321
322
public:
1618.1.1 by Brian Aker
Modify TableIdentifier to be const
323
  StorageEngineDoesTableExist(Session& session_arg, const TableIdentifier &identifier_arg) :
1358.1.1 by Brian Aker
Fixes regression in performance from Exists patch.
324
    session(session_arg), 
325
    identifier(identifier_arg) 
326
  { }
327
328
  result_type operator() (argument_type engine)
329
  {
330
    return engine->doDoesTableExist(session, identifier);
331
  }
332
};
333
1130.1.12 by Monty Taylor
Moved service stuff into plugin/
334
/**
1273.19.11 by Brian Aker
This restores temporary tables back to being viewable via show/select.
335
  Utility method which hides some of the details of getTableDefinition()
336
*/
1358.1.1 by Brian Aker
Fixes regression in performance from Exists patch.
337
bool plugin::StorageEngine::doesTableExist(Session &session,
1618.1.1 by Brian Aker
Modify TableIdentifier to be const
338
                                           const TableIdentifier &identifier,
1273.19.11 by Brian Aker
This restores temporary tables back to being viewable via show/select.
339
                                           bool include_temporary_tables)
340
{
1358.1.1 by Brian Aker
Fixes regression in performance from Exists patch.
341
  if (include_temporary_tables)
342
  {
343
    if (session.doDoesTableExist(identifier))
344
      return true;
345
  }
346
347
  EngineVector::iterator iter=
1414 by Brian Aker
Remove dead type.
348
    find_if(vector_of_engines.begin(), vector_of_engines.end(),
1358.1.1 by Brian Aker
Fixes regression in performance from Exists patch.
349
            StorageEngineDoesTableExist(session, identifier));
350
1414 by Brian Aker
Remove dead type.
351
  if (iter == vector_of_engines.end())
1358.1.1 by Brian Aker
Fixes regression in performance from Exists patch.
352
  {
353
    return false;
354
  }
355
356
  return true;
357
}
358
1618.1.1 by Brian Aker
Modify TableIdentifier to be const
359
bool plugin::StorageEngine::doDoesTableExist(Session&, const drizzled::TableIdentifier&)
1358.1.1 by Brian Aker
Fixes regression in performance from Exists patch.
360
{
361
  cerr << " Engine was called for doDoesTableExist() and does not implement it: " << this->getName() << "\n";
362
  assert(0);
363
  return false;
1273.19.11 by Brian Aker
This restores temporary tables back to being viewable via show/select.
364
}
365
366
/**
1183.1.2 by Brian Aker
Rename of handler to Cursor. You would not believe how long I have wanted
367
  Call this function in order to give the Cursor the possiblity
1130.1.12 by Monty Taylor
Moved service stuff into plugin/
368
  to ask engine if there are any new tables that should be written to disk
369
  or any dropped tables that need to be removed from disk
370
*/
1273.1.15 by Jay Pipes
This patch completes the first step in the splitting of
371
int StorageEngine::getTableDefinition(Session& session,
1618.1.1 by Brian Aker
Modify TableIdentifier to be const
372
                                      const TableIdentifier &identifier,
1938.4.2 by Brian Aker
Fix style issue around table for message (though this is imperfect,...)
373
                                      message::table::shared_ptr &table_message,
1309.2.3 by Brian Aker
Update the code so use a faster index lookup method.
374
                                      bool include_temporary_tables)
1223.4.17 by Brian Aker
Added a form of getTableDefinition() that uses TableIdentifiers
375
{
1130.1.12 by Monty Taylor
Moved service stuff into plugin/
376
  int err= ENOENT;
377
1273.19.11 by Brian Aker
This restores temporary tables back to being viewable via show/select.
378
  if (include_temporary_tables)
379
  {
1910.2.11 by Brian Aker
Have the SE go through the Session API for tables to directly find the table
380
    Table *table= session.find_temporary_table(identifier);
381
    if (table)
382
    {
1910.2.15 by Brian Aker
Update so that we use shared_ptr from the cache throughout more of the
383
      table_message.reset(new message::Table(*table->getShare()->getTableProto()));
1273.19.11 by Brian Aker
This restores temporary tables back to being viewable via show/select.
384
      return EEXIST;
1910.2.11 by Brian Aker
Have the SE go through the Session API for tables to directly find the table
385
    }
1273.19.11 by Brian Aker
This restores temporary tables back to being viewable via show/select.
386
  }
387
1938.4.2 by Brian Aker
Fix style issue around table for message (though this is imperfect,...)
388
  drizzled::message::table::shared_ptr table_ptr;
1910.2.14 by Brian Aker
Check simple cache performance hit.
389
  if ((table_ptr= drizzled::message::Cache::singleton().find(identifier)))
390
  {
1910.2.15 by Brian Aker
Update so that we use shared_ptr from the cache throughout more of the
391
    table_message= table_ptr;
1910.2.14 by Brian Aker
Check simple cache performance hit.
392
  }
393
1910.2.15 by Brian Aker
Update so that we use shared_ptr from the cache throughout more of the
394
  message::Table message;
1273.19.30 by Brian Aker
Performance patch... we now only cycle through engines that actually have
395
  EngineVector::iterator iter=
1183.1.16 by Brian Aker
Switch to using vector over Registry
396
    find_if(vector_of_engines.begin(), vector_of_engines.end(),
1910.2.15 by Brian Aker
Update so that we use shared_ptr from the cache throughout more of the
397
            StorageEngineGetTableDefinition(session, identifier, message, err));
1183.1.16 by Brian Aker
Switch to using vector over Registry
398
399
  if (iter == vector_of_engines.end())
1130.1.12 by Monty Taylor
Moved service stuff into plugin/
400
  {
1309.1.1 by Brian Aker
This removes the special case read of proto from SE interface, down to
401
    return ENOENT;
1130.1.12 by Monty Taylor
Moved service stuff into plugin/
402
  }
1910.2.15 by Brian Aker
Update so that we use shared_ptr from the cache throughout more of the
403
  table_message.reset(new message::Table(message));
1130.1.12 by Monty Taylor
Moved service stuff into plugin/
404
1910.2.14 by Brian Aker
Check simple cache performance hit.
405
 drizzled::message::Cache::singleton().insert(identifier, table_message);
406
1130.1.12 by Monty Taylor
Moved service stuff into plugin/
407
  return err;
408
}
409
410
/**
411
  An interceptor to hijack the text of the error message without
412
  setting an error in the thread. We need the text to present it
413
  in the form of a warning to the user.
414
*/
415
416
class Ha_delete_table_error_handler: public Internal_error_handler
417
{
418
public:
419
  Ha_delete_table_error_handler() : Internal_error_handler() {}
420
  virtual bool handle_error(uint32_t sql_errno,
421
                            const char *message,
422
                            DRIZZLE_ERROR::enum_warning_level level,
423
                            Session *session);
424
  char buff[DRIZZLE_ERRMSG_SIZE];
425
};
426
427
428
bool
429
Ha_delete_table_error_handler::
430
handle_error(uint32_t ,
431
             const char *message,
432
             DRIZZLE_ERROR::enum_warning_level ,
433
             Session *)
434
{
435
  /* Grab the error message */
436
  strncpy(buff, message, sizeof(buff)-1);
437
  return true;
438
}
439
440
/**
1259.5.16 by Stewart Smith
remove reference to frm file in StorageEngine::dropTable code path
441
   returns ENOENT if the file doesn't exists.
1130.1.12 by Monty Taylor
Moved service stuff into plugin/
442
*/
1273.1.15 by Jay Pipes
This patch completes the first step in the splitting of
443
int StorageEngine::dropTable(Session& session,
1618.1.1 by Brian Aker
Modify TableIdentifier to be const
444
                             const TableIdentifier &identifier)
1130.1.12 by Monty Taylor
Moved service stuff into plugin/
445
{
1183.1.8 by Brian Aker
Reworked delete table code (thank god... or... whatever... how about my dog?
446
  int error= 0;
447
  int error_proto;
1938.4.2 by Brian Aker
Fix style issue around table for message (though this is imperfect,...)
448
  message::table::shared_ptr src_proto;
1395.1.12 by Brian Aker
Fixes failure related to Heap's hack on deletion. Also cleans up error
449
  StorageEngine *engine;
1183.1.8 by Brian Aker
Reworked delete table code (thank god... or... whatever... how about my dog?
450
1358.1.2 by Brian Aker
Long pass through the system to use more of TableIdentifiers.
451
  error_proto= StorageEngine::getTableDefinition(session, identifier, src_proto);
1183.1.8 by Brian Aker
Reworked delete table code (thank god... or... whatever... how about my dog?
452
1273.2.33 by Stewart Smith
only produce error in DropTable path if it's something interesting. also generate correct error if we have non-ER_CORRUPT_TABLE_DEFINITION error from engine in getting table definition.
453
  if (error_proto == ER_CORRUPT_TABLE_DEFINITION)
1273.2.31 by Stewart Smith
if error reading table proto in DROP TABLE code path, do a simple error out.
454
  {
1395.1.12 by Brian Aker
Fixes failure related to Heap's hack on deletion. Also cleans up error
455
    string error_message;
456
1618.1.1 by Brian Aker
Modify TableIdentifier to be const
457
    error_message.append(const_cast<TableIdentifier &>(identifier).getSQLPath());
1395.1.12 by Brian Aker
Fixes failure related to Heap's hack on deletion. Also cleans up error
458
    error_message.append(" : ");
1910.2.15 by Brian Aker
Update so that we use shared_ptr from the cache throughout more of the
459
    error_message.append(src_proto->InitializationErrorString());
1395.1.12 by Brian Aker
Fixes failure related to Heap's hack on deletion. Also cleans up error
460
461
    my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0), error_message.c_str());
462
1273.2.31 by Stewart Smith
if error reading table proto in DROP TABLE code path, do a simple error out.
463
    return ER_CORRUPT_TABLE_DEFINITION;
464
  }
465
1910.2.15 by Brian Aker
Update so that we use shared_ptr from the cache throughout more of the
466
  if (src_proto)
467
    engine= StorageEngine::findByName(session, src_proto->engine().name());
468
  else
469
    engine= StorageEngine::findByName(session, "");
1183.1.8 by Brian Aker
Reworked delete table code (thank god... or... whatever... how about my dog?
470
1412 by Brian Aker
Innodb is now in the house (aka... it handls its own DFE).
471
  if (not engine)
1183.1.9 by Brian Aker
Rename deleteTableImpl -> doDeleteTable()
472
  {
1618.1.1 by Brian Aker
Modify TableIdentifier to be const
473
    my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0), const_cast<TableIdentifier &>(identifier).getSQLPath().c_str());
1412 by Brian Aker
Innodb is now in the house (aka... it handls its own DFE).
474
475
    return ER_CORRUPT_TABLE_DEFINITION;
1183.1.8 by Brian Aker
Reworked delete table code (thank god... or... whatever... how about my dog?
476
  }
477
1412 by Brian Aker
Innodb is now in the house (aka... it handls its own DFE).
478
  error= StorageEngine::dropTable(session, *engine, identifier);
479
1183.1.8 by Brian Aker
Reworked delete table code (thank god... or... whatever... how about my dog?
480
  if (error_proto && error == 0)
481
    return 0;
1130.1.12 by Monty Taylor
Moved service stuff into plugin/
482
483
  return error;
484
}
485
1395.1.12 by Brian Aker
Fixes failure related to Heap's hack on deletion. Also cleans up error
486
int StorageEngine::dropTable(Session& session,
487
                             StorageEngine &engine,
1618.1.1 by Brian Aker
Modify TableIdentifier to be const
488
                             const TableIdentifier &identifier)
1395.1.12 by Brian Aker
Fixes failure related to Heap's hack on deletion. Also cleans up error
489
{
490
  int error;
491
492
  engine.setTransactionReadWrite(session);
1502.5.2 by Barry.Leslie at PrimeBase
Changes made to drizzle source when building in the events plugin.
493
  
1502.5.8 by Barry.Leslie at PrimeBase
- Changed names to match the drizzle naming convention.
494
  if (unlikely(plugin::EventObserver::beforeDropTable(session, identifier)))
1502.5.7 by Barry.Leslie at PrimeBase
Renamed the 'Event' plugin to 'EventObserver' plugin along with some internal class renames to make things clearer.
495
  {
496
    error= ER_EVENT_OBSERVER_PLUGIN;
497
  }
498
  else
499
  {
500
    error= engine.doDropTable(session, identifier);
1502.5.8 by Barry.Leslie at PrimeBase
- Changed names to match the drizzle naming convention.
501
    if (unlikely(plugin::EventObserver::afterDropTable(session, identifier, error)))
1502.5.7 by Barry.Leslie at PrimeBase
Renamed the 'Event' plugin to 'EventObserver' plugin along with some internal class renames to make things clearer.
502
    {
503
      error= ER_EVENT_OBSERVER_PLUGIN;
504
    }
505
  }
506
1910.2.14 by Brian Aker
Check simple cache performance hit.
507
  drizzled::message::Cache::singleton().erase(identifier);
1395.1.12 by Brian Aker
Fixes failure related to Heap's hack on deletion. Also cleans up error
508
509
  return error;
510
}
511
1412 by Brian Aker
Innodb is now in the house (aka... it handls its own DFE).
512
971.1.38 by Monty Taylor
Moved delete table.
513
/**
514
  Initiates table-file and calls appropriate database-creator.
515
516
  @retval
517
   0  ok
518
  @retval
519
   1  error
520
*/
1372.1.4 by Brian Aker
Update to remove cache in enginges for per session (which also means... no
521
int StorageEngine::createTable(Session &session,
1618.1.1 by Brian Aker
Modify TableIdentifier to be const
522
                               const TableIdentifier &identifier,
1320.1.6 by Brian Aker
Remove unused createTable() option
523
                               message::Table& table_message)
971.1.38 by Monty Taylor
Moved delete table.
524
{
525
  int error= 1;
1608.2.4 by Brian Aker
Update for having share declared type.
526
  TableShare share(identifier);
1859.2.11 by Brian Aker
Merge in so that shell requires a share to construct.
527
  table::Shell table(share);
1130.3.16 by Monty Taylor
Moved the last three methods from plugin/storage_engine.cc to be static methods on StorageEngine.
528
  message::Table tmp_proto;
971.1.38 by Monty Taylor
Moved delete table.
529
1626.3.2 by Brian Aker
Cleanup table_share to pass in identifier.
530
  if (share.parse_table_proto(session, table_message) || share.open_table_from_share(&session, identifier, "", 0, 0, table))
1372.1.4 by Brian Aker
Update to remove cache in enginges for per session (which also means... no
531
  { 
532
    // @note Error occured, we should probably do a little more here.
533
  }
534
  else
535
  {
536
    /* Check for legal operations against the Engine using the proto (if used) */
537
    if (table_message.type() == message::Table::TEMPORARY &&
538
        share.storage_engine->check_flag(HTON_BIT_TEMPORARY_NOT_SUPPORTED) == true)
539
    {
540
      error= HA_ERR_UNSUPPORTED;
541
    }
542
    else if (table_message.type() != message::Table::TEMPORARY &&
543
             share.storage_engine->check_flag(HTON_BIT_TEMPORARY_ONLY) == true)
544
    {
545
      error= HA_ERR_UNSUPPORTED;
546
    }
547
    else
548
    {
1412 by Brian Aker
Innodb is now in the house (aka... it handls its own DFE).
549
      share.storage_engine->setTransactionReadWrite(session);
550
1413 by Brian Aker
doCreateTable() was still taking a pointer instead of a session reference.
551
      error= share.storage_engine->doCreateTable(session,
1412 by Brian Aker
Innodb is now in the house (aka... it handls its own DFE).
552
                                                 table,
553
                                                 identifier,
554
                                                 table_message);
1372.1.4 by Brian Aker
Update to remove cache in enginges for per session (which also means... no
555
    }
556
557
    if (error)
558
    {
1618.1.1 by Brian Aker
Modify TableIdentifier to be const
559
      my_error(ER_CANT_CREATE_TABLE, MYF(ME_BELL+ME_WAITTANG), const_cast<TableIdentifier &>(identifier).getSQLPath().c_str(), error);
1372.1.4 by Brian Aker
Update to remove cache in enginges for per session (which also means... no
560
    }
561
1672.3.2 by Brian Aker
Tiny little cleanup around Table.
562
    table.delete_table();
1372.1.4 by Brian Aker
Update to remove cache in enginges for per session (which also means... no
563
  }
564
971.1.38 by Monty Taylor
Moved delete table.
565
  return(error != 0);
566
}
567
1869.1.4 by Brian Aker
TableShare is no longer in the house (i.e. we no longer directly have a copy
568
Cursor *StorageEngine::getCursor(Table &arg)
1183.1.1 by Brian Aker
Rework interface pieces on SE (sort of... dumb ones...)
569
{
1869.1.4 by Brian Aker
TableShare is no longer in the house (i.e. we no longer directly have a copy
570
  return create(arg);
1183.1.1 by Brian Aker
Rework interface pieces on SE (sort of... dumb ones...)
571
}
1160.1.1 by Brian Aker
Refactor SE createTable back to engine class.
572
1429.1.3 by Brian Aker
Merge in work for fetching a list of table identifiers.
573
class AddTableIdentifier : 
574
  public unary_function<StorageEngine *, void>
575
{
576
  CachedDirectory &directory;
1642 by Brian Aker
This adds const to SchemaIdentifier.
577
  const SchemaIdentifier &identifier;
1429.1.3 by Brian Aker
Merge in work for fetching a list of table identifiers.
578
  TableIdentifiers &set_of_identifiers;
579
580
public:
581
1642 by Brian Aker
This adds const to SchemaIdentifier.
582
  AddTableIdentifier(CachedDirectory &directory_arg, const SchemaIdentifier &identifier_arg, TableIdentifiers &of_names) :
1429.1.3 by Brian Aker
Merge in work for fetching a list of table identifiers.
583
    directory(directory_arg),
584
    identifier(identifier_arg),
585
    set_of_identifiers(of_names)
586
  {
587
  }
588
589
  result_type operator() (argument_type engine)
590
  {
591
    engine->doGetTableIdentifiers(directory, identifier, set_of_identifiers);
592
  }
593
};
594
1415 by Brian Aker
Mass overhaul to use schema_identifier.
595
1663.1.4 by Brian Aker
Removed identifier bit
596
void StorageEngine::getIdentifiers(Session &session, const SchemaIdentifier &schema_identifier, TableIdentifiers &set_of_identifiers)
1429.1.3 by Brian Aker
Merge in work for fetching a list of table identifiers.
597
{
1786.3.1 by Monty Taylor
Initial working local catalog.
598
  static SchemaIdentifier INFORMATION_SCHEMA_IDENTIFIER("information_schema");
599
  static SchemaIdentifier DATA_DICTIONARY_IDENTIFIER("data_dictionary");
600
1429.1.3 by Brian Aker
Merge in work for fetching a list of table identifiers.
601
  CachedDirectory directory(schema_identifier.getPath(), set_of_table_definition_ext);
602
603
  if (schema_identifier == INFORMATION_SCHEMA_IDENTIFIER)
604
  { }
605
  else if (schema_identifier == DATA_DICTIONARY_IDENTIFIER)
606
  { }
607
  else
608
  {
609
    if (directory.fail())
610
    {
611
      errno= directory.getError();
612
      if (errno == ENOENT)
1652 by Brian Aker
Fix const_cast, disable the unittest for generators.
613
        my_error(ER_BAD_DB_ERROR, MYF(ME_BELL+ME_WAITTANG), const_cast<SchemaIdentifier &>(schema_identifier).getSQLPath().c_str());
1429.1.3 by Brian Aker
Merge in work for fetching a list of table identifiers.
614
      else
615
        my_error(ER_CANT_READ_DIR, MYF(ME_BELL+ME_WAITTANG), directory.getPath(), errno);
616
      return;
617
    }
618
  }
619
620
  for_each(vector_of_engines.begin(), vector_of_engines.end(),
621
           AddTableIdentifier(directory, schema_identifier, set_of_identifiers));
622
623
  session.doGetTableIdentifiers(directory, schema_identifier, set_of_identifiers);
624
}
625
1510.3.2 by mordred
Fix error found by cppcheck - modifying a container invalidates its iterators,
626
class DropTable: public unary_function<TableIdentifier&, bool>
627
{
628
  Session &session;
629
  StorageEngine *engine;
630
631
public:
632
633
  DropTable(Session &session_arg, StorageEngine *engine_arg) :
634
    session(session_arg),
635
    engine(engine_arg)
636
  { }
637
638
  result_type operator() (argument_type identifier)
639
  {
640
    return engine->doDropTable(session, identifier) == 0;
641
  } 
642
};
643
1213 by Brian Aker
Fixes startup failures when temporary tables were left behind in a crash.
644
/* This will later be converted to TableIdentifiers */
1273.1.15 by Jay Pipes
This patch completes the first step in the splitting of
645
class DropTables: public unary_function<StorageEngine *, void>
1213 by Brian Aker
Fixes startup failures when temporary tables were left behind in a crash.
646
{
647
  Session &session;
1643.3.3 by Brian Aker
Updated to harmonize the identifier API.
648
  TableIdentifiers &table_identifiers;
1213 by Brian Aker
Fixes startup failures when temporary tables were left behind in a crash.
649
650
public:
651
1643.3.3 by Brian Aker
Updated to harmonize the identifier API.
652
  DropTables(Session &session_arg, TableIdentifiers &table_identifiers_arg) :
1213 by Brian Aker
Fixes startup failures when temporary tables were left behind in a crash.
653
    session(session_arg),
1395.1.8 by Brian Aker
Cleanup usage of TI so that the NULL ones no longer exist.
654
    table_identifiers(table_identifiers_arg)
1213 by Brian Aker
Fixes startup failures when temporary tables were left behind in a crash.
655
  { }
656
657
  result_type operator() (argument_type engine)
658
  {
1510.3.2 by mordred
Fix error found by cppcheck - modifying a container invalidates its iterators,
659
    // True returning from DropTable means the table has been successfully
660
    // deleted, so it should be removed from the list of tables to drop
661
    table_identifiers.erase(remove_if(table_identifiers.begin(),
662
                                      table_identifiers.end(),
663
                                      DropTable(session, engine)),
664
                            table_identifiers.end());
1213 by Brian Aker
Fixes startup failures when temporary tables were left behind in a crash.
665
  }
666
};
667
668
/*
669
  This only works for engines which use file based DFE.
670
671
  Note-> Unlike MySQL, we do not, on purpose, delete files that do not match any engines. 
672
*/
1273.1.15 by Jay Pipes
This patch completes the first step in the splitting of
673
void StorageEngine::removeLostTemporaryTables(Session &session, const char *directory)
1213 by Brian Aker
Fixes startup failures when temporary tables were left behind in a crash.
674
{
675
  CachedDirectory dir(directory, set_of_table_definition_ext);
1643.3.3 by Brian Aker
Updated to harmonize the identifier API.
676
  TableIdentifiers table_identifiers;
1213 by Brian Aker
Fixes startup failures when temporary tables were left behind in a crash.
677
678
  if (dir.fail())
679
  {
1241.9.57 by Monty Taylor
Oy. Bigger change than I normally like - but this stuff is all intertwined.
680
    errno= dir.getError();
681
    my_error(ER_CANT_READ_DIR, MYF(0), directory, errno);
1213 by Brian Aker
Fixes startup failures when temporary tables were left behind in a crash.
682
683
    return;
684
  }
685
686
  CachedDirectory::Entries files= dir.getEntries();
687
688
  for (CachedDirectory::Entries::iterator fileIter= files.begin();
689
       fileIter != files.end(); fileIter++)
690
  {
691
    size_t length;
692
    string path;
693
    CachedDirectory::Entry *entry= *fileIter;
694
695
    /* We remove the file extension. */
696
    length= entry->filename.length();
697
    entry->filename.resize(length - DEFAULT_DEFINITION_FILE_EXT.length());
698
699
    path+= directory;
700
    path+= FN_LIBCHAR;
701
    path+= entry->filename;
1395.1.8 by Brian Aker
Cleanup usage of TI so that the NULL ones no longer exist.
702
    message::Table definition;
703
    if (StorageEngine::readTableFile(path, definition))
704
    {
1395.1.9 by Brian Aker
Small cleanup around how we do types internally.
705
      TableIdentifier identifier(definition.schema(), definition.name(), path);
1395.1.8 by Brian Aker
Cleanup usage of TI so that the NULL ones no longer exist.
706
      table_identifiers.push_back(identifier);
707
    }
1213 by Brian Aker
Fixes startup failures when temporary tables were left behind in a crash.
708
  }
709
710
  for_each(vector_of_engines.begin(), vector_of_engines.end(),
1395.1.8 by Brian Aker
Cleanup usage of TI so that the NULL ones no longer exist.
711
           DropTables(session, table_identifiers));
1213 by Brian Aker
Fixes startup failures when temporary tables were left behind in a crash.
712
  
713
  /*
714
    Now we just clean up anything that might left over.
715
716
    We rescan because some of what might have been there should
717
    now be all nice and cleaned up.
718
  */
719
  set<string> all_exts= set_of_table_definition_ext;
720
1273.19.30 by Brian Aker
Performance patch... we now only cycle through engines that actually have
721
  for (EngineVector::iterator iter= vector_of_engines.begin();
1213 by Brian Aker
Fixes startup failures when temporary tables were left behind in a crash.
722
       iter != vector_of_engines.end() ; iter++)
723
  {
724
    for (const char **ext= (*iter)->bas_ext(); *ext ; ext++)
725
      all_exts.insert(*ext);
726
  }
727
728
  CachedDirectory rescan(directory, all_exts);
729
730
  files= rescan.getEntries();
731
  for (CachedDirectory::Entries::iterator fileIter= files.begin();
732
       fileIter != files.end(); fileIter++)
733
  {
734
    string path;
735
    CachedDirectory::Entry *entry= *fileIter;
736
737
    path+= directory;
738
    path+= FN_LIBCHAR;
739
    path+= entry->filename;
740
741
    unlink(path.c_str());
742
  }
743
}
744
1160.1.1 by Brian Aker
Refactor SE createTable back to engine class.
745
1216.1.1 by Brian Aker
Move print_error up to Engine.
746
/**
747
  Print error that we got from Cursor function.
748
749
  @note
750
    In case of delete table it's only safe to use the following parts of
751
    the 'table' structure:
1532.1.15 by Brian Aker
Partial encapsulation of TableShare from Table.
752
    - table->getShare()->path
1216.1.1 by Brian Aker
Move print_error up to Engine.
753
    - table->alias
754
*/
1273.1.15 by Jay Pipes
This patch completes the first step in the splitting of
755
void StorageEngine::print_error(int error, myf errflag, Table &table)
1216.1.1 by Brian Aker
Move print_error up to Engine.
756
{
757
  print_error(error, errflag, &table);
758
}
759
1273.1.15 by Jay Pipes
This patch completes the first step in the splitting of
760
void StorageEngine::print_error(int error, myf errflag, Table *table)
1216.1.1 by Brian Aker
Move print_error up to Engine.
761
{
762
  int textno= ER_GET_ERRNO;
763
  switch (error) {
764
  case EACCES:
765
    textno=ER_OPEN_AS_READONLY;
766
    break;
767
  case EAGAIN:
768
    textno=ER_FILE_USED;
769
    break;
770
  case ENOENT:
771
    textno=ER_FILE_NOT_FOUND;
772
    break;
773
  case HA_ERR_KEY_NOT_FOUND:
774
  case HA_ERR_NO_ACTIVE_RECORD:
775
  case HA_ERR_END_OF_FILE:
776
    textno=ER_KEY_NOT_FOUND;
777
    break;
778
  case HA_ERR_WRONG_MRG_TABLE_DEF:
779
    textno=ER_WRONG_MRG_TABLE;
780
    break;
781
  case HA_ERR_FOUND_DUPP_KEY:
782
  {
783
    assert(table);
784
    uint32_t key_nr= table->get_dup_key(error);
785
    if ((int) key_nr >= 0)
786
    {
787
      const char *err_msg= ER(ER_DUP_ENTRY_WITH_KEY_NAME);
788
789
      print_keydup_error(key_nr, err_msg, *table);
1578.6.5 by Brian Aker
Remove error message for less effective one, but remove current_session().
790
1216.1.1 by Brian Aker
Move print_error up to Engine.
791
      return;
792
    }
793
    textno=ER_DUP_KEY;
794
    break;
795
  }
796
  case HA_ERR_FOREIGN_DUPLICATE_KEY:
797
  {
798
    assert(table);
799
    uint32_t key_nr= table->get_dup_key(error);
800
    if ((int) key_nr >= 0)
801
    {
802
      uint32_t max_length;
803
804
      /* Write the key in the error message */
805
      char key[MAX_KEY_LENGTH];
806
      String str(key,sizeof(key),system_charset_info);
807
808
      /* Table is opened and defined at this point */
809
      key_unpack(&str,table,(uint32_t) key_nr);
810
      max_length= (DRIZZLE_ERRMSG_SIZE-
811
                   (uint32_t) strlen(ER(ER_FOREIGN_DUPLICATE_KEY)));
812
      if (str.length() >= max_length)
813
      {
814
        str.length(max_length-4);
815
        str.append(STRING_WITH_LEN("..."));
816
      }
1532.1.15 by Brian Aker
Partial encapsulation of TableShare from Table.
817
      my_error(ER_FOREIGN_DUPLICATE_KEY, MYF(0), table->getShare()->getTableName(),
1216.1.1 by Brian Aker
Move print_error up to Engine.
818
        str.c_ptr(), key_nr+1);
819
      return;
820
    }
821
    textno= ER_DUP_KEY;
822
    break;
823
  }
824
  case HA_ERR_FOUND_DUPP_UNIQUE:
825
    textno=ER_DUP_UNIQUE;
826
    break;
827
  case HA_ERR_RECORD_CHANGED:
828
    textno=ER_CHECKREAD;
829
    break;
830
  case HA_ERR_CRASHED:
831
    textno=ER_NOT_KEYFILE;
832
    break;
833
  case HA_ERR_WRONG_IN_RECORD:
834
    textno= ER_CRASHED_ON_USAGE;
835
    break;
836
  case HA_ERR_CRASHED_ON_USAGE:
837
    textno=ER_CRASHED_ON_USAGE;
838
    break;
839
  case HA_ERR_NOT_A_TABLE:
840
    textno= error;
841
    break;
842
  case HA_ERR_CRASHED_ON_REPAIR:
843
    textno=ER_CRASHED_ON_REPAIR;
844
    break;
845
  case HA_ERR_OUT_OF_MEM:
846
    textno=ER_OUT_OF_RESOURCES;
847
    break;
848
  case HA_ERR_WRONG_COMMAND:
849
    textno=ER_ILLEGAL_HA;
850
    break;
851
  case HA_ERR_OLD_FILE:
852
    textno=ER_OLD_KEYFILE;
853
    break;
854
  case HA_ERR_UNSUPPORTED:
855
    textno=ER_UNSUPPORTED_EXTENSION;
856
    break;
857
  case HA_ERR_RECORD_FILE_FULL:
858
  case HA_ERR_INDEX_FILE_FULL:
859
    textno=ER_RECORD_FILE_FULL;
860
    break;
861
  case HA_ERR_LOCK_WAIT_TIMEOUT:
862
    textno=ER_LOCK_WAIT_TIMEOUT;
863
    break;
864
  case HA_ERR_LOCK_TABLE_FULL:
865
    textno=ER_LOCK_TABLE_FULL;
866
    break;
867
  case HA_ERR_LOCK_DEADLOCK:
868
    textno=ER_LOCK_DEADLOCK;
869
    break;
870
  case HA_ERR_READ_ONLY_TRANSACTION:
871
    textno=ER_READ_ONLY_TRANSACTION;
872
    break;
873
  case HA_ERR_CANNOT_ADD_FOREIGN:
874
    textno=ER_CANNOT_ADD_FOREIGN;
875
    break;
876
  case HA_ERR_ROW_IS_REFERENCED:
877
  {
878
    String str;
879
    get_error_message(error, &str);
880
    my_error(ER_ROW_IS_REFERENCED_2, MYF(0), str.c_ptr_safe());
881
    return;
882
  }
883
  case HA_ERR_NO_REFERENCED_ROW:
884
  {
885
    String str;
886
    get_error_message(error, &str);
887
    my_error(ER_NO_REFERENCED_ROW_2, MYF(0), str.c_ptr_safe());
888
    return;
889
  }
890
  case HA_ERR_TABLE_DEF_CHANGED:
891
    textno=ER_TABLE_DEF_CHANGED;
892
    break;
893
  case HA_ERR_NO_SUCH_TABLE:
894
    assert(table);
1532.1.15 by Brian Aker
Partial encapsulation of TableShare from Table.
895
    my_error(ER_NO_SUCH_TABLE, MYF(0), table->getShare()->getSchemaName(),
896
             table->getShare()->getTableName());
1216.1.1 by Brian Aker
Move print_error up to Engine.
897
    return;
898
  case HA_ERR_RBR_LOGGING_FAILED:
899
    textno= ER_BINLOG_ROW_LOGGING_FAILED;
900
    break;
901
  case HA_ERR_DROP_INDEX_FK:
902
  {
903
    assert(table);
904
    const char *ptr= "???";
905
    uint32_t key_nr= table->get_dup_key(error);
906
    if ((int) key_nr >= 0)
907
      ptr= table->key_info[key_nr].name;
908
    my_error(ER_DROP_INDEX_FK, MYF(0), ptr);
909
    return;
910
  }
911
  case HA_ERR_TABLE_NEEDS_UPGRADE:
912
    textno=ER_TABLE_NEEDS_UPGRADE;
913
    break;
914
  case HA_ERR_TABLE_READONLY:
915
    textno= ER_OPEN_AS_READONLY;
916
    break;
917
  case HA_ERR_AUTOINC_READ_FAILED:
918
    textno= ER_AUTOINC_READ_FAILED;
919
    break;
920
  case HA_ERR_AUTOINC_ERANGE:
921
    textno= ER_WARN_DATA_OUT_OF_RANGE;
922
    break;
923
  case HA_ERR_LOCK_OR_ACTIVE_TRANSACTION:
924
    my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
925
               ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
926
    return;
927
  default:
928
    {
929
      /* 
930
        The error was "unknown" to this function.
931
        Ask Cursor if it has got a message for this error 
932
      */
933
      bool temporary= false;
934
      String str;
935
      temporary= get_error_message(error, &str);
936
      if (!str.is_empty())
937
      {
938
        const char* engine_name= getName().c_str();
939
        if (temporary)
940
          my_error(ER_GET_TEMPORARY_ERRMSG, MYF(0), error, str.ptr(),
941
                   engine_name);
942
        else
943
          my_error(ER_GET_ERRMSG, MYF(0), error, str.ptr(), engine_name);
944
      }
945
      else
946
      {
947
	      my_error(ER_GET_ERRNO,errflag,error);
948
      }
949
      return;
950
    }
951
  }
1532.1.15 by Brian Aker
Partial encapsulation of TableShare from Table.
952
  my_error(textno, errflag, table->getShare()->getTableName(), error);
1216.1.1 by Brian Aker
Move print_error up to Engine.
953
}
954
955
956
/**
957
  Return an error message specific to this Cursor.
958
959
  @param error  error code previously returned by Cursor
960
  @param buf    pointer to String where to add error message
961
962
  @return
963
    Returns true if this is a temporary error
964
*/
1273.1.15 by Jay Pipes
This patch completes the first step in the splitting of
965
bool StorageEngine::get_error_message(int , String* )
1216.1.1 by Brian Aker
Move print_error up to Engine.
966
{
967
  return false;
968
}
969
970
1273.1.15 by Jay Pipes
This patch completes the first step in the splitting of
971
void StorageEngine::print_keydup_error(uint32_t key_nr, const char *msg, Table &table)
1216.1.1 by Brian Aker
Move print_error up to Engine.
972
{
973
  /* Write the duplicated key in the error message */
974
  char key[MAX_KEY_LENGTH];
975
  String str(key,sizeof(key),system_charset_info);
976
977
  if (key_nr == MAX_KEY)
978
  {
979
    /* Key is unknown */
980
    str.copy("", 0, system_charset_info);
981
    my_printf_error(ER_DUP_ENTRY, msg, MYF(0), str.c_ptr(), "*UNKNOWN*");
982
  }
983
  else
984
  {
985
    /* Table is opened and defined at this point */
986
    key_unpack(&str, &table, (uint32_t) key_nr);
987
    uint32_t max_length=DRIZZLE_ERRMSG_SIZE-(uint32_t) strlen(msg);
988
    if (str.length() >= max_length)
989
    {
990
      str.length(max_length-4);
991
      str.append(STRING_WITH_LEN("..."));
992
    }
993
    my_printf_error(ER_DUP_ENTRY, msg,
994
		    MYF(0), str.c_ptr(), table.key_info[key_nr].name);
995
  }
996
}
997
1237.6.12 by Brian Aker
Adding patch for engine methods for definition files.
998
1618.1.1 by Brian Aker
Modify TableIdentifier to be const
999
int StorageEngine::deleteDefinitionFromPath(const TableIdentifier &identifier)
1237.6.12 by Brian Aker
Adding patch for engine methods for definition files.
1000
{
1001
  string path(identifier.getPath());
1002
1003
  path.append(DEFAULT_DEFINITION_FILE_EXT);
1004
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
1005
  return internal::my_delete(path.c_str(), MYF(0));
1237.6.12 by Brian Aker
Adding patch for engine methods for definition files.
1006
}
1007
1618.1.1 by Brian Aker
Modify TableIdentifier to be const
1008
int StorageEngine::renameDefinitionFromPath(const TableIdentifier &dest, const TableIdentifier &src)
1237.6.12 by Brian Aker
Adding patch for engine methods for definition files.
1009
{
1395.1.18 by Brian Aker
Small update.
1010
  message::Table table_message;
1237.6.12 by Brian Aker
Adding patch for engine methods for definition files.
1011
  string src_path(src.getPath());
1012
  string dest_path(dest.getPath());
1013
1014
  src_path.append(DEFAULT_DEFINITION_FILE_EXT);
1015
  dest_path.append(DEFAULT_DEFINITION_FILE_EXT);
1016
1395.1.18 by Brian Aker
Small update.
1017
  bool was_read= StorageEngine::readTableFile(src_path.c_str(), table_message);
1018
1019
  if (not was_read)
1020
  {
1021
    return ENOENT;
1022
  }
1395.1.1 by Brian Aker
Fixes for alter table to make sure that the proto on disk is valid.
1023
1024
  dest.copyToTableMessage(table_message);
1025
1395.1.18 by Brian Aker
Small update.
1026
  int error= StorageEngine::writeDefinitionFromPath(dest, table_message);
1027
1028
  if (not error)
1395.1.1 by Brian Aker
Fixes for alter table to make sure that the proto on disk is valid.
1029
  {
1395.1.18 by Brian Aker
Small update.
1030
    if (unlink(src_path.c_str()))
1031
      perror(src_path.c_str());
1395.1.1 by Brian Aker
Fixes for alter table to make sure that the proto on disk is valid.
1032
  }
1033
1395.1.18 by Brian Aker
Small update.
1034
  return error;
1237.6.12 by Brian Aker
Adding patch for engine methods for definition files.
1035
}
1036
1618.1.1 by Brian Aker
Modify TableIdentifier to be const
1037
int StorageEngine::writeDefinitionFromPath(const TableIdentifier &identifier, message::Table &table_message)
1237.6.12 by Brian Aker
Adding patch for engine methods for definition files.
1038
{
1395.1.18 by Brian Aker
Small update.
1039
  char definition_file_tmp[FN_REFLEN];
1237.6.12 by Brian Aker
Adding patch for engine methods for definition files.
1040
  string file_name(identifier.getPath());
1041
1042
  file_name.append(DEFAULT_DEFINITION_FILE_EXT);
1043
1415 by Brian Aker
Mass overhaul to use schema_identifier.
1044
  snprintf(definition_file_tmp, sizeof(definition_file_tmp), "%sXXXXXX", file_name.c_str());
1395.1.18 by Brian Aker
Small update.
1045
1046
  int fd= mkstemp(definition_file_tmp);
1237.6.12 by Brian Aker
Adding patch for engine methods for definition files.
1047
1048
  if (fd == -1)
1395.1.1 by Brian Aker
Fixes for alter table to make sure that the proto on disk is valid.
1049
  {
1395.1.18 by Brian Aker
Small update.
1050
    perror(definition_file_tmp);
1237.6.12 by Brian Aker
Adding patch for engine methods for definition files.
1051
    return errno;
1395.1.1 by Brian Aker
Fixes for alter table to make sure that the proto on disk is valid.
1052
  }
1237.6.12 by Brian Aker
Adding patch for engine methods for definition files.
1053
1054
  google::protobuf::io::ZeroCopyOutputStream* output=
1055
    new google::protobuf::io::FileOutputStream(fd);
1056
1608.1.2 by Brian Aker
Merge enum test
1057
  bool success;
1058
1059
  try {
1060
    success= table_message.SerializeToZeroCopyStream(output);
1061
  }
1062
  catch (...)
1063
  {
1064
    success= false;
1065
  }
1066
1067
  if (not success)
1237.6.12 by Brian Aker
Adding patch for engine methods for definition files.
1068
  {
1395.1.18 by Brian Aker
Small update.
1069
    my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0),
1070
             table_message.InitializationErrorString().c_str());
1237.6.12 by Brian Aker
Adding patch for engine methods for definition files.
1071
    delete output;
1395.1.18 by Brian Aker
Small update.
1072
1073
    if (close(fd) == -1)
1074
      perror(definition_file_tmp);
1075
1076
    if (unlink(definition_file_tmp) == -1)
1077
      perror(definition_file_tmp);
1078
1079
    return ER_CORRUPT_TABLE_DEFINITION;
1237.6.12 by Brian Aker
Adding patch for engine methods for definition files.
1080
  }
1081
1082
  delete output;
1395.1.18 by Brian Aker
Small update.
1083
1084
  if (close(fd) == -1)
1085
  {
1086
    int error= errno;
1087
    perror(definition_file_tmp);
1088
1089
    if (unlink(definition_file_tmp))
1090
      perror(definition_file_tmp);
1091
1092
    return error;
1093
  }
1094
1095
  if (rename(definition_file_tmp, file_name.c_str()) == -1)
1096
  {
1097
    int error= errno;
1098
    perror(definition_file_tmp);
1099
1100
    if (unlink(definition_file_tmp))
1101
      perror(definition_file_tmp);
1102
1103
    return error;
1104
  }
1395.1.1 by Brian Aker
Fixes for alter table to make sure that the proto on disk is valid.
1105
1237.6.12 by Brian Aker
Adding patch for engine methods for definition files.
1106
  return 0;
1107
}
1108
1320.1.8 by Brian Aker
Temporary fix for allowing engines to say "don't do this".
1109
class CanCreateTable: public unary_function<StorageEngine *, bool>
1110
{
1618.1.1 by Brian Aker
Modify TableIdentifier to be const
1111
  const TableIdentifier &identifier;
1320.1.8 by Brian Aker
Temporary fix for allowing engines to say "don't do this".
1112
1113
public:
1618.1.1 by Brian Aker
Modify TableIdentifier to be const
1114
  CanCreateTable(const TableIdentifier &identifier_arg) :
1320.1.8 by Brian Aker
Temporary fix for allowing engines to say "don't do this".
1115
    identifier(identifier_arg)
1116
  { }
1117
1118
  result_type operator() (argument_type engine)
1119
  {
1120
    return not engine->doCanCreateTable(identifier);
1121
  }
1122
};
1123
1124
1125
/**
1126
  @note on success table can be created.
1127
*/
1618.1.1 by Brian Aker
Modify TableIdentifier to be const
1128
bool StorageEngine::canCreateTable(const TableIdentifier &identifier)
1320.1.8 by Brian Aker
Temporary fix for allowing engines to say "don't do this".
1129
{
1130
  EngineVector::iterator iter=
1131
    find_if(vector_of_engines.begin(), vector_of_engines.end(),
1132
            CanCreateTable(identifier));
1133
1134
  if (iter == vector_of_engines.end())
1135
  {
1136
    return true;
1137
  }
1138
1139
  return false;
1140
}
1141
1395.1.8 by Brian Aker
Cleanup usage of TI so that the NULL ones no longer exist.
1142
bool StorageEngine::readTableFile(const std::string &path, message::Table &table_message)
1143
{
1144
  fstream input(path.c_str(), ios::in | ios::binary);
1145
1146
  if (input.good())
1147
  {
1608.1.2 by Brian Aker
Merge enum test
1148
    try {
1149
      if (table_message.ParseFromIstream(&input))
1150
      {
1151
        return true;
1152
      }
1153
    }
1154
    catch (...)
1395.1.8 by Brian Aker
Cleanup usage of TI so that the NULL ones no longer exist.
1155
    {
1608.1.2 by Brian Aker
Merge enum test
1156
      my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0),
1157
               table_message.InitializationErrorString().empty() ? "": table_message.InitializationErrorString().c_str());
1395.1.8 by Brian Aker
Cleanup usage of TI so that the NULL ones no longer exist.
1158
    }
1159
  }
1160
  else
1161
  {
1162
    perror(path.c_str());
1163
  }
1164
1165
  return false;
1166
}
1167
1168
1169
1273.1.15 by Jay Pipes
This patch completes the first step in the splitting of
1170
} /* namespace plugin */
1160.1.1 by Brian Aker
Refactor SE createTable back to engine class.
1171
} /* namespace drizzled */