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> |
1130.1.12
by Monty Taylor
Moved service stuff into plugin/ |
28 |
#include <algorithm> |
29 |
#include <functional> |
|
30 |
||
31 |
#include <google/protobuf/io/zero_copy_stream.h> |
|
32 |
#include <google/protobuf/io/zero_copy_stream_impl.h> |
|
33 |
||
1241.9.64
by Monty Taylor
Moved remaining non-public portions of mysys and mystrings to drizzled/internal. |
34 |
#include "drizzled/internal/my_dir.h" |
1241.9.57
by Monty Taylor
Oy. Bigger change than I normally like - but this stuff is all intertwined. |
35 |
#include "drizzled/my_hash.h" |
1241.9.44
by Monty Taylor
Made magic with cached_directory. |
36 |
#include "drizzled/cached_directory.h" |
1130.1.12
by Monty Taylor
Moved service stuff into plugin/ |
37 |
|
575.1.5
by Monty Taylor
Moved stuff to handlerton.cc |
38 |
#include <drizzled/definitions.h> |
39 |
#include <drizzled/base.h> |
|
1183.1.2
by Brian Aker
Rename of handler to Cursor. You would not believe how long I have wanted |
40 |
#include <drizzled/cursor.h> |
960.2.23
by Monty Taylor
Moved handlerton to plugin/storage_engine.h. |
41 |
#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. |
42 |
#include <drizzled/session.h> |
575.1.5
by Monty Taylor
Moved stuff to handlerton.cc |
43 |
#include <drizzled/error.h> |
44 |
#include <drizzled/gettext.h> |
|
971.1.37
by Monty Taylor
Another one bites the dust. |
45 |
#include <drizzled/unireg.h> |
971.1.38
by Monty Taylor
Moved delete table. |
46 |
#include <drizzled/data_home.h> |
1130.1.12
by Monty Taylor
Moved service stuff into plugin/ |
47 |
#include "drizzled/errmsg_print.h" |
48 |
#include "drizzled/xid.h" |
|
1241.9.23
by Monty Taylor
Removed sql_table.h from server_includes.h. |
49 |
#include "drizzled/sql_table.h" |
1241.9.28
by Monty Taylor
Removed global_charset_info.h from server_includes.h |
50 |
#include "drizzled/global_charset_info.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" |
1241.9.28
by Monty Taylor
Removed global_charset_info.h from server_includes.h |
52 |
|
575.1.5
by Monty Taylor
Moved stuff to handlerton.cc |
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> |
55 |
||
1228.3.1
by Monty Taylor
Removed NameMap. Also remove the aliases from the plugin, since we can just |
56 |
#include "drizzled/hash.h" |
1217.1.3
by Brian Aker
Remove NameMap from Storage Engine. Modified the cleanup code to just do a |
57 |
|
58 |
static bool shutdown_has_begun= false; // Once we put in the container for the vector/etc for engines this will go away. |
|
59 |
||
960.2.44
by Monty Taylor
Removed legacy_db_type. |
60 |
using namespace std; |
1130.1.12
by Monty Taylor
Moved service stuff into plugin/ |
61 |
|
62 |
namespace drizzled |
|
63 |
{
|
|
64 |
||
1217.1.3
by Brian Aker
Remove NameMap from Storage Engine. Modified the cleanup code to just do a |
65 |
typedef hash_map<std::string, plugin::StorageEngine *> EngineMap; |
66 |
typedef std::vector<plugin::StorageEngine *> EngineVector; |
|
67 |
||
68 |
static EngineVector vector_of_engines; |
|
69 |
static EngineVector vector_of_transactional_engines; |
|
70 |
||
1228.1.3
by Monty Taylor
All of the outstanding plugin loader system cleanups: |
71 |
const std::string plugin::UNKNOWN_STRING("UNKNOWN"); |
72 |
const std::string plugin::DEFAULT_DEFINITION_FILE_EXT(".dfe"); |
|
73 |
||
1183.1.27
by Brian Aker
Fix issue where there are too many files in data directory. We now only |
74 |
static std::set<std::string> set_of_table_definition_ext; |
1130.1.12
by Monty Taylor
Moved service stuff into plugin/ |
75 |
|
76 |
plugin::StorageEngine::StorageEngine(const string name_arg, |
|
77 |
const bitset<HTON_BIT_SIZE> &flags_arg, |
|
78 |
size_t savepoint_offset_arg, |
|
79 |
bool support_2pc) |
|
1192.2.5
by Monty Taylor
Replaced overridable virtual methods with passing name to constructor. Now individual plugins will not be allowed to set their own plugin type name. :) |
80 |
: Plugin(name_arg, "StorageEngine"), |
1130.2.16
by Monty Taylor
Cleaned up the constructor initializer lists per Brian. |
81 |
two_phase_commit(support_2pc), |
82 |
enabled(true), |
|
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. |
83 |
flags(flags_arg), |
84 |
savepoint_offset(savepoint_alloc_size), |
|
85 |
orig_savepoint_offset(savepoint_offset_arg), |
|
86 |
slot(0) |
|
87 |
{
|
|
88 |
if (enabled) |
|
89 |
{
|
|
90 |
savepoint_alloc_size+= orig_savepoint_offset; |
|
91 |
slot= total_ha++; |
|
92 |
if (two_phase_commit) |
|
93 |
total_ha_2pc++; |
|
968.2.29
by Monty Taylor
First steps towards new plugin reg. |
94 |
}
|
1183.1.30
by Brian Aker
Added engine internal locks (instead of the session based....) |
95 |
pthread_mutex_init(&proto_cache_mutex, NULL); |
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 |
||
1130.1.4
by Monty Taylor
Moved StorageEngine into plugin namespace. |
99 |
plugin::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. |
100 |
{
|
101 |
savepoint_alloc_size-= orig_savepoint_offset; |
|
1183.1.30
by Brian Aker
Added engine internal locks (instead of the session based....) |
102 |
pthread_mutex_destroy(&proto_cache_mutex); |
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. |
103 |
}
|
104 |
||
1183.1.29
by Brian Aker
Clean up interface so that Truncate sets the propper engine when |
105 |
void plugin::StorageEngine::setTransactionReadWrite(Session& session) |
1039.3.8
by Stewart Smith
Re-introduce marking transaction as read-write for engine on create_table: |
106 |
{
|
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) |
107 |
Ha_trx_info *ha_info= session.getEngineInfo(this); |
108 |
||
1039.3.8
by Stewart Smith
Re-introduce marking transaction as read-write for engine on create_table: |
109 |
/*
|
110 |
When a storage engine method is called, the transaction must
|
|
111 |
have been started, unless it's a DDL call, for which the
|
|
112 |
storage engine starts the transaction internally, and commits
|
|
113 |
it internally, without registering in the ha_list.
|
|
114 |
Unfortunately here we can't know know for sure if the engine
|
|
115 |
has registered the transaction or not, so we must check.
|
|
116 |
*/
|
|
117 |
if (ha_info->is_started()) |
|
118 |
{
|
|
119 |
/*
|
|
1183.1.22
by Brian Aker
Merge Name changes |
120 |
* table_share can be NULL in plugin::StorageEngine::dropTable().
|
1152.1.2
by Brian Aker
First pass through Monty's engine patch for removing dead abstraction |
121 |
*/
|
1109.1.1
by Brian Aker
Applying refactor of tmp table bits back to session. (this all needs to be |
122 |
ha_info->set_trx_read_write(); |
1039.3.8
by Stewart Smith
Re-introduce marking transaction as read-write for engine on create_table: |
123 |
}
|
124 |
}
|
|
125 |
||
575.1.5
by Monty Taylor
Moved stuff to handlerton.cc |
126 |
|
1130.1.12
by Monty Taylor
Moved service stuff into plugin/ |
127 |
|
1183.1.7
by Brian Aker
Fix name conventions for rename table |
128 |
int plugin::StorageEngine::doRenameTable(Session *, |
129 |
const char *from, |
|
130 |
const char *to) |
|
1039.3.5
by Stewart Smith
move handler::rename_table to StorageEngine |
131 |
{
|
132 |
int error= 0; |
|
133 |
for (const char **ext= bas_ext(); *ext ; ext++) |
|
134 |
{
|
|
135 |
if (rename_file_ext(from, to, *ext)) |
|
136 |
{
|
|
1241.9.57
by Monty Taylor
Oy. Bigger change than I normally like - but this stuff is all intertwined. |
137 |
if ((error=errno) != ENOENT) |
1039.3.5
by Stewart Smith
move handler::rename_table to StorageEngine |
138 |
break; |
139 |
error= 0; |
|
140 |
}
|
|
141 |
}
|
|
142 |
return error; |
|
143 |
}
|
|
144 |
||
145 |
||
1039.3.2
by Stewart Smith
move delete_table out of handler and up into StorageEngine where it belongs. |
146 |
/**
|
147 |
Delete all files with extension from bas_ext().
|
|
148 |
||
149 |
@param name Base name of table
|
|
150 |
||
151 |
@note
|
|
1183.1.2
by Brian Aker
Rename of handler to Cursor. You would not believe how long I have wanted |
152 |
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. |
153 |
was actually used for the file.
|
154 |
||
155 |
@retval
|
|
156 |
0 If we successfully deleted at least one file from base_ext and
|
|
157 |
didn't get any other errors than ENOENT
|
|
158 |
@retval
|
|
159 |
!0 Error
|
|
160 |
*/
|
|
1183.1.29
by Brian Aker
Clean up interface so that Truncate sets the propper engine when |
161 |
int plugin::StorageEngine::doDropTable(Session&, |
162 |
const string table_path) |
|
1039.3.2
by Stewart Smith
move delete_table out of handler and up into StorageEngine where it belongs. |
163 |
{
|
164 |
int error= 0; |
|
165 |
int enoent_or_zero= ENOENT; // Error if no file was deleted |
|
166 |
char buff[FN_REFLEN]; |
|
167 |
||
1183.1.21
by Brian Aker
Fixed temp engines to no longer write out DFE. I have two designs right now |
168 |
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. |
169 |
{
|
170 |
fn_format(buff, table_path.c_str(), "", *ext, |
|
171 |
MY_UNPACK_FILENAME|MY_APPEND_EXT); |
|
172 |
if (my_delete_with_symlink(buff, MYF(0))) |
|
173 |
{
|
|
1241.9.57
by Monty Taylor
Oy. Bigger change than I normally like - but this stuff is all intertwined. |
174 |
if ((error= errno) != ENOENT) |
1039.3.2
by Stewart Smith
move delete_table out of handler and up into StorageEngine where it belongs. |
175 |
break; |
176 |
}
|
|
177 |
else
|
|
178 |
enoent_or_zero= 0; // No error for ENOENT |
|
179 |
error= enoent_or_zero; |
|
180 |
}
|
|
181 |
return error; |
|
182 |
}
|
|
971.1.38
by Monty Taylor
Moved delete table. |
183 |
|
1130.1.12
by Monty Taylor
Moved service stuff into plugin/ |
184 |
const char *plugin::StorageEngine::checkLowercaseNames(const char *path, |
185 |
char *tmp_path) |
|
186 |
{
|
|
187 |
if (flags.test(HTON_BIT_FILE_BASED)) |
|
188 |
return path; |
|
189 |
||
1183.1.2
by Brian Aker
Rename of handler to Cursor. You would not believe how long I have wanted |
190 |
/* Ensure that table Cursor get path in lower case */
|
1130.1.12
by Monty Taylor
Moved service stuff into plugin/ |
191 |
if (tmp_path != path) |
192 |
strcpy(tmp_path, path); |
|
193 |
||
194 |
/*
|
|
195 |
we only should turn into lowercase database/table part
|
|
196 |
so start the process after homedirectory
|
|
197 |
*/
|
|
198 |
if (strstr(tmp_path, drizzle_tmpdir) == tmp_path) |
|
199 |
my_casedn_str(files_charset_info, tmp_path + strlen(drizzle_tmpdir)); |
|
200 |
else
|
|
201 |
my_casedn_str(files_charset_info, tmp_path + drizzle_data_home_len); |
|
202 |
||
203 |
return tmp_path; |
|
204 |
}
|
|
205 |
||
206 |
||
1130.1.19
by Monty Taylor
Added error reporting to plugin registration. |
207 |
bool plugin::StorageEngine::addPlugin(plugin::StorageEngine *engine) |
1130.1.12
by Monty Taylor
Moved service stuff into plugin/ |
208 |
{
|
1217.1.3
by Brian Aker
Remove NameMap from Storage Engine. Modified the cleanup code to just do a |
209 |
|
1183.1.5
by Brian Aker
Reworked getTableNames() interface. Way simpler, less mallocs.... |
210 |
vector_of_engines.push_back(engine); |
211 |
||
1183.1.17
by Brian Aker
Added Innodb specific vector (well... for any engine) |
212 |
if (engine->check_flag(HTON_BIT_DOES_TRANSACTIONS)) |
213 |
vector_of_transactional_engines.push_back(engine); |
|
214 |
||
1213
by Brian Aker
Fixes startup failures when temporary tables were left behind in a crash. |
215 |
if (engine->getTableDefinitionFileExtension().length()) |
1183.1.27
by Brian Aker
Fix issue where there are too many files in data directory. We now only |
216 |
{
|
1213
by Brian Aker
Fixes startup failures when temporary tables were left behind in a crash. |
217 |
assert(engine->getTableDefinitionFileExtension().length() == DEFAULT_DEFINITION_FILE_EXT.length()); |
218 |
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 |
219 |
}
|
220 |
||
1130.1.19
by Monty Taylor
Added error reporting to plugin registration. |
221 |
return false; |
1130.1.12
by Monty Taylor
Moved service stuff into plugin/ |
222 |
}
|
223 |
||
1217.1.3
by Brian Aker
Remove NameMap from Storage Engine. Modified the cleanup code to just do a |
224 |
void plugin::StorageEngine::removePlugin(plugin::StorageEngine *) |
1130.1.12
by Monty Taylor
Moved service stuff into plugin/ |
225 |
{
|
1217.1.3
by Brian Aker
Remove NameMap from Storage Engine. Modified the cleanup code to just do a |
226 |
if (shutdown_has_begun == false) |
227 |
{
|
|
228 |
vector_of_engines.clear(); |
|
229 |
vector_of_transactional_engines.clear(); |
|
230 |
||
231 |
shutdown_has_begun= true; |
|
232 |
}
|
|
1130.1.12
by Monty Taylor
Moved service stuff into plugin/ |
233 |
}
|
234 |
||
1228.3.2
by Monty Taylor
Removed engine_map - just use vector_of_engines. |
235 |
class FindEngineByName |
236 |
: public unary_function<plugin::StorageEngine *, bool> |
|
237 |
{
|
|
238 |
const string target; |
|
239 |
public: |
|
240 |
explicit FindEngineByName(const string target_arg) |
|
241 |
: target(target_arg) |
|
242 |
{}
|
|
243 |
result_type operator() (argument_type engine) |
|
244 |
{
|
|
245 |
string engine_name(engine->getName()); |
|
246 |
||
247 |
transform(engine_name.begin(), engine_name.end(), |
|
248 |
engine_name.begin(), ::tolower); |
|
249 |
return engine_name == target; |
|
250 |
}
|
|
251 |
};
|
|
252 |
||
1183.1.29
by Brian Aker
Clean up interface so that Truncate sets the propper engine when |
253 |
plugin::StorageEngine *plugin::StorageEngine::findByName(string find_str) |
254 |
{
|
|
255 |
transform(find_str.begin(), find_str.end(), |
|
256 |
find_str.begin(), ::tolower); |
|
257 |
||
1228.3.2
by Monty Taylor
Removed engine_map - just use vector_of_engines. |
258 |
|
259 |
EngineVector::iterator iter= find_if(vector_of_engines.begin(), |
|
260 |
vector_of_engines.end(), |
|
261 |
FindEngineByName(find_str)); |
|
262 |
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 |
263 |
{
|
1228.3.2
by Monty Taylor
Removed engine_map - just use vector_of_engines. |
264 |
StorageEngine *engine= *iter; |
1217.1.3
by Brian Aker
Remove NameMap from Storage Engine. Modified the cleanup code to just do a |
265 |
if (engine->is_user_selectable()) |
266 |
return engine; |
|
267 |
}
|
|
1183.1.29
by Brian Aker
Clean up interface so that Truncate sets the propper engine when |
268 |
|
269 |
return NULL; |
|
270 |
}
|
|
271 |
||
272 |
plugin::StorageEngine *plugin::StorageEngine::findByName(Session& session, |
|
1130.1.12
by Monty Taylor
Moved service stuff into plugin/ |
273 |
string find_str) |
274 |
{
|
|
275 |
||
276 |
transform(find_str.begin(), find_str.end(), |
|
277 |
find_str.begin(), ::tolower); |
|
1183.1.5
by Brian Aker
Reworked getTableNames() interface. Way simpler, less mallocs.... |
278 |
|
279 |
if (find_str.compare("default") == 0) |
|
1183.1.29
by Brian Aker
Clean up interface so that Truncate sets the propper engine when |
280 |
return session.getDefaultStorageEngine(); |
1130.1.12
by Monty Taylor
Moved service stuff into plugin/ |
281 |
|
1228.3.2
by Monty Taylor
Removed engine_map - just use vector_of_engines. |
282 |
EngineVector::iterator iter= find_if(vector_of_engines.begin(), |
283 |
vector_of_engines.end(), |
|
284 |
FindEngineByName(find_str)); |
|
285 |
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 |
286 |
{
|
1228.3.2
by Monty Taylor
Removed engine_map - just use vector_of_engines. |
287 |
StorageEngine *engine= *iter; |
1217.1.3
by Brian Aker
Remove NameMap from Storage Engine. Modified the cleanup code to just do a |
288 |
if (engine->is_user_selectable()) |
289 |
return engine; |
|
290 |
}
|
|
1130.1.12
by Monty Taylor
Moved service stuff into plugin/ |
291 |
|
292 |
return NULL; |
|
293 |
}
|
|
294 |
||
295 |
class StorageEngineCloseConnection |
|
1217.1.3
by Brian Aker
Remove NameMap from Storage Engine. Modified the cleanup code to just do a |
296 |
: public unary_function<plugin::StorageEngine *, void> |
1130.1.12
by Monty Taylor
Moved service stuff into plugin/ |
297 |
{
|
298 |
Session *session; |
|
299 |
public: |
|
300 |
StorageEngineCloseConnection(Session *session_arg) : session(session_arg) {} |
|
301 |
/*
|
|
302 |
there's no need to rollback here as all transactions must
|
|
303 |
be rolled back already
|
|
304 |
*/
|
|
305 |
inline result_type operator() (argument_type engine) |
|
306 |
{
|
|
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) |
307 |
if (engine->is_enabled() && (*session->getEngineData(engine))) |
308 |
engine->close_connection(session); |
|
1130.1.12
by Monty Taylor
Moved service stuff into plugin/ |
309 |
}
|
310 |
};
|
|
311 |
||
312 |
/**
|
|
313 |
@note
|
|
314 |
don't bother to rollback here, it's done already
|
|
315 |
*/
|
|
316 |
void plugin::StorageEngine::closeConnection(Session* session) |
|
317 |
{
|
|
1183.1.16
by Brian Aker
Switch to using vector over Registry |
318 |
for_each(vector_of_engines.begin(), vector_of_engines.end(), |
1130.1.12
by Monty Taylor
Moved service stuff into plugin/ |
319 |
StorageEngineCloseConnection(session)); |
320 |
}
|
|
321 |
||
322 |
void plugin::StorageEngine::dropDatabase(char* path) |
|
323 |
{
|
|
1183.1.16
by Brian Aker
Switch to using vector over Registry |
324 |
for_each(vector_of_engines.begin(), vector_of_engines.end(), |
1130.1.12
by Monty Taylor
Moved service stuff into plugin/ |
325 |
bind2nd(mem_fun(&plugin::StorageEngine::drop_database),path)); |
326 |
}
|
|
327 |
||
328 |
int plugin::StorageEngine::commitOrRollbackByXID(XID *xid, bool commit) |
|
329 |
{
|
|
330 |
vector<int> results; |
|
331 |
||
332 |
if (commit) |
|
1217.1.3
by Brian Aker
Remove NameMap from Storage Engine. Modified the cleanup code to just do a |
333 |
transform(vector_of_engines.begin(), vector_of_engines.end(), results.begin(), |
1130.1.12
by Monty Taylor
Moved service stuff into plugin/ |
334 |
bind2nd(mem_fun(&plugin::StorageEngine::commit_by_xid),xid)); |
335 |
else
|
|
1217.1.3
by Brian Aker
Remove NameMap from Storage Engine. Modified the cleanup code to just do a |
336 |
transform(vector_of_engines.begin(), vector_of_engines.end(), results.begin(), |
1130.1.12
by Monty Taylor
Moved service stuff into plugin/ |
337 |
bind2nd(mem_fun(&plugin::StorageEngine::rollback_by_xid),xid)); |
338 |
||
339 |
if (find_if(results.begin(), results.end(), bind2nd(equal_to<int>(),0)) |
|
340 |
== results.end()) |
|
341 |
return 1; |
|
342 |
return 0; |
|
343 |
}
|
|
344 |
||
345 |
/**
|
|
346 |
@details
|
|
347 |
This function should be called when MySQL sends rows of a SELECT result set
|
|
348 |
or the EOF mark to the client. It releases a possible adaptive hash index
|
|
349 |
S-latch held by session in InnoDB and also releases a possible InnoDB query
|
|
350 |
FIFO ticket to enter InnoDB. To save CPU time, InnoDB allows a session to
|
|
1183.1.2
by Brian Aker
Rename of handler to Cursor. You would not believe how long I have wanted |
351 |
keep them over several calls of the InnoDB Cursor interface when a join
|
1130.1.12
by Monty Taylor
Moved service stuff into plugin/ |
352 |
is executed. But when we let the control to pass to the client they have
|
353 |
to be released because if the application program uses mysql_use_result(),
|
|
354 |
it may deadlock on the S-latch if the application on another connection
|
|
355 |
performs another SQL query. In MySQL-4.1 this is even more important because
|
|
356 |
there a connection can have several SELECT queries open at the same time.
|
|
357 |
||
358 |
@param session the thread handle of the current connection
|
|
359 |
||
360 |
@return
|
|
361 |
always 0
|
|
362 |
*/
|
|
363 |
int plugin::StorageEngine::releaseTemporaryLatches(Session *session) |
|
364 |
{
|
|
1183.1.17
by Brian Aker
Added Innodb specific vector (well... for any engine) |
365 |
for_each(vector_of_transactional_engines.begin(), vector_of_transactional_engines.end(), |
1130.1.12
by Monty Taylor
Moved service stuff into plugin/ |
366 |
bind2nd(mem_fun(&plugin::StorageEngine::release_temporary_latches),session)); |
367 |
return 0; |
|
368 |
}
|
|
369 |
||
370 |
bool plugin::StorageEngine::flushLogs(plugin::StorageEngine *engine) |
|
371 |
{
|
|
372 |
if (engine == NULL) |
|
373 |
{
|
|
1217.1.3
by Brian Aker
Remove NameMap from Storage Engine. Modified the cleanup code to just do a |
374 |
if (find_if(vector_of_engines.begin(), vector_of_engines.end(), |
1130.1.12
by Monty Taylor
Moved service stuff into plugin/ |
375 |
mem_fun(&plugin::StorageEngine::flush_logs)) |
1217.1.3
by Brian Aker
Remove NameMap from Storage Engine. Modified the cleanup code to just do a |
376 |
!= vector_of_engines.begin()) |
1130.1.12
by Monty Taylor
Moved service stuff into plugin/ |
377 |
return true; |
378 |
}
|
|
379 |
else
|
|
380 |
{
|
|
381 |
if ((!engine->is_enabled()) || |
|
382 |
(engine->flush_logs())) |
|
383 |
return true; |
|
384 |
}
|
|
385 |
return false; |
|
386 |
}
|
|
387 |
||
388 |
/**
|
|
389 |
recover() step of xa.
|
|
390 |
||
391 |
@note
|
|
392 |
there are three modes of operation:
|
|
393 |
- automatic recover after a crash
|
|
394 |
in this case commit_list != 0, tc_heuristic_recover==0
|
|
395 |
all xids from commit_list are committed, others are rolled back
|
|
396 |
- manual (heuristic) recover
|
|
397 |
in this case commit_list==0, tc_heuristic_recover != 0
|
|
398 |
DBA has explicitly specified that all prepared transactions should
|
|
399 |
be committed (or rolled back).
|
|
400 |
- no recovery (MySQL did not detect a crash)
|
|
401 |
in this case commit_list==0, tc_heuristic_recover == 0
|
|
402 |
there should be no prepared transactions in this case.
|
|
403 |
*/
|
|
404 |
class XARecover : unary_function<plugin::StorageEngine *, void> |
|
405 |
{
|
|
406 |
int trans_len, found_foreign_xids, found_my_xids; |
|
407 |
bool result; |
|
408 |
XID *trans_list; |
|
409 |
HASH *commit_list; |
|
410 |
bool dry_run; |
|
411 |
public: |
|
412 |
XARecover(XID *trans_list_arg, int trans_len_arg, |
|
413 |
HASH *commit_list_arg, bool dry_run_arg) |
|
414 |
: trans_len(trans_len_arg), found_foreign_xids(0), found_my_xids(0), |
|
415 |
result(false), |
|
416 |
trans_list(trans_list_arg), commit_list(commit_list_arg), |
|
417 |
dry_run(dry_run_arg) |
|
418 |
{}
|
|
419 |
||
420 |
int getForeignXIDs() |
|
421 |
{
|
|
422 |
return found_foreign_xids; |
|
423 |
}
|
|
424 |
||
425 |
int getMyXIDs() |
|
426 |
{
|
|
427 |
return found_my_xids; |
|
428 |
}
|
|
429 |
||
430 |
result_type operator() (argument_type engine) |
|
431 |
{
|
|
432 |
||
433 |
int got; |
|
434 |
||
435 |
if (engine->is_enabled()) |
|
436 |
{
|
|
437 |
while ((got= engine->recover(trans_list, trans_len)) > 0 ) |
|
438 |
{
|
|
439 |
errmsg_printf(ERRMSG_LVL_INFO, |
|
440 |
_("Found %d prepared transaction(s) in %s"), |
|
441 |
got, engine->getName().c_str()); |
|
442 |
for (int i=0; i < got; i ++) |
|
443 |
{
|
|
444 |
my_xid x=trans_list[i].get_my_xid(); |
|
445 |
if (!x) // not "mine" - that is generated by external TM |
|
446 |
{
|
|
447 |
xid_cache_insert(trans_list+i, XA_PREPARED); |
|
448 |
found_foreign_xids++; |
|
449 |
continue; |
|
450 |
}
|
|
451 |
if (dry_run) |
|
452 |
{
|
|
453 |
found_my_xids++; |
|
454 |
continue; |
|
455 |
}
|
|
456 |
// recovery mode
|
|
457 |
if (commit_list ? |
|
458 |
hash_search(commit_list, (unsigned char *)&x, sizeof(x)) != 0 : |
|
459 |
tc_heuristic_recover == TC_HEURISTIC_RECOVER_COMMIT) |
|
460 |
{
|
|
461 |
engine->commit_by_xid(trans_list+i); |
|
462 |
}
|
|
463 |
else
|
|
464 |
{
|
|
465 |
engine->rollback_by_xid(trans_list+i); |
|
466 |
}
|
|
467 |
}
|
|
468 |
if (got < trans_len) |
|
469 |
break; |
|
470 |
}
|
|
471 |
}
|
|
472 |
}
|
|
473 |
};
|
|
474 |
||
475 |
int plugin::StorageEngine::recover(HASH *commit_list) |
|
476 |
{
|
|
477 |
XID *trans_list= NULL; |
|
478 |
int trans_len= 0; |
|
479 |
||
480 |
bool dry_run= (commit_list==0 && tc_heuristic_recover==0); |
|
481 |
||
482 |
/* commit_list and tc_heuristic_recover cannot be set both */
|
|
483 |
assert(commit_list==0 || tc_heuristic_recover==0); |
|
484 |
||
485 |
/* if either is set, total_ha_2pc must be set too */
|
|
486 |
if (total_ha_2pc <= 1) |
|
487 |
return 0; |
|
488 |
||
489 |
||
490 |
#ifndef WILL_BE_DELETED_LATER
|
|
491 |
||
492 |
/*
|
|
493 |
for now, only InnoDB supports 2pc. It means we can always safely
|
|
494 |
rollback all pending transactions, without risking inconsistent data
|
|
495 |
*/
|
|
496 |
||
497 |
assert(total_ha_2pc == 2); // only InnoDB and binlog |
|
498 |
tc_heuristic_recover= TC_HEURISTIC_RECOVER_ROLLBACK; // forcing ROLLBACK |
|
499 |
dry_run=false; |
|
500 |
#endif
|
|
501 |
for (trans_len= MAX_XID_LIST_SIZE ; |
|
502 |
trans_list==0 && trans_len > MIN_XID_LIST_SIZE; trans_len/=2) |
|
503 |
{
|
|
504 |
trans_list=(XID *)malloc(trans_len*sizeof(XID)); |
|
505 |
}
|
|
506 |
if (!trans_list) |
|
507 |
{
|
|
508 |
errmsg_printf(ERRMSG_LVL_ERROR, ER(ER_OUTOFMEMORY), trans_len*sizeof(XID)); |
|
509 |
return(1); |
|
510 |
}
|
|
511 |
||
512 |
if (commit_list) |
|
513 |
errmsg_printf(ERRMSG_LVL_INFO, _("Starting crash recovery...")); |
|
514 |
||
515 |
||
516 |
XARecover recover_func(trans_list, trans_len, commit_list, dry_run); |
|
1183.1.17
by Brian Aker
Added Innodb specific vector (well... for any engine) |
517 |
for_each(vector_of_transactional_engines.begin(), vector_of_transactional_engines.end(), |
1183.1.16
by Brian Aker
Switch to using vector over Registry |
518 |
recover_func); |
1130.1.12
by Monty Taylor
Moved service stuff into plugin/ |
519 |
free(trans_list); |
520 |
||
521 |
if (recover_func.getForeignXIDs()) |
|
522 |
errmsg_printf(ERRMSG_LVL_WARN, |
|
523 |
_("Found %d prepared XA transactions"), |
|
524 |
recover_func.getForeignXIDs()); |
|
525 |
if (dry_run && recover_func.getMyXIDs()) |
|
526 |
{
|
|
527 |
errmsg_printf(ERRMSG_LVL_ERROR, |
|
528 |
_("Found %d prepared transactions! It means that drizzled " |
|
529 |
"was not shut down properly last time and critical "
|
|
530 |
"recovery information (last binlog or %s file) was "
|
|
531 |
"manually deleted after a crash. You have to start "
|
|
532 |
"drizzled with the --tc-heuristic-recover switch to "
|
|
533 |
"commit or rollback pending transactions."), |
|
534 |
recover_func.getMyXIDs(), opt_tc_log_file); |
|
535 |
return(1); |
|
536 |
}
|
|
537 |
if (commit_list) |
|
538 |
errmsg_printf(ERRMSG_LVL_INFO, _("Crash recovery finished.")); |
|
539 |
return(0); |
|
540 |
}
|
|
541 |
||
542 |
int plugin::StorageEngine::startConsistentSnapshot(Session *session) |
|
543 |
{
|
|
1183.1.16
by Brian Aker
Switch to using vector over Registry |
544 |
for_each(vector_of_engines.begin(), vector_of_engines.end(), |
1130.1.12
by Monty Taylor
Moved service stuff into plugin/ |
545 |
bind2nd(mem_fun(&plugin::StorageEngine::start_consistent_snapshot), |
546 |
session)); |
|
547 |
return 0; |
|
548 |
}
|
|
549 |
||
1200
by Brian Aker
Clean up some mispellings |
550 |
class StorageEngineGetTableDefinition: public unary_function<plugin::StorageEngine *,bool> |
1130.1.12
by Monty Taylor
Moved service stuff into plugin/ |
551 |
{
|
1183.1.29
by Brian Aker
Clean up interface so that Truncate sets the propper engine when |
552 |
Session& session; |
1130.1.12
by Monty Taylor
Moved service stuff into plugin/ |
553 |
const char* path; |
1183.5.1
by Brian Aker
Extended definition interface (filename building should now be moved |
554 |
const char *db; |
555 |
const char *table_name; |
|
556 |
const bool is_tmp; |
|
1130.1.12
by Monty Taylor
Moved service stuff into plugin/ |
557 |
message::Table *table_proto; |
558 |
int *err; |
|
1183.5.1
by Brian Aker
Extended definition interface (filename building should now be moved |
559 |
|
1130.1.12
by Monty Taylor
Moved service stuff into plugin/ |
560 |
public: |
1200
by Brian Aker
Clean up some mispellings |
561 |
StorageEngineGetTableDefinition(Session& session_arg, |
562 |
const char* path_arg, |
|
563 |
const char *db_arg, |
|
564 |
const char *table_name_arg, |
|
565 |
const bool is_tmp_arg, |
|
566 |
message::Table *table_proto_arg, |
|
567 |
int *err_arg) : |
|
1183.1.29
by Brian Aker
Clean up interface so that Truncate sets the propper engine when |
568 |
session(session_arg), |
569 |
path(path_arg), |
|
1183.5.1
by Brian Aker
Extended definition interface (filename building should now be moved |
570 |
db(db_arg), |
571 |
table_name(table_name_arg), |
|
572 |
is_tmp(is_tmp_arg), |
|
573 |
table_proto(table_proto_arg), |
|
574 |
err(err_arg) {} |
|
1130.1.12
by Monty Taylor
Moved service stuff into plugin/ |
575 |
|
576 |
result_type operator() (argument_type engine) |
|
577 |
{
|
|
1183.1.29
by Brian Aker
Clean up interface so that Truncate sets the propper engine when |
578 |
int ret= engine->doGetTableDefinition(session, |
579 |
path, |
|
1183.5.1
by Brian Aker
Extended definition interface (filename building should now be moved |
580 |
db, |
581 |
table_name, |
|
582 |
is_tmp, |
|
583 |
table_proto); |
|
1130.1.12
by Monty Taylor
Moved service stuff into plugin/ |
584 |
|
585 |
if (ret != ENOENT) |
|
586 |
*err= ret; |
|
587 |
||
588 |
return *err == EEXIST; |
|
589 |
}
|
|
590 |
};
|
|
591 |
||
592 |
static int drizzle_read_table_proto(const char* path, message::Table* table) |
|
593 |
{
|
|
594 |
int fd= open(path, O_RDONLY); |
|
595 |
||
596 |
if (fd == -1) |
|
597 |
return errno; |
|
598 |
||
599 |
google::protobuf::io::ZeroCopyInputStream* input= |
|
600 |
new google::protobuf::io::FileInputStream(fd); |
|
601 |
||
602 |
if (table->ParseFromZeroCopyStream(input) == false) |
|
603 |
{
|
|
604 |
delete input; |
|
605 |
close(fd); |
|
606 |
return -1; |
|
607 |
}
|
|
608 |
||
609 |
delete input; |
|
610 |
close(fd); |
|
611 |
return 0; |
|
612 |
}
|
|
613 |
||
614 |
/**
|
|
1183.1.2
by Brian Aker
Rename of handler to Cursor. You would not believe how long I have wanted |
615 |
Call this function in order to give the Cursor the possiblity
|
1130.1.12
by Monty Taylor
Moved service stuff into plugin/ |
616 |
to ask engine if there are any new tables that should be written to disk
|
617 |
or any dropped tables that need to be removed from disk
|
|
618 |
*/
|
|
1183.1.29
by Brian Aker
Clean up interface so that Truncate sets the propper engine when |
619 |
int plugin::StorageEngine::getTableDefinition(Session& session, |
1223.4.17
by Brian Aker
Added a form of getTableDefinition() that uses TableIdentifiers |
620 |
TableIdentifier &identifier, |
621 |
message::Table *table_proto) |
|
622 |
{
|
|
623 |
return getTableDefinition(session, |
|
624 |
identifier.getPath(), identifier.getDBName(), identifier.getTableName(), identifier.isTmp(), |
|
625 |
table_proto); |
|
626 |
}
|
|
627 |
||
628 |
int plugin::StorageEngine::getTableDefinition(Session& session, |
|
1183.1.29
by Brian Aker
Clean up interface so that Truncate sets the propper engine when |
629 |
const char* path, |
1183.5.1
by Brian Aker
Extended definition interface (filename building should now be moved |
630 |
const char *, |
631 |
const char *, |
|
632 |
const bool, |
|
633 |
message::Table *table_proto) |
|
1130.1.12
by Monty Taylor
Moved service stuff into plugin/ |
634 |
{
|
635 |
int err= ENOENT; |
|
636 |
||
1183.1.16
by Brian Aker
Switch to using vector over Registry |
637 |
vector<plugin::StorageEngine *>::iterator iter= |
638 |
find_if(vector_of_engines.begin(), vector_of_engines.end(), |
|
1200
by Brian Aker
Clean up some mispellings |
639 |
StorageEngineGetTableDefinition(session, path, NULL, NULL, true, table_proto, &err)); |
1183.1.16
by Brian Aker
Switch to using vector over Registry |
640 |
|
641 |
if (iter == vector_of_engines.end()) |
|
1130.1.12
by Monty Taylor
Moved service stuff into plugin/ |
642 |
{
|
643 |
string proto_path(path); |
|
644 |
string file_ext(".dfe"); |
|
645 |
proto_path.append(file_ext); |
|
646 |
||
647 |
int error= access(proto_path.c_str(), F_OK); |
|
648 |
||
649 |
if (error == 0) |
|
650 |
err= EEXIST; |
|
651 |
else
|
|
652 |
err= errno; |
|
653 |
||
654 |
if (table_proto) |
|
655 |
{
|
|
656 |
int read_proto_err= drizzle_read_table_proto(proto_path.c_str(), |
|
657 |
table_proto); |
|
658 |
||
659 |
if (read_proto_err) |
|
660 |
err= read_proto_err; |
|
661 |
}
|
|
662 |
}
|
|
663 |
||
664 |
return err; |
|
665 |
}
|
|
666 |
||
667 |
/**
|
|
668 |
An interceptor to hijack the text of the error message without
|
|
669 |
setting an error in the thread. We need the text to present it
|
|
670 |
in the form of a warning to the user.
|
|
671 |
*/
|
|
672 |
||
673 |
class Ha_delete_table_error_handler: public Internal_error_handler |
|
674 |
{
|
|
675 |
public: |
|
676 |
Ha_delete_table_error_handler() : Internal_error_handler() {} |
|
677 |
virtual bool handle_error(uint32_t sql_errno, |
|
678 |
const char *message, |
|
679 |
DRIZZLE_ERROR::enum_warning_level level, |
|
680 |
Session *session); |
|
681 |
char buff[DRIZZLE_ERRMSG_SIZE]; |
|
682 |
};
|
|
683 |
||
684 |
||
685 |
bool
|
|
686 |
Ha_delete_table_error_handler:: |
|
687 |
handle_error(uint32_t , |
|
688 |
const char *message, |
|
689 |
DRIZZLE_ERROR::enum_warning_level , |
|
690 |
Session *) |
|
691 |
{
|
|
692 |
/* Grab the error message */
|
|
693 |
strncpy(buff, message, sizeof(buff)-1); |
|
694 |
return true; |
|
695 |
}
|
|
696 |
||
697 |
||
698 |
/**
|
|
699 |
This should return ENOENT if the file doesn't exists.
|
|
700 |
The .frm file will be deleted only if we return 0 or ENOENT
|
|
701 |
*/
|
|
1223.4.16
by Brian Aker
Drop Table now uses identifier. |
702 |
int plugin::StorageEngine::dropTable(Session& session, |
703 |
TableIdentifier &identifier, |
|
1183.1.22
by Brian Aker
Merge Name changes |
704 |
bool generate_warning) |
1130.1.12
by Monty Taylor
Moved service stuff into plugin/ |
705 |
{
|
1183.1.8
by Brian Aker
Reworked delete table code (thank god... or... whatever... how about my dog? |
706 |
int error= 0; |
707 |
int error_proto; |
|
708 |
message::Table src_proto; |
|
709 |
plugin::StorageEngine* engine; |
|
710 |
||
1183.1.29
by Brian Aker
Clean up interface so that Truncate sets the propper engine when |
711 |
error_proto= plugin::StorageEngine::getTableDefinition(session, |
1223.4.17
by Brian Aker
Added a form of getTableDefinition() that uses TableIdentifiers |
712 |
identifier, |
1183.5.1
by Brian Aker
Extended definition interface (filename building should now be moved |
713 |
&src_proto); |
1183.1.8
by Brian Aker
Reworked delete table code (thank god... or... whatever... how about my dog? |
714 |
|
715 |
engine= plugin::StorageEngine::findByName(session, |
|
716 |
src_proto.engine().name()); |
|
717 |
||
718 |
if (engine) |
|
1183.1.9
by Brian Aker
Rename deleteTableImpl -> doDeleteTable() |
719 |
{
|
720 |
engine->setTransactionReadWrite(session); |
|
1223.4.16
by Brian Aker
Drop Table now uses identifier. |
721 |
error= engine->doDropTable(session, identifier.getPath()); |
1183.1.9
by Brian Aker
Rename deleteTableImpl -> doDeleteTable() |
722 |
}
|
1183.1.8
by Brian Aker
Reworked delete table code (thank god... or... whatever... how about my dog? |
723 |
|
724 |
if (error != ENOENT) |
|
725 |
{
|
|
726 |
if (error == 0) |
|
727 |
{
|
|
728 |
if (engine && engine->check_flag(HTON_BIT_HAS_DATA_DICTIONARY)) |
|
1237.6.12
by Brian Aker
Adding patch for engine methods for definition files. |
729 |
{
|
730 |
deleteDefinitionFromPath(identifier); |
|
731 |
}
|
|
1183.1.8
by Brian Aker
Reworked delete table code (thank god... or... whatever... how about my dog? |
732 |
else
|
1237.6.12
by Brian Aker
Adding patch for engine methods for definition files. |
733 |
{
|
734 |
error= deleteDefinitionFromPath(identifier); |
|
735 |
}
|
|
1183.1.8
by Brian Aker
Reworked delete table code (thank god... or... whatever... how about my dog? |
736 |
}
|
737 |
}
|
|
738 |
||
739 |
if (error_proto && error == 0) |
|
740 |
return 0; |
|
1130.1.12
by Monty Taylor
Moved service stuff into plugin/ |
741 |
|
742 |
if (error && generate_warning) |
|
743 |
{
|
|
744 |
/*
|
|
1216.1.1
by Brian Aker
Move print_error up to Engine. |
745 |
Because engine->print_error() use my_error() to generate the error message
|
1183.1.2
by Brian Aker
Rename of handler to Cursor. You would not believe how long I have wanted |
746 |
we use an internal error Cursor to intercept it and store the text
|
1130.1.12
by Monty Taylor
Moved service stuff into plugin/ |
747 |
in a temporary buffer. Later the message will be presented to user
|
748 |
as a warning.
|
|
749 |
*/
|
|
750 |
Ha_delete_table_error_handler ha_delete_table_error_handler; |
|
751 |
||
1216.1.1
by Brian Aker
Move print_error up to Engine. |
752 |
session.push_internal_handler(&ha_delete_table_error_handler); |
753 |
engine->print_error(error, 0); |
|
754 |
||
755 |
session.pop_internal_handler(); |
|
1130.1.12
by Monty Taylor
Moved service stuff into plugin/ |
756 |
|
757 |
/*
|
|
758 |
XXX: should we convert *all* errors to warnings here?
|
|
759 |
What if the error is fatal?
|
|
760 |
*/
|
|
1183.1.29
by Brian Aker
Clean up interface so that Truncate sets the propper engine when |
761 |
push_warning(&session, DRIZZLE_ERROR::WARN_LEVEL_ERROR, error, |
1130.1.12
by Monty Taylor
Moved service stuff into plugin/ |
762 |
ha_delete_table_error_handler.buff); |
763 |
}
|
|
764 |
||
765 |
return error; |
|
766 |
}
|
|
767 |
||
971.1.38
by Monty Taylor
Moved delete table. |
768 |
/**
|
769 |
Initiates table-file and calls appropriate database-creator.
|
|
770 |
||
771 |
@retval
|
|
772 |
0 ok
|
|
773 |
@retval
|
|
774 |
1 error
|
|
1220.1.14
by Brian Aker
Updated fix for create table like. |
775 |
|
1222.1.8
by Brian Aker
Remove check_table() |
776 |
@todo refactor to remove goto
|
971.1.38
by Monty Taylor
Moved delete table. |
777 |
*/
|
1223.4.15
by Brian Aker
Final step to make createTable() use the TableIdentifier. |
778 |
int plugin::StorageEngine::createTable(Session& session, |
779 |
TableIdentifier &identifier, |
|
1160.1.1
by Brian Aker
Refactor SE createTable back to engine class. |
780 |
bool update_create_info, |
1183.1.18
by Brian Aker
Fixed references to doCreateTable() |
781 |
drizzled::message::Table& table_proto, bool proto_used) |
971.1.38
by Monty Taylor
Moved delete table. |
782 |
{
|
783 |
int error= 1; |
|
784 |
Table table; |
|
1223.4.15
by Brian Aker
Final step to make createTable() use the TableIdentifier. |
785 |
TableShare share(identifier.getDBName(), 0, identifier.getTableName(), identifier.getPath()); |
1130.3.16
by Monty Taylor
Moved the last three methods from plugin/storage_engine.cc to be static methods on StorageEngine. |
786 |
message::Table tmp_proto; |
971.1.38
by Monty Taylor
Moved delete table. |
787 |
|
1183.1.18
by Brian Aker
Fixed references to doCreateTable() |
788 |
if (proto_used) |
1095.3.16
by Stewart Smith
Remove requirement of having to re-read table proto on CREATE TABLE. Now we only have to do it if we didn't have a table_proto passed to ha_create_table. |
789 |
{
|
1183.1.18
by Brian Aker
Fixed references to doCreateTable() |
790 |
if (parse_table_proto(session, table_proto, &share)) |
1095.3.16
by Stewart Smith
Remove requirement of having to re-read table proto on CREATE TABLE. Now we only have to do it if we didn't have a table_proto passed to ha_create_table. |
791 |
goto err; |
792 |
}
|
|
793 |
else
|
|
794 |
{
|
|
795 |
if (open_table_def(session, &share)) |
|
796 |
goto err; |
|
797 |
}
|
|
798 |
||
1183.1.29
by Brian Aker
Clean up interface so that Truncate sets the propper engine when |
799 |
if (open_table_from_share(&session, &share, "", 0, (uint32_t) READ_ALL, 0, |
1217.1.1
by Brian Aker
Remove open_table_mode (no longer in use). |
800 |
&table)) |
971.1.38
by Monty Taylor
Moved delete table. |
801 |
goto err; |
802 |
||
803 |
if (update_create_info) |
|
1222.1.7
by Brian Aker
Remove HA_CREATE_INFO from createTable() |
804 |
table.updateCreateInfo(&table_proto); |
971.1.38
by Monty Taylor
Moved delete table. |
805 |
|
1220.1.14
by Brian Aker
Updated fix for create table like. |
806 |
/* Check for legal operations against the Engine using the proto (if used) */
|
807 |
if (proto_used) |
|
808 |
{
|
|
1235.1.11
by Brian Aker
Small cleanups, did in MERGE table only engine flag. |
809 |
if (table_proto.type() == message::Table::TEMPORARY && |
1220.1.14
by Brian Aker
Updated fix for create table like. |
810 |
share.storage_engine->check_flag(HTON_BIT_TEMPORARY_NOT_SUPPORTED) == true) |
811 |
{
|
|
812 |
error= HA_ERR_UNSUPPORTED; |
|
813 |
goto err2; |
|
814 |
}
|
|
1235.1.11
by Brian Aker
Small cleanups, did in MERGE table only engine flag. |
815 |
else if (table_proto.type() != message::Table::TEMPORARY && |
1220.1.14
by Brian Aker
Updated fix for create table like. |
816 |
share.storage_engine->check_flag(HTON_BIT_TEMPORARY_ONLY) == true) |
817 |
{
|
|
818 |
error= HA_ERR_UNSUPPORTED; |
|
819 |
goto err2; |
|
820 |
}
|
|
821 |
}
|
|
822 |
||
1222.1.8
by Brian Aker
Remove check_table() |
823 |
if (! share.storage_engine->is_enabled()) |
824 |
{
|
|
825 |
error= HA_ERR_UNSUPPORTED; |
|
826 |
goto err2; |
|
827 |
}
|
|
828 |
||
1220.1.14
by Brian Aker
Updated fix for create table like. |
829 |
|
1183.1.6
by Brian Aker
Simplify createTable() |
830 |
{
|
831 |
char name_buff[FN_REFLEN]; |
|
832 |
const char *table_name_arg; |
|
833 |
||
1223.4.15
by Brian Aker
Final step to make createTable() use the TableIdentifier. |
834 |
table_name_arg= share.storage_engine->checkLowercaseNames(identifier.getPath(), name_buff); |
1183.1.6
by Brian Aker
Simplify createTable() |
835 |
|
836 |
share.storage_engine->setTransactionReadWrite(session); |
|
837 |
||
1235.1.11
by Brian Aker
Small cleanups, did in MERGE table only engine flag. |
838 |
error= share.storage_engine->doCreateTable(&session, |
1222.1.7
by Brian Aker
Remove HA_CREATE_INFO from createTable() |
839 |
table_name_arg, |
840 |
table, |
|
841 |
table_proto); |
|
1183.1.6
by Brian Aker
Simplify createTable() |
842 |
}
|
843 |
||
1220.1.14
by Brian Aker
Updated fix for create table like. |
844 |
err2: |
971.1.38
by Monty Taylor
Moved delete table. |
845 |
table.closefrm(false); |
1220.1.14
by Brian Aker
Updated fix for create table like. |
846 |
|
971.1.38
by Monty Taylor
Moved delete table. |
847 |
if (error) |
848 |
{
|
|
1095.3.14
by Brian Aker
Moved file based flag up to engine (from handler). checkLowercaseNames() is now a ember of StorageEngine. |
849 |
char name_buff[FN_REFLEN]; |
1223.4.15
by Brian Aker
Final step to make createTable() use the TableIdentifier. |
850 |
sprintf(name_buff,"%s.%s", identifier.getDBName(), identifier.getTableName()); |
971.1.38
by Monty Taylor
Moved delete table. |
851 |
my_error(ER_CANT_CREATE_TABLE, MYF(ME_BELL+ME_WAITTANG), name_buff, error); |
852 |
}
|
|
853 |
err: |
|
1000.1.5
by Brian Aker
More refactoring back to TableShare object. |
854 |
share.free_table_share(); |
971.1.38
by Monty Taylor
Moved delete table. |
855 |
return(error != 0); |
856 |
}
|
|
857 |
||
1253.1.3
by Monty Taylor
MEM_ROOT == memory::Root |
858 |
Cursor *plugin::StorageEngine::getCursor(TableShare &share, memory::Root *alloc) |
1183.1.1
by Brian Aker
Rework interface pieces on SE (sort of... dumb ones...) |
859 |
{
|
860 |
assert(enabled); |
|
1220.1.4
by Brian Aker
Merge Brian (first pass of this cleanup) |
861 |
return create(share, alloc); |
1183.1.1
by Brian Aker
Rework interface pieces on SE (sort of... dumb ones...) |
862 |
}
|
1160.1.1
by Brian Aker
Refactor SE createTable back to engine class. |
863 |
|
1198
by Brian Aker
Merge Brian |
864 |
/**
|
865 |
TODO -> Remove this to force all engines to implement their own file. Solves the "we only looked at dfe" problem.
|
|
866 |
*/
|
|
1183.1.13
by Brian Aker
Fix pass by reference for directory object |
867 |
void plugin::StorageEngine::doGetTableNames(CachedDirectory &directory, string&, set<string>& set_of_names) |
1183.1.5
by Brian Aker
Reworked getTableNames() interface. Way simpler, less mallocs.... |
868 |
{
|
869 |
CachedDirectory::Entries entries= directory.getEntries(); |
|
870 |
||
871 |
for (CachedDirectory::Entries::iterator entry_iter= entries.begin(); |
|
872 |
entry_iter != entries.end(); ++entry_iter) |
|
873 |
{
|
|
874 |
CachedDirectory::Entry *entry= *entry_iter; |
|
875 |
string *filename= &entry->filename; |
|
876 |
||
877 |
assert(filename->size()); |
|
878 |
||
879 |
const char *ext= strchr(filename->c_str(), '.'); |
|
880 |
||
1198
by Brian Aker
Merge Brian |
881 |
if (ext == NULL || my_strcasecmp(system_charset_info, ext, DEFAULT_DEFINITION_FILE_EXT.c_str()) || |
1241.9.12
by Monty Taylor
Trims more out of server_includes.h. |
882 |
(filename->compare(0, strlen(TMP_FILE_PREFIX), TMP_FILE_PREFIX) == 0)) |
1183.1.5
by Brian Aker
Reworked getTableNames() interface. Way simpler, less mallocs.... |
883 |
{ } |
884 |
else
|
|
885 |
{
|
|
886 |
char uname[NAME_LEN + 1]; |
|
887 |
uint32_t file_name_len; |
|
888 |
||
889 |
file_name_len= filename_to_tablename(filename->c_str(), uname, sizeof(uname)); |
|
890 |
// TODO: Remove need for memory copy here
|
|
891 |
uname[file_name_len - sizeof(".dfe") + 1]= '\0'; // Subtract ending, place NULL |
|
1183.1.13
by Brian Aker
Fix pass by reference for directory object |
892 |
set_of_names.insert(uname); |
1183.1.5
by Brian Aker
Reworked getTableNames() interface. Way simpler, less mallocs.... |
893 |
}
|
894 |
}
|
|
895 |
}
|
|
896 |
||
1183.1.14
by Brian Aker
Style cleanup |
897 |
class AddTableName : |
898 |
public unary_function<plugin::StorageEngine *, void> |
|
1183.1.5
by Brian Aker
Reworked getTableNames() interface. Way simpler, less mallocs.... |
899 |
{
|
900 |
string db; |
|
901 |
CachedDirectory& directory; |
|
1183.1.13
by Brian Aker
Fix pass by reference for directory object |
902 |
set<string>& set_of_names; |
1183.1.5
by Brian Aker
Reworked getTableNames() interface. Way simpler, less mallocs.... |
903 |
|
904 |
public: |
|
905 |
||
906 |
AddTableName(CachedDirectory& directory_arg, string& database_name, set<string>& of_names) : |
|
1183.1.13
by Brian Aker
Fix pass by reference for directory object |
907 |
directory(directory_arg), |
908 |
set_of_names(of_names) |
|
1183.1.5
by Brian Aker
Reworked getTableNames() interface. Way simpler, less mallocs.... |
909 |
{
|
910 |
db= database_name; |
|
911 |
}
|
|
912 |
||
913 |
result_type operator() (argument_type engine) |
|
914 |
{
|
|
915 |
engine->doGetTableNames(directory, db, set_of_names); |
|
916 |
}
|
|
917 |
};
|
|
918 |
||
919 |
void plugin::StorageEngine::getTableNames(string& db, set<string>& set_of_names) |
|
920 |
{
|
|
921 |
char tmp_path[FN_REFLEN]; |
|
922 |
||
923 |
build_table_filename(tmp_path, sizeof(tmp_path), db.c_str(), "", false); |
|
924 |
||
1183.1.27
by Brian Aker
Fix issue where there are too many files in data directory. We now only |
925 |
CachedDirectory directory(tmp_path, set_of_table_definition_ext); |
1183.1.5
by Brian Aker
Reworked getTableNames() interface. Way simpler, less mallocs.... |
926 |
|
1183.1.15
by Brian Aker
I_S now provides its own tables via the SE interface |
927 |
if (db.compare("information_schema")) |
1183.1.12
by Brian Aker
Slight cleanup of the interface (no need to keep checking CachedDirectory |
928 |
{
|
1183.1.15
by Brian Aker
I_S now provides its own tables via the SE interface |
929 |
if (directory.fail()) |
930 |
{
|
|
1241.9.57
by Monty Taylor
Oy. Bigger change than I normally like - but this stuff is all intertwined. |
931 |
errno= directory.getError(); |
932 |
if (errno == ENOENT) |
|
1183.1.15
by Brian Aker
I_S now provides its own tables via the SE interface |
933 |
my_error(ER_BAD_DB_ERROR, MYF(ME_BELL+ME_WAITTANG), db.c_str()); |
934 |
else
|
|
1241.9.57
by Monty Taylor
Oy. Bigger change than I normally like - but this stuff is all intertwined. |
935 |
my_error(ER_CANT_READ_DIR, MYF(ME_BELL+ME_WAITTANG), directory.getPath(), errno); |
1183.1.15
by Brian Aker
I_S now provides its own tables via the SE interface |
936 |
return; |
937 |
}
|
|
1183.1.12
by Brian Aker
Slight cleanup of the interface (no need to keep checking CachedDirectory |
938 |
}
|
939 |
||
1183.1.5
by Brian Aker
Reworked getTableNames() interface. Way simpler, less mallocs.... |
940 |
for_each(vector_of_engines.begin(), vector_of_engines.end(), |
941 |
AddTableName(directory, db, set_of_names)); |
|
942 |
}
|
|
943 |
||
1213
by Brian Aker
Fixes startup failures when temporary tables were left behind in a crash. |
944 |
/* This will later be converted to TableIdentifiers */
|
945 |
class DropTables: public unary_function<plugin::StorageEngine *, void> |
|
946 |
{
|
|
947 |
Session &session; |
|
948 |
set<string>& set_of_names; |
|
949 |
||
950 |
public: |
|
951 |
||
952 |
DropTables(Session &session_arg, set<string>& of_names) : |
|
953 |
session(session_arg), |
|
954 |
set_of_names(of_names) |
|
955 |
{ } |
|
956 |
||
957 |
result_type operator() (argument_type engine) |
|
958 |
{
|
|
959 |
||
960 |
for (set<string>::iterator iter= set_of_names.begin(); |
|
961 |
iter != set_of_names.end(); |
|
962 |
iter++) |
|
963 |
{
|
|
964 |
int error= engine->doDropTable(session, *iter); |
|
965 |
||
966 |
// On a return of zero we know we found and deleted the table. So we
|
|
967 |
// remove it from our search.
|
|
968 |
if (! error) |
|
969 |
set_of_names.erase(iter); |
|
970 |
}
|
|
971 |
}
|
|
972 |
};
|
|
973 |
||
974 |
/*
|
|
975 |
This only works for engines which use file based DFE.
|
|
976 |
||
977 |
Note-> Unlike MySQL, we do not, on purpose, delete files that do not match any engines.
|
|
978 |
*/
|
|
979 |
void plugin::StorageEngine::removeLostTemporaryTables(Session &session, const char *directory) |
|
980 |
{
|
|
981 |
CachedDirectory dir(directory, set_of_table_definition_ext); |
|
982 |
set<string> set_of_table_names; |
|
983 |
||
984 |
if (dir.fail()) |
|
985 |
{
|
|
1241.9.57
by Monty Taylor
Oy. Bigger change than I normally like - but this stuff is all intertwined. |
986 |
errno= dir.getError(); |
987 |
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. |
988 |
|
989 |
return; |
|
990 |
}
|
|
991 |
||
992 |
CachedDirectory::Entries files= dir.getEntries(); |
|
993 |
||
994 |
for (CachedDirectory::Entries::iterator fileIter= files.begin(); |
|
995 |
fileIter != files.end(); fileIter++) |
|
996 |
{
|
|
997 |
size_t length; |
|
998 |
string path; |
|
999 |
CachedDirectory::Entry *entry= *fileIter; |
|
1000 |
||
1001 |
/* We remove the file extension. */
|
|
1002 |
length= entry->filename.length(); |
|
1003 |
entry->filename.resize(length - DEFAULT_DEFINITION_FILE_EXT.length()); |
|
1004 |
||
1005 |
path+= directory; |
|
1006 |
path+= FN_LIBCHAR; |
|
1007 |
path+= entry->filename; |
|
1008 |
set_of_table_names.insert(path); |
|
1009 |
}
|
|
1010 |
||
1011 |
for_each(vector_of_engines.begin(), vector_of_engines.end(), |
|
1012 |
DropTables(session, set_of_table_names)); |
|
1013 |
||
1014 |
/*
|
|
1015 |
Now we just clean up anything that might left over.
|
|
1016 |
||
1017 |
We rescan because some of what might have been there should
|
|
1018 |
now be all nice and cleaned up.
|
|
1019 |
*/
|
|
1020 |
set<string> all_exts= set_of_table_definition_ext; |
|
1021 |
||
1022 |
for (vector<plugin::StorageEngine *>::iterator iter= vector_of_engines.begin(); |
|
1023 |
iter != vector_of_engines.end() ; iter++) |
|
1024 |
{
|
|
1025 |
for (const char **ext= (*iter)->bas_ext(); *ext ; ext++) |
|
1026 |
all_exts.insert(*ext); |
|
1027 |
}
|
|
1028 |
||
1029 |
CachedDirectory rescan(directory, all_exts); |
|
1030 |
||
1031 |
files= rescan.getEntries(); |
|
1032 |
for (CachedDirectory::Entries::iterator fileIter= files.begin(); |
|
1033 |
fileIter != files.end(); fileIter++) |
|
1034 |
{
|
|
1035 |
string path; |
|
1036 |
CachedDirectory::Entry *entry= *fileIter; |
|
1037 |
||
1038 |
path+= directory; |
|
1039 |
path+= FN_LIBCHAR; |
|
1040 |
path+= entry->filename; |
|
1041 |
||
1042 |
unlink(path.c_str()); |
|
1043 |
}
|
|
1044 |
}
|
|
1045 |
||
1160.1.1
by Brian Aker
Refactor SE createTable back to engine class. |
1046 |
|
1216.1.1
by Brian Aker
Move print_error up to Engine. |
1047 |
/**
|
1048 |
Print error that we got from Cursor function.
|
|
1049 |
||
1050 |
@note
|
|
1051 |
In case of delete table it's only safe to use the following parts of
|
|
1052 |
the 'table' structure:
|
|
1053 |
- table->s->path
|
|
1054 |
- table->alias
|
|
1055 |
*/
|
|
1056 |
void plugin::StorageEngine::print_error(int error, myf errflag, Table &table) |
|
1057 |
{
|
|
1058 |
print_error(error, errflag, &table); |
|
1059 |
}
|
|
1060 |
||
1061 |
void plugin::StorageEngine::print_error(int error, myf errflag, Table *table) |
|
1062 |
{
|
|
1063 |
int textno= ER_GET_ERRNO; |
|
1064 |
switch (error) { |
|
1065 |
case EACCES: |
|
1066 |
textno=ER_OPEN_AS_READONLY; |
|
1067 |
break; |
|
1068 |
case EAGAIN: |
|
1069 |
textno=ER_FILE_USED; |
|
1070 |
break; |
|
1071 |
case ENOENT: |
|
1072 |
textno=ER_FILE_NOT_FOUND; |
|
1073 |
break; |
|
1074 |
case HA_ERR_KEY_NOT_FOUND: |
|
1075 |
case HA_ERR_NO_ACTIVE_RECORD: |
|
1076 |
case HA_ERR_END_OF_FILE: |
|
1077 |
textno=ER_KEY_NOT_FOUND; |
|
1078 |
break; |
|
1079 |
case HA_ERR_WRONG_MRG_TABLE_DEF: |
|
1080 |
textno=ER_WRONG_MRG_TABLE; |
|
1081 |
break; |
|
1082 |
case HA_ERR_FOUND_DUPP_KEY: |
|
1083 |
{
|
|
1084 |
assert(table); |
|
1085 |
uint32_t key_nr= table->get_dup_key(error); |
|
1086 |
if ((int) key_nr >= 0) |
|
1087 |
{
|
|
1088 |
const char *err_msg= ER(ER_DUP_ENTRY_WITH_KEY_NAME); |
|
1089 |
||
1090 |
if (key_nr == 0 && |
|
1091 |
(table->key_info[0].key_part[0].field->flags & |
|
1092 |
AUTO_INCREMENT_FLAG) |
|
1093 |
&& (current_session)->lex->sql_command == SQLCOM_ALTER_TABLE) |
|
1094 |
{
|
|
1095 |
err_msg= ER(ER_DUP_ENTRY_AUTOINCREMENT_CASE); |
|
1096 |
}
|
|
1097 |
||
1098 |
print_keydup_error(key_nr, err_msg, *table); |
|
1099 |
return; |
|
1100 |
}
|
|
1101 |
textno=ER_DUP_KEY; |
|
1102 |
break; |
|
1103 |
}
|
|
1104 |
case HA_ERR_FOREIGN_DUPLICATE_KEY: |
|
1105 |
{
|
|
1106 |
assert(table); |
|
1107 |
uint32_t key_nr= table->get_dup_key(error); |
|
1108 |
if ((int) key_nr >= 0) |
|
1109 |
{
|
|
1110 |
uint32_t max_length; |
|
1111 |
||
1112 |
/* Write the key in the error message */
|
|
1113 |
char key[MAX_KEY_LENGTH]; |
|
1114 |
String str(key,sizeof(key),system_charset_info); |
|
1115 |
||
1116 |
/* Table is opened and defined at this point */
|
|
1117 |
key_unpack(&str,table,(uint32_t) key_nr); |
|
1118 |
max_length= (DRIZZLE_ERRMSG_SIZE- |
|
1119 |
(uint32_t) strlen(ER(ER_FOREIGN_DUPLICATE_KEY))); |
|
1120 |
if (str.length() >= max_length) |
|
1121 |
{
|
|
1122 |
str.length(max_length-4); |
|
1123 |
str.append(STRING_WITH_LEN("...")); |
|
1124 |
}
|
|
1125 |
my_error(ER_FOREIGN_DUPLICATE_KEY, MYF(0), table->s->table_name.str, |
|
1126 |
str.c_ptr(), key_nr+1); |
|
1127 |
return; |
|
1128 |
}
|
|
1129 |
textno= ER_DUP_KEY; |
|
1130 |
break; |
|
1131 |
}
|
|
1132 |
case HA_ERR_FOUND_DUPP_UNIQUE: |
|
1133 |
textno=ER_DUP_UNIQUE; |
|
1134 |
break; |
|
1135 |
case HA_ERR_RECORD_CHANGED: |
|
1136 |
textno=ER_CHECKREAD; |
|
1137 |
break; |
|
1138 |
case HA_ERR_CRASHED: |
|
1139 |
textno=ER_NOT_KEYFILE; |
|
1140 |
break; |
|
1141 |
case HA_ERR_WRONG_IN_RECORD: |
|
1142 |
textno= ER_CRASHED_ON_USAGE; |
|
1143 |
break; |
|
1144 |
case HA_ERR_CRASHED_ON_USAGE: |
|
1145 |
textno=ER_CRASHED_ON_USAGE; |
|
1146 |
break; |
|
1147 |
case HA_ERR_NOT_A_TABLE: |
|
1148 |
textno= error; |
|
1149 |
break; |
|
1150 |
case HA_ERR_CRASHED_ON_REPAIR: |
|
1151 |
textno=ER_CRASHED_ON_REPAIR; |
|
1152 |
break; |
|
1153 |
case HA_ERR_OUT_OF_MEM: |
|
1154 |
textno=ER_OUT_OF_RESOURCES; |
|
1155 |
break; |
|
1156 |
case HA_ERR_WRONG_COMMAND: |
|
1157 |
textno=ER_ILLEGAL_HA; |
|
1158 |
break; |
|
1159 |
case HA_ERR_OLD_FILE: |
|
1160 |
textno=ER_OLD_KEYFILE; |
|
1161 |
break; |
|
1162 |
case HA_ERR_UNSUPPORTED: |
|
1163 |
textno=ER_UNSUPPORTED_EXTENSION; |
|
1164 |
break; |
|
1165 |
case HA_ERR_RECORD_FILE_FULL: |
|
1166 |
case HA_ERR_INDEX_FILE_FULL: |
|
1167 |
textno=ER_RECORD_FILE_FULL; |
|
1168 |
break; |
|
1169 |
case HA_ERR_LOCK_WAIT_TIMEOUT: |
|
1170 |
textno=ER_LOCK_WAIT_TIMEOUT; |
|
1171 |
break; |
|
1172 |
case HA_ERR_LOCK_TABLE_FULL: |
|
1173 |
textno=ER_LOCK_TABLE_FULL; |
|
1174 |
break; |
|
1175 |
case HA_ERR_LOCK_DEADLOCK: |
|
1176 |
textno=ER_LOCK_DEADLOCK; |
|
1177 |
break; |
|
1178 |
case HA_ERR_READ_ONLY_TRANSACTION: |
|
1179 |
textno=ER_READ_ONLY_TRANSACTION; |
|
1180 |
break; |
|
1181 |
case HA_ERR_CANNOT_ADD_FOREIGN: |
|
1182 |
textno=ER_CANNOT_ADD_FOREIGN; |
|
1183 |
break; |
|
1184 |
case HA_ERR_ROW_IS_REFERENCED: |
|
1185 |
{
|
|
1186 |
String str; |
|
1187 |
get_error_message(error, &str); |
|
1188 |
my_error(ER_ROW_IS_REFERENCED_2, MYF(0), str.c_ptr_safe()); |
|
1189 |
return; |
|
1190 |
}
|
|
1191 |
case HA_ERR_NO_REFERENCED_ROW: |
|
1192 |
{
|
|
1193 |
String str; |
|
1194 |
get_error_message(error, &str); |
|
1195 |
my_error(ER_NO_REFERENCED_ROW_2, MYF(0), str.c_ptr_safe()); |
|
1196 |
return; |
|
1197 |
}
|
|
1198 |
case HA_ERR_TABLE_DEF_CHANGED: |
|
1199 |
textno=ER_TABLE_DEF_CHANGED; |
|
1200 |
break; |
|
1201 |
case HA_ERR_NO_SUCH_TABLE: |
|
1202 |
assert(table); |
|
1203 |
my_error(ER_NO_SUCH_TABLE, MYF(0), table->s->db.str, |
|
1204 |
table->s->table_name.str); |
|
1205 |
return; |
|
1206 |
case HA_ERR_RBR_LOGGING_FAILED: |
|
1207 |
textno= ER_BINLOG_ROW_LOGGING_FAILED; |
|
1208 |
break; |
|
1209 |
case HA_ERR_DROP_INDEX_FK: |
|
1210 |
{
|
|
1211 |
assert(table); |
|
1212 |
const char *ptr= "???"; |
|
1213 |
uint32_t key_nr= table->get_dup_key(error); |
|
1214 |
if ((int) key_nr >= 0) |
|
1215 |
ptr= table->key_info[key_nr].name; |
|
1216 |
my_error(ER_DROP_INDEX_FK, MYF(0), ptr); |
|
1217 |
return; |
|
1218 |
}
|
|
1219 |
case HA_ERR_TABLE_NEEDS_UPGRADE: |
|
1220 |
textno=ER_TABLE_NEEDS_UPGRADE; |
|
1221 |
break; |
|
1222 |
case HA_ERR_TABLE_READONLY: |
|
1223 |
textno= ER_OPEN_AS_READONLY; |
|
1224 |
break; |
|
1225 |
case HA_ERR_AUTOINC_READ_FAILED: |
|
1226 |
textno= ER_AUTOINC_READ_FAILED; |
|
1227 |
break; |
|
1228 |
case HA_ERR_AUTOINC_ERANGE: |
|
1229 |
textno= ER_WARN_DATA_OUT_OF_RANGE; |
|
1230 |
break; |
|
1231 |
case HA_ERR_LOCK_OR_ACTIVE_TRANSACTION: |
|
1232 |
my_message(ER_LOCK_OR_ACTIVE_TRANSACTION, |
|
1233 |
ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0)); |
|
1234 |
return; |
|
1235 |
default: |
|
1236 |
{
|
|
1237 |
/*
|
|
1238 |
The error was "unknown" to this function.
|
|
1239 |
Ask Cursor if it has got a message for this error
|
|
1240 |
*/
|
|
1241 |
bool temporary= false; |
|
1242 |
String str; |
|
1243 |
temporary= get_error_message(error, &str); |
|
1244 |
if (!str.is_empty()) |
|
1245 |
{
|
|
1246 |
const char* engine_name= getName().c_str(); |
|
1247 |
if (temporary) |
|
1248 |
my_error(ER_GET_TEMPORARY_ERRMSG, MYF(0), error, str.ptr(), |
|
1249 |
engine_name); |
|
1250 |
else
|
|
1251 |
my_error(ER_GET_ERRMSG, MYF(0), error, str.ptr(), engine_name); |
|
1252 |
}
|
|
1253 |
else
|
|
1254 |
{
|
|
1255 |
my_error(ER_GET_ERRNO,errflag,error); |
|
1256 |
}
|
|
1257 |
return; |
|
1258 |
}
|
|
1259 |
}
|
|
1260 |
my_error(textno, errflag, table->s->table_name.str, error); |
|
1261 |
}
|
|
1262 |
||
1263 |
||
1264 |
/**
|
|
1265 |
Return an error message specific to this Cursor.
|
|
1266 |
||
1267 |
@param error error code previously returned by Cursor
|
|
1268 |
@param buf pointer to String where to add error message
|
|
1269 |
||
1270 |
@return
|
|
1271 |
Returns true if this is a temporary error
|
|
1272 |
*/
|
|
1273 |
bool plugin::StorageEngine::get_error_message(int , String* ) |
|
1274 |
{
|
|
1275 |
return false; |
|
1276 |
}
|
|
1277 |
||
1278 |
||
1279 |
void plugin::StorageEngine::print_keydup_error(uint32_t key_nr, const char *msg, Table &table) |
|
1280 |
{
|
|
1281 |
/* Write the duplicated key in the error message */
|
|
1282 |
char key[MAX_KEY_LENGTH]; |
|
1283 |
String str(key,sizeof(key),system_charset_info); |
|
1284 |
||
1285 |
if (key_nr == MAX_KEY) |
|
1286 |
{
|
|
1287 |
/* Key is unknown */
|
|
1288 |
str.copy("", 0, system_charset_info); |
|
1289 |
my_printf_error(ER_DUP_ENTRY, msg, MYF(0), str.c_ptr(), "*UNKNOWN*"); |
|
1290 |
}
|
|
1291 |
else
|
|
1292 |
{
|
|
1293 |
/* Table is opened and defined at this point */
|
|
1294 |
key_unpack(&str, &table, (uint32_t) key_nr); |
|
1295 |
uint32_t max_length=DRIZZLE_ERRMSG_SIZE-(uint32_t) strlen(msg); |
|
1296 |
if (str.length() >= max_length) |
|
1297 |
{
|
|
1298 |
str.length(max_length-4); |
|
1299 |
str.append(STRING_WITH_LEN("...")); |
|
1300 |
}
|
|
1301 |
my_printf_error(ER_DUP_ENTRY, msg, |
|
1302 |
MYF(0), str.c_ptr(), table.key_info[key_nr].name); |
|
1303 |
}
|
|
1304 |
}
|
|
1305 |
||
1237.6.12
by Brian Aker
Adding patch for engine methods for definition files. |
1306 |
|
1307 |
int plugin::StorageEngine::deleteDefinitionFromPath(TableIdentifier &identifier) |
|
1308 |
{
|
|
1309 |
string path(identifier.getPath()); |
|
1310 |
||
1311 |
path.append(DEFAULT_DEFINITION_FILE_EXT); |
|
1312 |
||
1313 |
return my_delete(path.c_str(), MYF(0)); |
|
1314 |
}
|
|
1315 |
||
1316 |
int plugin::StorageEngine::renameDefinitionFromPath(TableIdentifier &dest, TableIdentifier &src) |
|
1317 |
{
|
|
1318 |
string src_path(src.getPath()); |
|
1319 |
string dest_path(dest.getPath()); |
|
1320 |
||
1321 |
src_path.append(DEFAULT_DEFINITION_FILE_EXT); |
|
1322 |
dest_path.append(DEFAULT_DEFINITION_FILE_EXT); |
|
1323 |
||
1324 |
return my_rename(src_path.c_str(), dest_path.c_str(), MYF(MY_WME)); |
|
1325 |
}
|
|
1326 |
||
1327 |
int plugin::StorageEngine::writeDefinitionFromPath(TableIdentifier &identifier, message::Table &table_proto) |
|
1328 |
{
|
|
1329 |
string file_name(identifier.getPath()); |
|
1330 |
||
1331 |
file_name.append(DEFAULT_DEFINITION_FILE_EXT); |
|
1332 |
||
1333 |
int fd= open(file_name.c_str(), O_RDWR|O_CREAT|O_TRUNC, my_umask); |
|
1334 |
||
1335 |
if (fd == -1) |
|
1336 |
return errno; |
|
1337 |
||
1338 |
google::protobuf::io::ZeroCopyOutputStream* output= |
|
1339 |
new google::protobuf::io::FileOutputStream(fd); |
|
1340 |
||
1341 |
if (table_proto.SerializeToZeroCopyStream(output) == false) |
|
1342 |
{
|
|
1343 |
delete output; |
|
1344 |
close(fd); |
|
1345 |
return errno; |
|
1346 |
}
|
|
1347 |
||
1348 |
delete output; |
|
1349 |
close(fd); |
|
1350 |
return 0; |
|
1351 |
}
|
|
1352 |
||
1353 |
||
1160.1.1
by Brian Aker
Refactor SE createTable back to engine class. |
1354 |
} /* namespace drizzled */ |