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