~drizzle-trunk/drizzle/development

1283.3.1 by Stewart Smith
Skeleton embedded_innodb plugin. Does nothing.
1
/*
2
  Copyright (C) 2010 Stewart Smith
3
4
  This program is free software; you can redistribute it and/or
5
  modify it under the terms of the GNU General Public License
6
  as published by the Free Software Foundation; either version 2
7
  of the License, or (at your option) any later version.
8
9
  This program is distributed in the hope that it will be useful,
10
  but WITHOUT ANY WARRANTY; without even the implied warranty of
11
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
  GNU General Public License for more details.
13
14
  You should have received a copy of the GNU General Public License
15
  along with this program; if not, write to the Free Software
16
  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
17
*/
18
1283.37.4 by Stewart Smith
fix embedded_innodb auto_increment for negative values (just strange really).
19
/* innobase_get_int_col_max_value() comes from ha_innodb.cc which is under
20
   the following license and Copyright */
21
22
/*****************************************************************************
23
24
Copyright (c) 2000, 2009, MySQL AB & Innobase Oy. All Rights Reserved.
25
Copyright (c) 2008, 2009 Google Inc.
26
27
Portions of this file contain modifications contributed and copyrighted by
1283.60.5 by Stewart Smith
add BLOB support to embedded_innodb along with a simple test.
28
staticGoogle, Inc. Those modifications are gratefully acknowledged and are described
1283.37.4 by Stewart Smith
fix embedded_innodb auto_increment for negative values (just strange really).
29
briefly in the InnoDB documentation. The contributions by Google are
30
incorporated with their permission, and subject to the conditions contained in
31
the file COPYING.Google.
32
33
This program is free software; you can redistribute it and/or modify it under
34
the terms of the GNU General Public License as published by the Free Software
35
Foundation; version 2 of the License.
36
37
This program is distributed in the hope that it will be useful, but WITHOUT
38
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
39
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
40
41
You should have received a copy of the GNU General Public License along with
42
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
43
Place, Suite 330, Boston, MA 02111-1307 USA
44
45
*****************************************************************************/
46
/***********************************************************************
47
48
Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved.
49
Copyright (c) 2009, Percona Inc.
50
51
Portions of this file contain modifications contributed and copyrighted
52
by Percona Inc.. Those modifications are
53
gratefully acknowledged and are described briefly in the InnoDB
54
documentation. The contributions by Percona Inc. are incorporated with
55
their permission, and subject to the conditions contained in the file
56
COPYING.Percona.
57
58
This program is free software; you can redistribute it and/or modify it
59
under the terms of the GNU General Public License as published by the
60
Free Software Foundation; version 2 of the License.
61
62
This program is distributed in the hope that it will be useful, but
63
WITHOUT ANY WARRANTY; without even the implied warranty of
64
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
65
Public License for more details.
66
67
You should have received a copy of the GNU General Public License along
68
with this program; if not, write to the Free Software Foundation, Inc.,
69
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
70
71
***********************************************************************/
72
73
1283.3.1 by Stewart Smith
Skeleton embedded_innodb plugin. Does nothing.
74
#include "config.h"
75
#include <drizzled/table.h>
76
#include <drizzled/error.h>
77
#include "drizzled/internal/my_pthread.h"
1283.3.80 by Stewart Smith
add basic transactional support to Embedded InnoDB engine.
78
#include <drizzled/plugin/transactional_storage_engine.h>
1283.3.1 by Stewart Smith
Skeleton embedded_innodb plugin. Does nothing.
79
80
#include <fcntl.h>
81
82
#include <string>
83
#include <map>
84
#include <fstream>
85
#include <drizzled/message/table.pb.h>
86
#include "drizzled/internal/m_string.h"
87
88
#include "drizzled/global_charset_info.h"
89
1283.3.5 by Stewart Smith
add LIBINNODB_VERSION() function
90
#include "libinnodb_version_func.h"
1283.10.2 by Stewart Smith
simple LIBINNODB_DATADICT_DUMP() function to dump contents of libinnodb data dict as string.
91
#include "libinnodb_datadict_dump_func.h"
1283.28.3 by Stewart Smith
simple table function for Embedded InnoDB Configuration. Currently returns nothing.
92
#include "config_table_function.h"
1283.28.9 by Stewart Smith
basic DATA_DICTIONARY.INNODB_STATUS table_function plugin. This gets the InnoDB status and lets the user query it.
93
#include "status_table_function.h"
1283.3.1 by Stewart Smith
Skeleton embedded_innodb plugin. Does nothing.
94
1283.3.9 by Stewart Smith
call basic embedded innodb init functions (ib_init() and ib_startup()). Also shutdown functions.
95
#include "embedded_innodb-1.0/innodb.h"
96
1283.3.27 by Stewart Smith
basic code to insert a integer
97
#include "embedded_innodb_engine.h"
98
99
#include <drizzled/field.h>
1283.35.40 by Stewart Smith
update timestamp column for ON UPDATE NOW() in embedded_innodb
100
#include "drizzled/field/timestamp.h" // needed for UPDATE NOW()
1283.60.5 by Stewart Smith
add BLOB support to embedded_innodb along with a simple test.
101
#include "drizzled/field/blob.h"
1283.3.80 by Stewart Smith
add basic transactional support to Embedded InnoDB engine.
102
#include <drizzled/session.h>
1283.3.27 by Stewart Smith
basic code to insert a integer
103
1283.3.1 by Stewart Smith
Skeleton embedded_innodb plugin. Does nothing.
104
using namespace std;
105
using namespace google;
106
using namespace drizzled;
107
1283.60.10 by Stewart Smith
the memory management for BLOBS is completely insane. For certain types of index lookups we *must* do a copy and clear it *only* in ::reset() or ::extra(). This patch fixes up any valgrind warnings/assertions for embedded_innodb executing type_blob test.
108
int read_row_from_innodb(unsigned char* buf, ib_crsr_t cursor, ib_tpl_t tuple, Table* table, bool has_hidden_primary_key, uint64_t *hidden_pkey, drizzled::memory::Root **blobroot= NULL);
1283.28.29 by Stewart Smith
implement rnd_pos for embedded_innodb. Also fix up fill_ib_search_tpl_froM_drizzle_key for primary keys that aren't all at the start of the table. It turns out that the clustered index search tuple numbers columns just in the clustered index, not anything to do with column numbers in the table.
109
static void fill_ib_search_tpl_from_drizzle_key(ib_tpl_t search_tuple,
1475.2.9 by Stewart Smith
fix many compile failures that people introduced in embedded_innodb because it's not built by default.. i.e. plugin=disabled is EPIC FAIL
110
                                                const drizzled::KeyInfo *key_info,
1283.28.29 by Stewart Smith
implement rnd_pos for embedded_innodb. Also fix up fill_ib_search_tpl_froM_drizzle_key for primary keys that aren't all at the start of the table. It turns out that the clustered index search tuple numbers columns just in the clustered index, not anything to do with column numbers in the table.
111
                                                const unsigned char *key_ptr,
112
                                                uint32_t key_len);
1283.43.5 by Stewart Smith
fix up store_key_value_from_innodb() prototype after switch from KEY to KeyInfo
113
static void store_key_value_from_innodb(KeyInfo *key_info, unsigned char* ref, int ref_len, const unsigned char *record);
1283.3.43 by Stewart Smith
refactor out rnd_next() into read_row_from_innodb() and a call to ib_cursor_next(). This allows us to make the row reading code generic for index scans/lookups.
114
1283.4.1 by Stewart Smith
currently storage engine plugins definition file extension *must* be 3 characters.
115
#define EMBEDDED_INNODB_EXT ".EID"
1283.3.1 by Stewart Smith
Skeleton embedded_innodb plugin. Does nothing.
116
1283.17.13 by Stewart Smith
define should be a const char*
117
const char INNODB_TABLE_DEFINITIONS_TABLE[]= "data_dictionary/innodb_table_definitions";
1283.3.85 by Stewart Smith
take a savepoint at the start of each embedded innodb statement and roll back to that savepoint on error.
118
const string statement_savepoint_name("STATEMENT");
119
1283.17.12 by Stewart Smith
use define to set the name of the innodb_table_definitions table instead of repeating it 5 times through the code
120
1283.3.1 by Stewart Smith
Skeleton embedded_innodb plugin. Does nothing.
121
static const char *EmbeddedInnoDBCursor_exts[] = {
122
  NULL
123
};
124
1283.3.80 by Stewart Smith
add basic transactional support to Embedded InnoDB engine.
125
class EmbeddedInnoDBEngine : public drizzled::plugin::TransactionalStorageEngine
1283.3.1 by Stewart Smith
Skeleton embedded_innodb plugin. Does nothing.
126
{
127
public:
128
  EmbeddedInnoDBEngine(const string &name_arg)
1283.3.80 by Stewart Smith
add basic transactional support to Embedded InnoDB engine.
129
   : drizzled::plugin::TransactionalStorageEngine(name_arg,
130
                                                  HTON_NULL_IN_KEY |
131
                                                  HTON_CAN_INDEX_BLOBS |
132
                                                  HTON_AUTO_PART_KEY |
1283.39.11 by Stewart Smith
fix write_row_to_innodb_tuple for proper WriteSet behaviour. oh my the API is bonghits.
133
                                                  HTON_PARTIAL_COLUMN_READ |
1283.26.13 by Stewart Smith
merge trunk
134
                                                  HTON_HAS_DOES_TRANSACTIONS)
1283.3.1 by Stewart Smith
Skeleton embedded_innodb plugin. Does nothing.
135
  {
136
    table_definition_ext= EMBEDDED_INNODB_EXT;
137
  }
138
1283.23.10 by Stewart Smith
merge libinnodb init/de-init with trunk
139
  ~EmbeddedInnoDBEngine();
140
1283.3.1 by Stewart Smith
Skeleton embedded_innodb plugin. Does nothing.
141
  virtual Cursor *create(TableShare &table,
142
                         drizzled::memory::Root *mem_root)
143
  {
144
    return new (mem_root) EmbeddedInnoDBCursor(*this, table);
145
  }
146
147
  const char **bas_ext() const {
148
    return EmbeddedInnoDBCursor_exts;
149
  }
150
1283.4.19 by Stewart Smith
merge fixes for embedded_innodb: changed prototypes for engine
151
  int doCreateTable(Session&,
1283.11.19 by Stewart Smith
fix up create table for new bits of storage engine API r.e. TableIdentifier
152
                    Table& table_arg,
153
                    drizzled::TableIdentifier &identifier,
154
                    drizzled::message::Table& proto);
1283.3.1 by Stewart Smith
Skeleton embedded_innodb plugin. Does nothing.
155
1283.4.13 by Stewart Smith
update embedded_innodb for TableIdentifier
156
  int doDropTable(Session&, TableIdentifier &identifier);
1283.3.1 by Stewart Smith
Skeleton embedded_innodb plugin. Does nothing.
157
1283.4.16 by Stewart Smith
fix up plugin initialisation and add doRenameTable empty function as it's now pure virtual
158
  int doRenameTable(drizzled::Session&,
159
                    drizzled::TableIdentifier&,
160
                    drizzled::TableIdentifier&);
161
1283.3.1 by Stewart Smith
Skeleton embedded_innodb plugin. Does nothing.
162
  int doGetTableDefinition(Session& session,
1283.4.13 by Stewart Smith
update embedded_innodb for TableIdentifier
163
                           TableIdentifier &identifier,
164
                           drizzled::message::Table &table_proto);
1283.3.1 by Stewart Smith
Skeleton embedded_innodb plugin. Does nothing.
165
1283.11.19 by Stewart Smith
fix up create table for new bits of storage engine API r.e. TableIdentifier
166
  bool doDoesTableExist(Session&, TableIdentifier &identifier);
1283.3.1 by Stewart Smith
Skeleton embedded_innodb plugin. Does nothing.
167
1283.16.32 by Stewart Smith
implement both doGetTableNames and doGetTableIdentifiers through a common function
168
private:
169
  void getTableNamesInSchemaFromInnoDB(drizzled::SchemaIdentifier &schema,
170
                                       drizzled::plugin::TableNameList *set_of_names,
171
                                       drizzled::TableIdentifiers *identifiers);
172
173
public:
1283.3.1 by Stewart Smith
Skeleton embedded_innodb plugin. Does nothing.
174
  void doGetTableNames(drizzled::CachedDirectory &,
1283.16.30 by Stewart Smith
merge trunk
175
                       drizzled::SchemaIdentifier &schema,
1283.16.28 by Stewart Smith
merge trunk, fix up table name in doGetTableDefinition due to bug lp:552178
176
                       drizzled::plugin::TableNameList &set_of_names);
1283.3.1 by Stewart Smith
Skeleton embedded_innodb plugin. Does nothing.
177
1283.4.21 by Stewart Smith
add two new empty functions that are required for a skeleton engine: get_auto_increment and doGetTableIdentifiers
178
  void doGetTableIdentifiers(drizzled::CachedDirectory &,
1283.16.32 by Stewart Smith
implement both doGetTableNames and doGetTableIdentifiers through a common function
179
                             drizzled::SchemaIdentifier &schema,
180
                             drizzled::TableIdentifiers &identifiers);
1283.4.21 by Stewart Smith
add two new empty functions that are required for a skeleton engine: get_auto_increment and doGetTableIdentifiers
181
1283.3.1 by Stewart Smith
Skeleton embedded_innodb plugin. Does nothing.
182
  /* The following defines can be increased if necessary */
183
  uint32_t max_supported_keys()          const { return 64; }
184
  uint32_t max_supported_key_length()    const { return 1000; }
185
  uint32_t max_supported_key_part_length() const { return 1000; }
186
187
  uint32_t index_flags(enum  ha_key_alg) const
188
  {
189
    return (HA_READ_NEXT |
190
            HA_READ_PREV |
191
            HA_READ_RANGE |
192
            HA_READ_ORDER |
193
            HA_KEYREAD_ONLY);
194
  }
1283.3.80 by Stewart Smith
add basic transactional support to Embedded InnoDB engine.
195
  virtual int doStartTransaction(Session *session,
196
                                 start_transaction_option_t options);
197
  virtual void doStartStatement(Session *session);
198
  virtual void doEndStatement(Session *session);
199
200
  virtual int doSetSavepoint(Session* session,
201
                                 drizzled::NamedSavepoint &savepoint);
202
  virtual int doRollbackToSavepoint(Session* session,
203
                                     drizzled::NamedSavepoint &savepoint);
204
  virtual int doReleaseSavepoint(Session* session,
205
                                     drizzled::NamedSavepoint &savepoint);
206
  virtual int doCommit(Session* session, bool all);
207
  virtual int doRollback(Session* session, bool all);
208
209
  typedef std::map<std::string, EmbeddedInnoDBTableShare*> EmbeddedInnoDBMap;
210
  EmbeddedInnoDBMap embedded_innodb_open_tables;
211
  EmbeddedInnoDBTableShare *findOpenTable(const std::string table_name);
212
  void addOpenTable(const std::string &table_name, EmbeddedInnoDBTableShare *);
213
  void deleteOpenTable(const std::string &table_name);
1283.3.1 by Stewart Smith
Skeleton embedded_innodb plugin. Does nothing.
214
1283.36.13 by Stewart Smith
basic auto_increment implementation for embedded_innodb. On startup, fetch the maximum value for the auto_increment column (or what's in the table message as the auto_increment value). Use an atomic variable in the embedded-innodb table share to keep track of the auto_increment_value. We can then use atomic ops to get an autoinc value (or several) as well as update it in the event of inserting a larger number. Currently there's a bug (well, difference in behaviour) around inserting -1 into an auto-inc field where the table already has a value 'higher' than that and then asking for another auto-inc value. Check the auto_increment test case failure for it. This will be fixed in a later commit.
215
  uint64_t getInitialAutoIncrementValue(EmbeddedInnoDBCursor *cursor);
1283.35.97 by Stewart Smith
support tables without an explicit primary key in embedded_innodb by creating a hidden auto_increment primary key. We also have to support tables without an explicit primary key but with an auto increment, so we have our own hidden one. yes, it hurts.
216
  uint64_t getHiddenPrimaryKeyInitialAutoIncrementValue(EmbeddedInnoDBCursor *cursor);
217
1283.3.1 by Stewart Smith
Skeleton embedded_innodb plugin. Does nothing.
218
};
219
1283.3.80 by Stewart Smith
add basic transactional support to Embedded InnoDB engine.
220
static drizzled::plugin::StorageEngine *embedded_innodb_engine= NULL;
221
222
223
static ib_trx_t* get_trx(Session* session)
224
{
225
  return (ib_trx_t*) session->getEngineData(embedded_innodb_engine);
226
}
227
228
int EmbeddedInnoDBEngine::doStartTransaction(Session *session,
229
                                             start_transaction_option_t options)
230
{
231
  ib_trx_t *transaction;
232
233
  (void)options;
234
235
  transaction= get_trx(session);
236
  *transaction= ib_trx_begin(IB_TRX_REPEATABLE_READ);
237
238
  return 0;
239
}
240
241
void EmbeddedInnoDBEngine::doStartStatement(Session *session)
242
{
243
  if(*get_trx(session) == NULL)
244
    doStartTransaction(session, START_TRANS_NO_OPTIONS);
1283.3.85 by Stewart Smith
take a savepoint at the start of each embedded innodb statement and roll back to that savepoint on error.
245
246
  ib_savepoint_take(*get_trx(session), statement_savepoint_name.c_str(),
247
                    statement_savepoint_name.length());
1283.3.80 by Stewart Smith
add basic transactional support to Embedded InnoDB engine.
248
}
249
250
void EmbeddedInnoDBEngine::doEndStatement(Session *session)
251
{
252
  doCommit(session, false);
253
}
254
255
int EmbeddedInnoDBEngine::doSetSavepoint(Session* session,
256
                                         drizzled::NamedSavepoint &savepoint)
257
{
1283.3.86 by Stewart Smith
basic savepoints for embedded innodb
258
  ib_trx_t *transaction= get_trx(session);
259
  ib_savepoint_take(*transaction, savepoint.getName().c_str(),
260
                    savepoint.getName().length());
1283.3.80 by Stewart Smith
add basic transactional support to Embedded InnoDB engine.
261
  return 0;
262
}
263
264
int EmbeddedInnoDBEngine::doRollbackToSavepoint(Session* session,
265
                                                drizzled::NamedSavepoint &savepoint)
266
{
1283.3.86 by Stewart Smith
basic savepoints for embedded innodb
267
  ib_trx_t *transaction= get_trx(session);
268
  ib_err_t err;
269
270
  err= ib_savepoint_rollback(*transaction, savepoint.getName().c_str(),
271
                             savepoint.getName().length());
272
  if (err != DB_SUCCESS)
273
    return -1;
1283.3.80 by Stewart Smith
add basic transactional support to Embedded InnoDB engine.
274
275
  return 0;
276
}
277
278
int EmbeddedInnoDBEngine::doReleaseSavepoint(Session* session,
279
                                             drizzled::NamedSavepoint &savepoint)
280
{
1283.3.86 by Stewart Smith
basic savepoints for embedded innodb
281
  ib_trx_t *transaction= get_trx(session);
282
  ib_err_t err;
283
284
  err= ib_savepoint_release(*transaction, savepoint.getName().c_str(),
285
                            savepoint.getName().length());
286
  if (err != DB_SUCCESS)
287
    return -1;
1283.3.80 by Stewart Smith
add basic transactional support to Embedded InnoDB engine.
288
289
  return 0;
290
}
291
292
int EmbeddedInnoDBEngine::doCommit(Session* session, bool all)
293
{
294
  ib_err_t err;
295
  ib_trx_t *transaction= get_trx(session);
296
297
  if (all || (!session_test_options(session, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)))
298
  {
299
    err= ib_trx_commit(*transaction);
300
301
    if (err != DB_SUCCESS)
302
      return -1;
303
304
    *transaction= NULL;
305
  }
306
307
  return 0;
308
}
309
310
int EmbeddedInnoDBEngine::doRollback(Session* session, bool all)
311
{
1283.3.83 by Stewart Smith
implement basic ROLLBACK (with test) for embedded innodb
312
  ib_err_t err;
313
  ib_trx_t *transaction= get_trx(session);
314
315
  if (all || !session_test_options(session, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))
316
  {
317
    err= ib_trx_rollback(*transaction);
318
319
    if (err != DB_SUCCESS)
320
      return -1;
321
322
    *transaction= NULL;
323
  }
1283.3.85 by Stewart Smith
take a savepoint at the start of each embedded innodb statement and roll back to that savepoint on error.
324
  else
325
  {
326
    err= ib_savepoint_rollback(*transaction, statement_savepoint_name.c_str(),
327
                               statement_savepoint_name.length());
328
    if (err != DB_SUCCESS)
329
      return -1;
330
  }
1283.3.80 by Stewart Smith
add basic transactional support to Embedded InnoDB engine.
331
332
  return 0;
333
}
334
335
EmbeddedInnoDBTableShare *EmbeddedInnoDBEngine::findOpenTable(const string table_name)
336
{
337
  EmbeddedInnoDBMap::iterator find_iter=
338
    embedded_innodb_open_tables.find(table_name);
339
340
  if (find_iter != embedded_innodb_open_tables.end())
341
    return (*find_iter).second;
342
  else
343
    return NULL;
344
}
345
346
void EmbeddedInnoDBEngine::addOpenTable(const string &table_name, EmbeddedInnoDBTableShare *share)
347
{
348
  embedded_innodb_open_tables[table_name]= share;
349
}
350
351
void EmbeddedInnoDBEngine::deleteOpenTable(const string &table_name)
352
{
353
  embedded_innodb_open_tables.erase(table_name);
354
}
355
356
static pthread_mutex_t embedded_innodb_mutex= PTHREAD_MUTEX_INITIALIZER;
357
1283.35.97 by Stewart Smith
support tables without an explicit primary key in embedded_innodb by creating a hidden auto_increment primary key. We also have to support tables without an explicit primary key but with an auto increment, so we have our own hidden one. yes, it hurts.
358
uint64_t EmbeddedInnoDBCursor::getHiddenPrimaryKeyInitialAutoIncrementValue()
359
{
360
  uint64_t nr;
361
  ib_err_t err;
362
  ib_trx_t transaction= *get_trx(ha_session());
363
  ib_cursor_attach_trx(cursor, transaction);
364
  tuple= ib_clust_read_tuple_create(cursor);
365
  err= ib_cursor_last(cursor);
366
  assert(err == DB_SUCCESS || err == DB_END_OF_INDEX); // Probably a FIXME
367
  err= ib_cursor_read_row(cursor, tuple);
368
  if (err == DB_RECORD_NOT_FOUND)
369
    nr= 1;
370
  else
371
  {
372
    assert (err == DB_SUCCESS);
1532.1.15 by Brian Aker
Partial encapsulation of TableShare from Table.
373
    err= ib_tuple_read_u64(tuple, table->getShare()->fields, &nr);
1283.35.97 by Stewart Smith
support tables without an explicit primary key in embedded_innodb by creating a hidden auto_increment primary key. We also have to support tables without an explicit primary key but with an auto increment, so we have our own hidden one. yes, it hurts.
374
    nr++;
375
  }
376
  ib_tuple_delete(tuple);
377
  err= ib_cursor_reset(cursor);
378
  assert(err == DB_SUCCESS);
379
  return nr;
380
}
381
1283.36.13 by Stewart Smith
basic auto_increment implementation for embedded_innodb. On startup, fetch the maximum value for the auto_increment column (or what's in the table message as the auto_increment value). Use an atomic variable in the embedded-innodb table share to keep track of the auto_increment_value. We can then use atomic ops to get an autoinc value (or several) as well as update it in the event of inserting a larger number. Currently there's a bug (well, difference in behaviour) around inserting -1 into an auto-inc field where the table already has a value 'higher' than that and then asking for another auto-inc value. Check the auto_increment test case failure for it. This will be fixed in a later commit.
382
uint64_t EmbeddedInnoDBCursor::getInitialAutoIncrementValue()
383
{
384
  uint64_t nr;
385
  int error;
386
387
  (void) extra(HA_EXTRA_KEYREAD);
1532.1.15 by Brian Aker
Partial encapsulation of TableShare from Table.
388
  table->mark_columns_used_by_index_no_reset(table->getShare()->next_number_index);
389
  doStartIndexScan(table->getShare()->next_number_index, 1);
390
  if (table->getShare()->next_number_keypart == 0)
1283.36.13 by Stewart Smith
basic auto_increment implementation for embedded_innodb. On startup, fetch the maximum value for the auto_increment column (or what's in the table message as the auto_increment value). Use an atomic variable in the embedded-innodb table share to keep track of the auto_increment_value. We can then use atomic ops to get an autoinc value (or several) as well as update it in the event of inserting a larger number. Currently there's a bug (well, difference in behaviour) around inserting -1 into an auto-inc field where the table already has a value 'higher' than that and then asking for another auto-inc value. Check the auto_increment test case failure for it. This will be fixed in a later commit.
391
  {						// Autoincrement at key-start
392
    error=index_last(table->record[1]);
393
  }
394
  else
395
  {
396
    unsigned char key[MAX_KEY_LENGTH];
397
    key_copy(key, table->record[0],
1532.1.15 by Brian Aker
Partial encapsulation of TableShare from Table.
398
             table->key_info + table->getShare()->next_number_index,
399
             table->getShare()->next_number_key_offset);
1283.36.13 by Stewart Smith
basic auto_increment implementation for embedded_innodb. On startup, fetch the maximum value for the auto_increment column (or what's in the table message as the auto_increment value). Use an atomic variable in the embedded-innodb table share to keep track of the auto_increment_value. We can then use atomic ops to get an autoinc value (or several) as well as update it in the event of inserting a larger number. Currently there's a bug (well, difference in behaviour) around inserting -1 into an auto-inc field where the table already has a value 'higher' than that and then asking for another auto-inc value. Check the auto_increment test case failure for it. This will be fixed in a later commit.
400
    error= index_read_map(table->record[1], key,
1532.1.15 by Brian Aker
Partial encapsulation of TableShare from Table.
401
                          make_prev_keypart_map(table->getShare()->next_number_keypart),
1283.36.13 by Stewart Smith
basic auto_increment implementation for embedded_innodb. On startup, fetch the maximum value for the auto_increment column (or what's in the table message as the auto_increment value). Use an atomic variable in the embedded-innodb table share to keep track of the auto_increment_value. We can then use atomic ops to get an autoinc value (or several) as well as update it in the event of inserting a larger number. Currently there's a bug (well, difference in behaviour) around inserting -1 into an auto-inc field where the table already has a value 'higher' than that and then asking for another auto-inc value. Check the auto_increment test case failure for it. This will be fixed in a later commit.
402
                          HA_READ_PREFIX_LAST);
403
  }
404
405
  if (error)
406
    nr=1;
407
  else
408
    nr= ((uint64_t) table->found_next_number_field->
1532.1.15 by Brian Aker
Partial encapsulation of TableShare from Table.
409
         val_int_offset(table->getShare()->rec_buff_length)+1);
1283.37.10 by Stewart Smith
getInitialAutoIncrementValue() calls new names for index_init and index_end()
410
  doEndIndexScan();
1283.36.13 by Stewart Smith
basic auto_increment implementation for embedded_innodb. On startup, fetch the maximum value for the auto_increment column (or what's in the table message as the auto_increment value). Use an atomic variable in the embedded-innodb table share to keep track of the auto_increment_value. We can then use atomic ops to get an autoinc value (or several) as well as update it in the event of inserting a larger number. Currently there's a bug (well, difference in behaviour) around inserting -1 into an auto-inc field where the table already has a value 'higher' than that and then asking for another auto-inc value. Check the auto_increment test case failure for it. This will be fixed in a later commit.
411
  (void) extra(HA_EXTRA_NO_KEYREAD);
412
1532.1.15 by Brian Aker
Partial encapsulation of TableShare from Table.
413
  if (table->getShare()->getTableProto()->options().auto_increment_value() > nr)
414
    nr= table->getShare()->getTableProto()->options().auto_increment_value();
1283.36.13 by Stewart Smith
basic auto_increment implementation for embedded_innodb. On startup, fetch the maximum value for the auto_increment column (or what's in the table message as the auto_increment value). Use an atomic variable in the embedded-innodb table share to keep track of the auto_increment_value. We can then use atomic ops to get an autoinc value (or several) as well as update it in the event of inserting a larger number. Currently there's a bug (well, difference in behaviour) around inserting -1 into an auto-inc field where the table already has a value 'higher' than that and then asking for another auto-inc value. Check the auto_increment test case failure for it. This will be fixed in a later commit.
415
416
  return nr;
417
}
418
1283.35.97 by Stewart Smith
support tables without an explicit primary key in embedded_innodb by creating a hidden auto_increment primary key. We also have to support tables without an explicit primary key but with an auto increment, so we have our own hidden one. yes, it hurts.
419
EmbeddedInnoDBTableShare::EmbeddedInnoDBTableShare(const char* name, bool hidden_primary_key)
420
  : use_count(0), has_hidden_primary_key(hidden_primary_key)
1283.36.13 by Stewart Smith
basic auto_increment implementation for embedded_innodb. On startup, fetch the maximum value for the auto_increment column (or what's in the table message as the auto_increment value). Use an atomic variable in the embedded-innodb table share to keep track of the auto_increment_value. We can then use atomic ops to get an autoinc value (or several) as well as update it in the event of inserting a larger number. Currently there's a bug (well, difference in behaviour) around inserting -1 into an auto-inc field where the table already has a value 'higher' than that and then asking for another auto-inc value. Check the auto_increment test case failure for it. This will be fixed in a later commit.
421
{
422
  table_name.assign(name);
423
}
424
425
uint64_t EmbeddedInnoDBEngine::getInitialAutoIncrementValue(EmbeddedInnoDBCursor *cursor)
426
{
427
  doStartTransaction(current_session, START_TRANS_NO_OPTIONS);
428
  uint64_t initial_auto_increment_value= cursor->getInitialAutoIncrementValue();
429
  doCommit(current_session, true);
430
431
  return initial_auto_increment_value;
432
}
433
1283.35.97 by Stewart Smith
support tables without an explicit primary key in embedded_innodb by creating a hidden auto_increment primary key. We also have to support tables without an explicit primary key but with an auto increment, so we have our own hidden one. yes, it hurts.
434
uint64_t EmbeddedInnoDBEngine::getHiddenPrimaryKeyInitialAutoIncrementValue(EmbeddedInnoDBCursor *cursor)
435
{
436
  doStartTransaction(current_session, START_TRANS_NO_OPTIONS);
437
  uint64_t initial_auto_increment_value= cursor->getHiddenPrimaryKeyInitialAutoIncrementValue();
438
  doCommit(current_session, true);
439
440
  return initial_auto_increment_value;
441
}
442
443
EmbeddedInnoDBTableShare *EmbeddedInnoDBCursor::get_share(const char *table_name, bool has_hidden_primary_key, int *rc)
1283.3.80 by Stewart Smith
add basic transactional support to Embedded InnoDB engine.
444
{
445
  pthread_mutex_lock(&embedded_innodb_mutex);
446
447
  EmbeddedInnoDBEngine *a_engine= static_cast<EmbeddedInnoDBEngine *>(engine);
448
  share= a_engine->findOpenTable(table_name);
449
450
  if (!share)
451
  {
1283.35.97 by Stewart Smith
support tables without an explicit primary key in embedded_innodb by creating a hidden auto_increment primary key. We also have to support tables without an explicit primary key but with an auto increment, so we have our own hidden one. yes, it hurts.
452
    share= new EmbeddedInnoDBTableShare(table_name, has_hidden_primary_key);
1283.3.80 by Stewart Smith
add basic transactional support to Embedded InnoDB engine.
453
454
    if (share == NULL)
455
    {
456
      pthread_mutex_unlock(&embedded_innodb_mutex);
457
      *rc= HA_ERR_OUT_OF_MEM;
458
      return(NULL);
459
    }
460
1283.35.97 by Stewart Smith
support tables without an explicit primary key in embedded_innodb by creating a hidden auto_increment primary key. We also have to support tables without an explicit primary key but with an auto increment, so we have our own hidden one. yes, it hurts.
461
    if (table->found_next_number_field)
462
    {
463
      share->auto_increment_value.fetch_and_store(
464
                                  a_engine->getInitialAutoIncrementValue(this));
465
466
    }
467
468
    if (has_hidden_primary_key)
469
    {
470
      uint64_t hidden_pkey= 0;
471
      hidden_pkey= a_engine->getHiddenPrimaryKeyInitialAutoIncrementValue(this);
472
      share->hidden_pkey_auto_increment_value.fetch_and_store(hidden_pkey);
473
    }
474
1283.3.80 by Stewart Smith
add basic transactional support to Embedded InnoDB engine.
475
    a_engine->addOpenTable(share->table_name, share);
476
    thr_lock_init(&share->lock);
477
  }
478
  share->use_count++;
479
480
  pthread_mutex_unlock(&embedded_innodb_mutex);
481
482
  return(share);
483
}
484
485
int EmbeddedInnoDBCursor::free_share()
486
{
487
  pthread_mutex_lock(&embedded_innodb_mutex);
488
  if (!--share->use_count)
489
  {
490
    EmbeddedInnoDBEngine *a_engine= static_cast<EmbeddedInnoDBEngine *>(engine);
491
    a_engine->deleteOpenTable(share->table_name);
492
    delete share;
493
  }
494
  pthread_mutex_unlock(&embedded_innodb_mutex);
495
496
  return 0;
497
}
498
499
500
THR_LOCK_DATA **EmbeddedInnoDBCursor::store_lock(Session *session,
501
                                                 THR_LOCK_DATA **to,
502
                                                 thr_lock_type lock_type)
503
{
504
  /* Currently, we can get a transaction start by ::store_lock
505
     instead of beginTransaction, startStatement.
506
507
     See https://bugs.launchpad.net/drizzle/+bug/535528
508
509
     all stemming from the transactional engine interface needing
510
     a severe amount of immodium.
511
   */
512
513
  if(*get_trx(session) == NULL)
514
  {
515
    ib_trx_t *transaction= get_trx(session);
516
    *transaction= ib_trx_begin(IB_TRX_REPEATABLE_READ);
517
  }
518
1283.3.85 by Stewart Smith
take a savepoint at the start of each embedded innodb statement and roll back to that savepoint on error.
519
  if (lock_type != TL_UNLOCK)
520
  {
521
    ib_savepoint_take(*get_trx(session), statement_savepoint_name.c_str(),
522
                      statement_savepoint_name.length());
523
  }
524
1283.3.80 by Stewart Smith
add basic transactional support to Embedded InnoDB engine.
525
  /* the below is just copied from ha_archive.cc in some dim hope it's
526
     kinda right. */
527
528
  if (lock_type != TL_IGNORE && lock.type == TL_UNLOCK)
529
  {
530
    /*
531
      Here is where we get into the guts of a row level lock.
532
      If TL_UNLOCK is set
533
      If we are not doing a LOCK Table or DISCARD/IMPORT
534
      TABLESPACE, then allow multiple writers
535
    */
536
537
    if ((lock_type >= TL_WRITE_CONCURRENT_INSERT &&
538
         lock_type <= TL_WRITE)
539
        && !session_tablespace_op(session))
540
      lock_type = TL_WRITE_ALLOW_WRITE;
541
542
    /*
543
      In queries of type INSERT INTO t1 SELECT ... FROM t2 ...
544
      MySQL would use the lock TL_READ_NO_INSERT on t2, and that
545
      would conflict with TL_WRITE_ALLOW_WRITE, blocking all inserts
546
      to t2. Convert the lock to a normal read lock to allow
547
      concurrent inserts to t2.
548
    */
549
550
    if (lock_type == TL_READ_NO_INSERT)
551
      lock_type = TL_READ;
552
553
    lock.type=lock_type;
554
  }
555
556
  *to++= &lock;
557
558
  return to;
559
}
560
1283.36.13 by Stewart Smith
basic auto_increment implementation for embedded_innodb. On startup, fetch the maximum value for the auto_increment column (or what's in the table message as the auto_increment value). Use an atomic variable in the embedded-innodb table share to keep track of the auto_increment_value. We can then use atomic ops to get an autoinc value (or several) as well as update it in the event of inserting a larger number. Currently there's a bug (well, difference in behaviour) around inserting -1 into an auto-inc field where the table already has a value 'higher' than that and then asking for another auto-inc value. Check the auto_increment test case failure for it. This will be fixed in a later commit.
561
void EmbeddedInnoDBCursor::get_auto_increment(uint64_t, //offset,
562
                                              uint64_t, //increment,
563
                                              uint64_t, //nb_dis,
564
                                              uint64_t *first_value,
565
                                              uint64_t *nb_reserved_values)
566
{
1283.37.4 by Stewart Smith
fix embedded_innodb auto_increment for negative values (just strange really).
567
fetch:
1283.36.13 by Stewart Smith
basic auto_increment implementation for embedded_innodb. On startup, fetch the maximum value for the auto_increment column (or what's in the table message as the auto_increment value). Use an atomic variable in the embedded-innodb table share to keep track of the auto_increment_value. We can then use atomic ops to get an autoinc value (or several) as well as update it in the event of inserting a larger number. Currently there's a bug (well, difference in behaviour) around inserting -1 into an auto-inc field where the table already has a value 'higher' than that and then asking for another auto-inc value. Check the auto_increment test case failure for it. This will be fixed in a later commit.
568
  *first_value= share->auto_increment_value.fetch_and_increment();
1283.37.4 by Stewart Smith
fix embedded_innodb auto_increment for negative values (just strange really).
569
  if (*first_value == 0)
570
  {
571
    /* if it's zero, then we skip it... why? because of ass.
572
       set auto-inc to -1 and the sequence is:
573
       -1, 1.
574
       Zero is still "magic".
575
    */
576
    share->auto_increment_value.compare_and_swap(1, 0);
577
    goto fetch;
578
  }
1283.36.13 by Stewart Smith
basic auto_increment implementation for embedded_innodb. On startup, fetch the maximum value for the auto_increment column (or what's in the table message as the auto_increment value). Use an atomic variable in the embedded-innodb table share to keep track of the auto_increment_value. We can then use atomic ops to get an autoinc value (or several) as well as update it in the event of inserting a larger number. Currently there's a bug (well, difference in behaviour) around inserting -1 into an auto-inc field where the table already has a value 'higher' than that and then asking for another auto-inc value. Check the auto_increment test case failure for it. This will be fixed in a later commit.
579
  *nb_reserved_values= 1;
580
}
581
1283.11.19 by Stewart Smith
fix up create table for new bits of storage engine API r.e. TableIdentifier
582
static void TableIdentifier_to_innodb_name(TableIdentifier &identifier, std::string *str)
583
{
584
  str->reserve(identifier.getSchemaName().length() + identifier.getTableName().length() + 1);
1283.36.13 by Stewart Smith
basic auto_increment implementation for embedded_innodb. On startup, fetch the maximum value for the auto_increment column (or what's in the table message as the auto_increment value). Use an atomic variable in the embedded-innodb table share to keep track of the auto_increment_value. We can then use atomic ops to get an autoinc value (or several) as well as update it in the event of inserting a larger number. Currently there's a bug (well, difference in behaviour) around inserting -1 into an auto-inc field where the table already has a value 'higher' than that and then asking for another auto-inc value. Check the auto_increment test case failure for it. This will be fixed in a later commit.
585
//  str->append(identifier.getPath().c_str()+2);
1283.11.19 by Stewart Smith
fix up create table for new bits of storage engine API r.e. TableIdentifier
586
  str->assign(identifier.getSchemaName());
587
  str->append("/");
588
  str->append(identifier.getTableName());
589
}
590
1283.3.1 by Stewart Smith
Skeleton embedded_innodb plugin. Does nothing.
591
EmbeddedInnoDBCursor::EmbeddedInnoDBCursor(drizzled::plugin::StorageEngine &engine_arg,
592
                           TableShare &table_arg)
1283.39.8 by Stewart Smith
add support for REPLACE to embedded_innodb. On duplicate key on insert if we have HA_EXTRA_WRITE_CAN_REPLACE set, then we delete the row and insert.
593
  :Cursor(engine_arg, table_arg),
1283.60.10 by Stewart Smith
the memory management for BLOBS is completely insane. For certain types of index lookups we *must* do a copy and clear it *only* in ::reset() or ::extra(). This patch fixes up any valgrind warnings/assertions for embedded_innodb executing type_blob test.
594
   write_can_replace(false),
595
   blobroot(NULL)
1283.3.1 by Stewart Smith
Skeleton embedded_innodb plugin. Does nothing.
596
{ }
597
1283.3.27 by Stewart Smith
basic code to insert a integer
598
int EmbeddedInnoDBCursor::open(const char *name, int, uint32_t)
1283.3.1 by Stewart Smith
Skeleton embedded_innodb plugin. Does nothing.
599
{
1283.3.36 by Stewart Smith
'correctly' deal with transaction in an autocommit type way. this means queries like 'insert select' work as we're always in the correct transactional context.
600
  ib_err_t err= ib_cursor_open_table(name+2, NULL, &cursor);
1283.35.97 by Stewart Smith
support tables without an explicit primary key in embedded_innodb by creating a hidden auto_increment primary key. We also have to support tables without an explicit primary key but with an auto increment, so we have our own hidden one. yes, it hurts.
601
  bool has_hidden_primary_key= false;
1283.12.15 by Stewart Smith
style fixups: == and spaces
602
  assert (err == DB_SUCCESS);
1283.35.97 by Stewart Smith
support tables without an explicit primary key in embedded_innodb by creating a hidden auto_increment primary key. We also have to support tables without an explicit primary key but with an auto increment, so we have our own hidden one. yes, it hurts.
603
  ib_id_t idx_id;
604
605
  err= ib_index_get_id(name+2, "HIDDEN_PRIMARY", &idx_id);
606
  if (err == DB_SUCCESS)
607
    has_hidden_primary_key= true;
1283.3.27 by Stewart Smith
basic code to insert a integer
608
1283.3.80 by Stewart Smith
add basic transactional support to Embedded InnoDB engine.
609
  int rc;
1283.35.97 by Stewart Smith
support tables without an explicit primary key in embedded_innodb by creating a hidden auto_increment primary key. We also have to support tables without an explicit primary key but with an auto increment, so we have our own hidden one. yes, it hurts.
610
  share= get_share(name, has_hidden_primary_key, &rc);
1283.3.80 by Stewart Smith
add basic transactional support to Embedded InnoDB engine.
611
  thr_lock_data_init(&share->lock, &lock, NULL);
612
1283.35.97 by Stewart Smith
support tables without an explicit primary key in embedded_innodb by creating a hidden auto_increment primary key. We also have to support tables without an explicit primary key but with an auto increment, so we have our own hidden one. yes, it hurts.
613
1532.1.15 by Brian Aker
Partial encapsulation of TableShare from Table.
614
  if (table->getShare()->primary_key != MAX_KEY)
615
    ref_length= table->key_info[table->getShare()->primary_key].key_length;
1283.35.97 by Stewart Smith
support tables without an explicit primary key in embedded_innodb by creating a hidden auto_increment primary key. We also have to support tables without an explicit primary key but with an auto increment, so we have our own hidden one. yes, it hurts.
616
  else if (share->has_hidden_primary_key)
617
    ref_length= sizeof(uint64_t);
1283.28.24 by Stewart Smith
store ref_length in ::open() for ::position() in embedded_innodb. This method doesn't work for tables without a primary key though.... :/
618
  else
1283.35.97 by Stewart Smith
support tables without an explicit primary key in embedded_innodb by creating a hidden auto_increment primary key. We also have to support tables without an explicit primary key but with an auto increment, so we have our own hidden one. yes, it hurts.
619
  {
620
    ref_length= 0; // FIXME: this is a bug. we need to work out what index it is.
621
  }
1283.28.24 by Stewart Smith
store ref_length in ::open() for ::position() in embedded_innodb. This method doesn't work for tables without a primary key though.... :/
622
1283.60.11 by Stewart Smith
doStartTableScan() can be called twice in a row without a doEndTableScan()
623
  in_table_scan= false;
624
1283.3.1 by Stewart Smith
Skeleton embedded_innodb plugin. Does nothing.
625
  return(0);
626
}
627
628
int EmbeddedInnoDBCursor::close(void)
629
{
1283.19.28 by Stewart Smith
fixup error checking
630
  ib_err_t err= ib_cursor_close(cursor);
631
  if (err != DB_SUCCESS)
632
    return -1; // FIXME
633
1283.3.80 by Stewart Smith
add basic transactional support to Embedded InnoDB engine.
634
  free_share();
635
1283.60.10 by Stewart Smith
the memory management for BLOBS is completely insane. For certain types of index lookups we *must* do a copy and clear it *only* in ::reset() or ::extra(). This patch fixes up any valgrind warnings/assertions for embedded_innodb executing type_blob test.
636
  delete blobroot;
637
  blobroot= NULL;
638
1283.3.1 by Stewart Smith
Skeleton embedded_innodb plugin. Does nothing.
639
  return 0;
640
}
641
1283.3.13 by Stewart Smith
beginning of creating the table specified in the table proto. Embedded InnoDB now creates at least INT and VARCHAR types.
642
static int create_table_add_field(ib_tbl_sch_t schema,
1283.11.9 by Stewart Smith
create_table_add_field should take const reference of the field
643
                                  const message::Table::Field &field,
1283.3.13 by Stewart Smith
beginning of creating the table specified in the table proto. Embedded InnoDB now creates at least INT and VARCHAR types.
644
                                  ib_err_t *err)
645
{
646
  ib_col_attr_t column_attr= IB_COL_NONE;
647
1283.11.10 by Stewart Smith
fix setting of IB_COL_NOT_NULL flag
648
  if (field.has_constraints() && ! field.constraints().is_nullable())
1283.3.13 by Stewart Smith
beginning of creating the table specified in the table proto. Embedded InnoDB now creates at least INT and VARCHAR types.
649
    column_attr= IB_COL_NOT_NULL;
650
651
  switch (field.type())
652
  {
653
  case message::Table::Field::VARCHAR:
654
    *err= ib_table_schema_add_col(schema, field.name().c_str(), IB_VARCHAR,
655
                                  column_attr, 0,
656
                                  field.string_options().length());
657
    break;
658
  case message::Table::Field::INTEGER:
659
    *err= ib_table_schema_add_col(schema, field.name().c_str(), IB_INT,
660
                                  column_attr, 0, 4);
661
    break;
662
  case message::Table::Field::BIGINT:
663
    *err= ib_table_schema_add_col(schema, field.name().c_str(), IB_INT,
664
                                  column_attr, 0, 8);
665
    break;
1283.35.1 by Stewart Smith
basic DOUBLE type support. Currently fails some of the type_float test, researching error.
666
  case message::Table::Field::DOUBLE:
1283.35.45 by Stewart Smith
enable DATE type for embedded_innodb.
667
  case message::Table::Field::DATETIME:
1283.35.1 by Stewart Smith
basic DOUBLE type support. Currently fails some of the type_float test, researching error.
668
    *err= ib_table_schema_add_col(schema, field.name().c_str(), IB_DOUBLE,
669
                                  column_attr, 0, sizeof(double));
670
    break;
1283.35.27 by Stewart Smith
add ENUM SQL type support to Embedded InnoDB
671
  case message::Table::Field::ENUM:
672
  {
673
    message::Table::Field::EnumerationValues field_options=
674
      field.enumeration_values();
675
676
    if (field_options.field_value_size() <= 256)
677
      *err= ib_table_schema_add_col(schema, field.name().c_str(), IB_INT,
678
                                    column_attr, 0, 1);
679
    else if (field_options.field_value_size() > 256)
680
      *err= ib_table_schema_add_col(schema, field.name().c_str(), IB_INT,
681
                                    column_attr, 0, 2);
682
    else
683
    {
684
      assert(field_options.field_value_size() < (int)0x10000);
685
    }
686
    break;
687
  }
1283.35.45 by Stewart Smith
enable DATE type for embedded_innodb.
688
  case message::Table::Field::DATE:
1283.35.30 by Stewart Smith
support creating embedded_innodb tables with timestamp columns.
689
  case message::Table::Field::TIMESTAMP:
690
    *err= ib_table_schema_add_col(schema, field.name().c_str(), IB_INT,
691
                                  column_attr, 0, 4);
692
    break;
1283.60.5 by Stewart Smith
add BLOB support to embedded_innodb along with a simple test.
693
  case message::Table::Field::BLOB:
694
    *err= ib_table_schema_add_col(schema, field.name().c_str(), IB_BLOB,
695
                                  column_attr, 0, 0);
696
    break;
1283.61.1 by Stewart Smith
very simple addition to create fields of DECIMAL type
697
  case message::Table::Field::DECIMAL:
698
    *err= ib_table_schema_add_col(schema, field.name().c_str(), IB_DECIMAL,
699
                                  column_attr, 0, 0);
700
    break;
1283.3.13 by Stewart Smith
beginning of creating the table specified in the table proto. Embedded InnoDB now creates at least INT and VARCHAR types.
701
  default:
702
    my_error(ER_CHECK_NOT_IMPLEMENTED, MYF(0), "Column Type");
703
    return(HA_ERR_UNSUPPORTED);
704
  }
705
706
  return 0;
707
}
708
1283.17.15 by Stewart Smith
add proper error checking to store_table_message() and roll back the data dictionary transaction if there was an error storing the table proto
709
static ib_err_t store_table_message(ib_trx_t transaction, const char* table_name, drizzled::message::Table& table_message)
1283.3.26 by Stewart Smith
basic store/read/delete table proto from embedded innodb table. This makes CREATE TABLE 100% crash safe. This also makes SHOW CREATE TABLE work for embedded innodb tables.
710
{
711
  ib_crsr_t cursor;
1283.17.11 by Stewart Smith
change data_dictionary.innodb_table_proto to data_dictionary.innodb_table_definition
712
  ib_tpl_t message_tuple;
1283.3.26 by Stewart Smith
basic store/read/delete table proto from embedded innodb table. This makes CREATE TABLE 100% crash safe. This also makes SHOW CREATE TABLE work for embedded innodb tables.
713
  ib_err_t err;
1283.17.15 by Stewart Smith
add proper error checking to store_table_message() and roll back the data dictionary transaction if there was an error storing the table proto
714
  string serialized_message;
1283.3.26 by Stewart Smith
basic store/read/delete table proto from embedded innodb table. This makes CREATE TABLE 100% crash safe. This also makes SHOW CREATE TABLE work for embedded innodb tables.
715
1283.17.12 by Stewart Smith
use define to set the name of the innodb_table_definitions table instead of repeating it 5 times through the code
716
  err= ib_cursor_open_table(INNODB_TABLE_DEFINITIONS_TABLE, transaction, &cursor);
1283.17.15 by Stewart Smith
add proper error checking to store_table_message() and roll back the data dictionary transaction if there was an error storing the table proto
717
  if (err != DB_SUCCESS)
718
    return err;
1283.17.11 by Stewart Smith
change data_dictionary.innodb_table_proto to data_dictionary.innodb_table_definition
719
720
  message_tuple= ib_clust_read_tuple_create(cursor);
721
722
  err= ib_col_set_value(message_tuple, 0, table_name, strlen(table_name));
1283.17.15 by Stewart Smith
add proper error checking to store_table_message() and roll back the data dictionary transaction if there was an error storing the table proto
723
  if (err != DB_SUCCESS)
724
    goto cleanup;
1283.17.11 by Stewart Smith
change data_dictionary.innodb_table_proto to data_dictionary.innodb_table_definition
725
726
  table_message.SerializeToString(&serialized_message);
727
728
  err= ib_col_set_value(message_tuple, 1, serialized_message.c_str(),
729
                        serialized_message.length());
1283.17.15 by Stewart Smith
add proper error checking to store_table_message() and roll back the data dictionary transaction if there was an error storing the table proto
730
  if (err != DB_SUCCESS)
731
    goto cleanup;
1283.17.11 by Stewart Smith
change data_dictionary.innodb_table_proto to data_dictionary.innodb_table_definition
732
733
  err= ib_cursor_insert_row(cursor, message_tuple);
734
1283.17.15 by Stewart Smith
add proper error checking to store_table_message() and roll back the data dictionary transaction if there was an error storing the table proto
735
cleanup:
1283.17.11 by Stewart Smith
change data_dictionary.innodb_table_proto to data_dictionary.innodb_table_definition
736
  ib_tuple_delete(message_tuple);
1283.3.26 by Stewart Smith
basic store/read/delete table proto from embedded innodb table. This makes CREATE TABLE 100% crash safe. This also makes SHOW CREATE TABLE work for embedded innodb tables.
737
1283.19.28 by Stewart Smith
fixup error checking
738
  ib_err_t cleanup_err= ib_cursor_close(cursor);
739
  if (err == DB_SUCCESS)
740
    err= cleanup_err;
1283.3.26 by Stewart Smith
basic store/read/delete table proto from embedded innodb table. This makes CREATE TABLE 100% crash safe. This also makes SHOW CREATE TABLE work for embedded innodb tables.
741
1283.17.15 by Stewart Smith
add proper error checking to store_table_message() and roll back the data dictionary transaction if there was an error storing the table proto
742
  return err;
1283.3.26 by Stewart Smith
basic store/read/delete table proto from embedded innodb table. This makes CREATE TABLE 100% crash safe. This also makes SHOW CREATE TABLE work for embedded innodb tables.
743
}
744
1283.17.38 by Stewart Smith
merge trunk
745
1283.11.25 by Stewart Smith
merge trunk
746
int EmbeddedInnoDBEngine::doCreateTable(Session &session,
1283.11.19 by Stewart Smith
fix up create table for new bits of storage engine API r.e. TableIdentifier
747
                                        Table& table_obj,
748
                                        drizzled::TableIdentifier &identifier,
749
                                        drizzled::message::Table& table_message)
1283.3.1 by Stewart Smith
Skeleton embedded_innodb plugin. Does nothing.
750
{
1283.3.12 by Stewart Smith
incredibly simple CREATE TABLE (and test) for embedded innodb. just creates a table with the supplied name (NOT with the supplied schema). Tests that we can't create the same table twice and that we're talking okay to libinnodb.
751
  ib_tbl_sch_t innodb_table_schema= NULL;
1283.3.13 by Stewart Smith
beginning of creating the table specified in the table proto. Embedded InnoDB now creates at least INT and VARCHAR types.
752
//  ib_idx_sch_t innodb_pkey= NULL;
1283.3.12 by Stewart Smith
incredibly simple CREATE TABLE (and test) for embedded innodb. just creates a table with the supplied name (NOT with the supplied schema). Tests that we can't create the same table twice and that we're talking okay to libinnodb.
753
  ib_trx_t innodb_schema_transaction;
754
  ib_id_t innodb_table_id;
755
  ib_err_t innodb_err= DB_SUCCESS;
1283.11.19 by Stewart Smith
fix up create table for new bits of storage engine API r.e. TableIdentifier
756
  string innodb_table_name;
1283.35.97 by Stewart Smith
support tables without an explicit primary key in embedded_innodb by creating a hidden auto_increment primary key. We also have to support tables without an explicit primary key but with an auto increment, so we have our own hidden one. yes, it hurts.
757
  bool has_explicit_pkey= false;
1283.11.25 by Stewart Smith
merge trunk
758
1283.3.12 by Stewart Smith
incredibly simple CREATE TABLE (and test) for embedded innodb. just creates a table with the supplied name (NOT with the supplied schema). Tests that we can't create the same table twice and that we're talking okay to libinnodb.
759
  (void)table_obj;
760
1283.11.19 by Stewart Smith
fix up create table for new bits of storage engine API r.e. TableIdentifier
761
  TableIdentifier_to_innodb_name(identifier, &innodb_table_name);
762
763
  innodb_err= ib_table_schema_create(innodb_table_name.c_str(),
764
                                     &innodb_table_schema, IB_TBL_COMPACT, 0);
1283.3.12 by Stewart Smith
incredibly simple CREATE TABLE (and test) for embedded innodb. just creates a table with the supplied name (NOT with the supplied schema). Tests that we can't create the same table twice and that we're talking okay to libinnodb.
765
766
  if (innodb_err != DB_SUCCESS)
767
  {
1283.11.25 by Stewart Smith
merge trunk
768
    push_warning_printf(&session, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
1283.3.12 by Stewart Smith
incredibly simple CREATE TABLE (and test) for embedded innodb. just creates a table with the supplied name (NOT with the supplied schema). Tests that we can't create the same table twice and that we're talking okay to libinnodb.
769
                        ER_CANT_CREATE_TABLE,
770
                        _("Cannot create table %s. InnoDB Error %d (%s)\n"),
1283.11.19 by Stewart Smith
fix up create table for new bits of storage engine API r.e. TableIdentifier
771
                        innodb_table_name.c_str(), innodb_err, ib_strerror(innodb_err));
1283.3.12 by Stewart Smith
incredibly simple CREATE TABLE (and test) for embedded innodb. just creates a table with the supplied name (NOT with the supplied schema). Tests that we can't create the same table twice and that we're talking okay to libinnodb.
772
    return HA_ERR_GENERIC;
773
  }
774
1283.3.13 by Stewart Smith
beginning of creating the table specified in the table proto. Embedded InnoDB now creates at least INT and VARCHAR types.
775
  for (int colnr= 0; colnr < table_message.field_size() ; colnr++)
776
  {
777
    const message::Table::Field field = table_message.field(colnr);
778
779
    int field_err= create_table_add_field(innodb_table_schema, field,
780
                                          &innodb_err);
781
782
    if (innodb_err != DB_SUCCESS || field_err != 0)
783
      ib_table_schema_delete(innodb_table_schema); /* cleanup */
784
785
    if (innodb_err != DB_SUCCESS)
786
    {
1283.11.25 by Stewart Smith
merge trunk
787
      push_warning_printf(&session, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
1283.3.13 by Stewart Smith
beginning of creating the table specified in the table proto. Embedded InnoDB now creates at least INT and VARCHAR types.
788
                          ER_CANT_CREATE_TABLE,
789
                          _("Cannot create field %s on table %s."
790
                            " InnoDB Error %d (%s)\n"),
1283.11.19 by Stewart Smith
fix up create table for new bits of storage engine API r.e. TableIdentifier
791
                          field.name().c_str(), innodb_table_name.c_str(),
1283.3.13 by Stewart Smith
beginning of creating the table specified in the table proto. Embedded InnoDB now creates at least INT and VARCHAR types.
792
                          innodb_err, ib_strerror(innodb_err));
793
      return HA_ERR_GENERIC;
794
    }
795
    if (field_err != 0)
796
      return field_err;
797
  }
1283.3.37 by Stewart Smith
basic support for indexes in CREATE TABLE for embedded innodb engine
798
1283.35.49 by Stewart Smith
allow embedded_innodb tables to be created with a first not null unique index instead of just explicit PRIMARY KEY. We use this key as the clustered index (which is really our requirement)
799
  bool has_primary= false;
1283.3.37 by Stewart Smith
basic support for indexes in CREATE TABLE for embedded innodb engine
800
  for (int indexnr= 0; indexnr < table_message.indexes_size() ; indexnr++)
801
  {
802
    message::Table::Index *index = table_message.mutable_indexes(indexnr);
803
804
    ib_idx_sch_t innodb_index;
805
1283.18.31 by Stewart Smith
fix up error handling in index creation
806
    innodb_err= ib_table_schema_add_index(innodb_table_schema, index->name().c_str(),
807
                                   &innodb_index);
808
    if (innodb_err != DB_SUCCESS)
809
      goto schema_error;
1283.3.37 by Stewart Smith
basic support for indexes in CREATE TABLE for embedded innodb engine
810
811
    if (index->is_primary())
1283.18.31 by Stewart Smith
fix up error handling in index creation
812
    {
1283.35.49 by Stewart Smith
allow embedded_innodb tables to be created with a first not null unique index instead of just explicit PRIMARY KEY. We use this key as the clustered index (which is really our requirement)
813
      has_primary= true;
1283.18.31 by Stewart Smith
fix up error handling in index creation
814
      innodb_err= ib_index_schema_set_clustered(innodb_index);
1283.35.97 by Stewart Smith
support tables without an explicit primary key in embedded_innodb by creating a hidden auto_increment primary key. We also have to support tables without an explicit primary key but with an auto increment, so we have our own hidden one. yes, it hurts.
815
      has_explicit_pkey= true;
1283.18.31 by Stewart Smith
fix up error handling in index creation
816
      if (innodb_err != DB_SUCCESS)
817
        goto schema_error;
818
    }
1283.3.37 by Stewart Smith
basic support for indexes in CREATE TABLE for embedded innodb engine
819
820
    if (index->is_unique())
1283.18.31 by Stewart Smith
fix up error handling in index creation
821
    {
822
      innodb_err= ib_index_schema_set_unique(innodb_index);
823
      if (innodb_err != DB_SUCCESS)
824
        goto schema_error;
825
    }
1283.3.37 by Stewart Smith
basic support for indexes in CREATE TABLE for embedded innodb engine
826
827
    if (index->type() == message::Table::Index::UNKNOWN_INDEX)
828
      index->set_type(message::Table::Index::BTREE);
829
830
    for (int partnr= 0; partnr < index->index_part_size(); partnr++)
831
    {
1283.3.38 by Stewart Smith
add comment about TODO for index prefixes
832
      /* TODO: Index prefix lengths */
1283.3.37 by Stewart Smith
basic support for indexes in CREATE TABLE for embedded innodb engine
833
      const message::Table::Index::IndexPart part= index->index_part(partnr);
1283.18.31 by Stewart Smith
fix up error handling in index creation
834
      innodb_err= ib_index_schema_add_col(innodb_index, table_message.field(part.fieldnr()).name().c_str(), 0);
835
      if (innodb_err != DB_SUCCESS)
836
        goto schema_error;
1283.3.37 by Stewart Smith
basic support for indexes in CREATE TABLE for embedded innodb engine
837
    }
1283.35.49 by Stewart Smith
allow embedded_innodb tables to be created with a first not null unique index instead of just explicit PRIMARY KEY. We use this key as the clustered index (which is really our requirement)
838
839
    if (! has_primary && index->is_unique())
840
    {
841
      innodb_err= ib_index_schema_set_clustered(innodb_index);
1283.35.97 by Stewart Smith
support tables without an explicit primary key in embedded_innodb by creating a hidden auto_increment primary key. We also have to support tables without an explicit primary key but with an auto increment, so we have our own hidden one. yes, it hurts.
842
      has_explicit_pkey= true;
1283.35.49 by Stewart Smith
allow embedded_innodb tables to be created with a first not null unique index instead of just explicit PRIMARY KEY. We use this key as the clustered index (which is really our requirement)
843
      if (innodb_err != DB_SUCCESS)
844
        goto schema_error;
845
    }
846
1283.3.37 by Stewart Smith
basic support for indexes in CREATE TABLE for embedded innodb engine
847
  }
848
1283.35.97 by Stewart Smith
support tables without an explicit primary key in embedded_innodb by creating a hidden auto_increment primary key. We also have to support tables without an explicit primary key but with an auto increment, so we have our own hidden one. yes, it hurts.
849
  if (! has_explicit_pkey)
850
  {
851
    ib_idx_sch_t innodb_index;
852
853
    innodb_err= ib_table_schema_add_col(innodb_table_schema, "hidden_primary_key_col",
854
                                        IB_INT, IB_COL_NOT_NULL, 0, 8);
855
856
    innodb_err= ib_table_schema_add_index(innodb_table_schema, "HIDDEN_PRIMARY",
857
                                          &innodb_index);
858
    if (innodb_err != DB_SUCCESS)
859
      goto schema_error;
860
861
    innodb_err= ib_index_schema_set_clustered(innodb_index);
862
    if (innodb_err != DB_SUCCESS)
863
      goto schema_error;
864
865
    innodb_err= ib_index_schema_add_col(innodb_index, "hidden_primary_key_col", 0);
866
    if (innodb_err != DB_SUCCESS)
867
      goto schema_error;
868
  }
869
1283.3.12 by Stewart Smith
incredibly simple CREATE TABLE (and test) for embedded innodb. just creates a table with the supplied name (NOT with the supplied schema). Tests that we can't create the same table twice and that we're talking okay to libinnodb.
870
  innodb_schema_transaction= ib_trx_begin(IB_TRX_REPEATABLE_READ);
1283.11.15 by Stewart Smith
fix up checking return codes used in CREATE TABLE for Embedded InnoDB Engine
871
  innodb_err= ib_schema_lock_exclusive(innodb_schema_transaction);
872
  if (innodb_err != DB_SUCCESS)
873
  {
874
    ib_err_t rollback_err= ib_trx_rollback(innodb_schema_transaction);
875
    ib_table_schema_delete(innodb_table_schema);
876
1283.11.25 by Stewart Smith
merge trunk
877
    push_warning_printf(&session, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
1283.11.15 by Stewart Smith
fix up checking return codes used in CREATE TABLE for Embedded InnoDB Engine
878
                        ER_CANT_CREATE_TABLE,
879
                        _("Cannot Lock Embedded InnoDB Data Dictionary. InnoDB Error %d (%s)\n"),
880
                        innodb_err, ib_strerror(innodb_err));
881
882
    assert (rollback_err == DB_SUCCESS);
883
884
    return HA_ERR_GENERIC;
885
  }
1283.3.12 by Stewart Smith
incredibly simple CREATE TABLE (and test) for embedded innodb. just creates a table with the supplied name (NOT with the supplied schema). Tests that we can't create the same table twice and that we're talking okay to libinnodb.
886
887
  innodb_err= ib_table_create(innodb_schema_transaction, innodb_table_schema,
888
                              &innodb_table_id);
889
890
  if (innodb_err != DB_SUCCESS)
891
  {
1283.11.15 by Stewart Smith
fix up checking return codes used in CREATE TABLE for Embedded InnoDB Engine
892
    ib_err_t rollback_err= ib_trx_rollback(innodb_schema_transaction);
1283.3.12 by Stewart Smith
incredibly simple CREATE TABLE (and test) for embedded innodb. just creates a table with the supplied name (NOT with the supplied schema). Tests that we can't create the same table twice and that we're talking okay to libinnodb.
893
    ib_table_schema_delete(innodb_table_schema);
894
895
    if (innodb_err == DB_TABLE_IS_BEING_USED)
896
      return EEXIST;
897
1283.11.25 by Stewart Smith
merge trunk
898
    push_warning_printf(&session, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
1283.3.12 by Stewart Smith
incredibly simple CREATE TABLE (and test) for embedded innodb. just creates a table with the supplied name (NOT with the supplied schema). Tests that we can't create the same table twice and that we're talking okay to libinnodb.
899
                        ER_CANT_CREATE_TABLE,
900
                        _("Cannot create table %s. InnoDB Error %d (%s)\n"),
1283.11.19 by Stewart Smith
fix up create table for new bits of storage engine API r.e. TableIdentifier
901
                        innodb_table_name.c_str(),
902
                        innodb_err, ib_strerror(innodb_err));
1283.11.15 by Stewart Smith
fix up checking return codes used in CREATE TABLE for Embedded InnoDB Engine
903
904
    assert (rollback_err == DB_SUCCESS);
1283.3.12 by Stewart Smith
incredibly simple CREATE TABLE (and test) for embedded innodb. just creates a table with the supplied name (NOT with the supplied schema). Tests that we can't create the same table twice and that we're talking okay to libinnodb.
905
    return HA_ERR_GENERIC;
906
  }
907
1283.17.31 by Stewart Smith
fix up store/read table message for TableIdentifier
908
  innodb_err= store_table_message(innodb_schema_transaction,
909
                                  innodb_table_name.c_str(),
1283.17.15 by Stewart Smith
add proper error checking to store_table_message() and roll back the data dictionary transaction if there was an error storing the table proto
910
                                  table_message);
1283.3.26 by Stewart Smith
basic store/read/delete table proto from embedded innodb table. This makes CREATE TABLE 100% crash safe. This also makes SHOW CREATE TABLE work for embedded innodb tables.
911
1283.17.15 by Stewart Smith
add proper error checking to store_table_message() and roll back the data dictionary transaction if there was an error storing the table proto
912
  if (innodb_err == DB_SUCCESS)
913
    innodb_err= ib_trx_commit(innodb_schema_transaction);
914
  else
915
    innodb_err= ib_trx_rollback(innodb_schema_transaction);
1283.3.12 by Stewart Smith
incredibly simple CREATE TABLE (and test) for embedded innodb. just creates a table with the supplied name (NOT with the supplied schema). Tests that we can't create the same table twice and that we're talking okay to libinnodb.
916
1283.18.31 by Stewart Smith
fix up error handling in index creation
917
schema_error:
1283.3.12 by Stewart Smith
incredibly simple CREATE TABLE (and test) for embedded innodb. just creates a table with the supplied name (NOT with the supplied schema). Tests that we can't create the same table twice and that we're talking okay to libinnodb.
918
  ib_table_schema_delete(innodb_table_schema);
919
920
  if (innodb_err != DB_SUCCESS)
921
  {
1283.11.25 by Stewart Smith
merge trunk
922
    push_warning_printf(&session, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
1283.3.12 by Stewart Smith
incredibly simple CREATE TABLE (and test) for embedded innodb. just creates a table with the supplied name (NOT with the supplied schema). Tests that we can't create the same table twice and that we're talking okay to libinnodb.
923
                        ER_CANT_CREATE_TABLE,
924
                        _("Cannot create table %s. InnoDB Error %d (%s)\n"),
1283.11.19 by Stewart Smith
fix up create table for new bits of storage engine API r.e. TableIdentifier
925
                        innodb_table_name.c_str(),
926
                        innodb_err, ib_strerror(innodb_err));
1283.3.12 by Stewart Smith
incredibly simple CREATE TABLE (and test) for embedded innodb. just creates a table with the supplied name (NOT with the supplied schema). Tests that we can't create the same table twice and that we're talking okay to libinnodb.
927
    return HA_ERR_GENERIC;
928
  }
929
930
  return 0;
1283.3.1 by Stewart Smith
Skeleton embedded_innodb plugin. Does nothing.
931
}
932
1283.17.11 by Stewart Smith
change data_dictionary.innodb_table_proto to data_dictionary.innodb_table_definition
933
static int delete_table_message_from_innodb(ib_trx_t transaction, const char* table_name)
1283.3.26 by Stewart Smith
basic store/read/delete table proto from embedded innodb table. This makes CREATE TABLE 100% crash safe. This also makes SHOW CREATE TABLE work for embedded innodb tables.
934
{
935
  ib_crsr_t cursor;
936
  ib_tpl_t search_tuple;
937
  int res;
938
  ib_err_t err;
939
1283.19.28 by Stewart Smith
fixup error checking
940
  err= ib_cursor_open_table(INNODB_TABLE_DEFINITIONS_TABLE, transaction, &cursor);
941
  if (err != DB_SUCCESS)
942
    return err;
943
1283.3.26 by Stewart Smith
basic store/read/delete table proto from embedded innodb table. This makes CREATE TABLE 100% crash safe. This also makes SHOW CREATE TABLE work for embedded innodb tables.
944
  search_tuple= ib_clust_search_tuple_create(cursor);
945
1283.19.28 by Stewart Smith
fixup error checking
946
  err= ib_col_set_value(search_tuple, 0, table_name, strlen(table_name));
947
  if (err != DB_SUCCESS)
948
    goto rollback;
1283.3.26 by Stewart Smith
basic store/read/delete table proto from embedded innodb table. This makes CREATE TABLE 100% crash safe. This also makes SHOW CREATE TABLE work for embedded innodb tables.
949
950
//  ib_cursor_set_match_mode(cursor, IB_EXACT_MATCH);
951
952
  err= ib_cursor_moveto(cursor, search_tuple, IB_CUR_GE, &res);
953
  if (err == DB_RECORD_NOT_FOUND || res != 0)
954
    goto rollback;
955
956
  err= ib_cursor_delete_row(cursor);
957
  assert (err == DB_SUCCESS);
958
959
rollback:
1283.19.28 by Stewart Smith
fixup error checking
960
  ib_err_t rollback_err= ib_cursor_close(cursor);
961
  if (err == DB_SUCCESS)
962
    err= rollback_err;
963
1283.3.26 by Stewart Smith
basic store/read/delete table proto from embedded innodb table. This makes CREATE TABLE 100% crash safe. This also makes SHOW CREATE TABLE work for embedded innodb tables.
964
  ib_tuple_delete(search_tuple);
965
966
  return err;
967
}
1283.3.1 by Stewart Smith
Skeleton embedded_innodb plugin. Does nothing.
968
1283.15.22 by Stewart Smith
fix up drop table for new bits of storage engine API r.e. TableIdentifier
969
int EmbeddedInnoDBEngine::doDropTable(Session &session,
970
                                      TableIdentifier &identifier)
1283.3.1 by Stewart Smith
Skeleton embedded_innodb plugin. Does nothing.
971
{
1283.3.23 by Stewart Smith
Add basic DROP TABLE support to embedded innodb engine.
972
  ib_trx_t innodb_schema_transaction;
973
  ib_err_t innodb_err;
1283.15.22 by Stewart Smith
fix up drop table for new bits of storage engine API r.e. TableIdentifier
974
  string innodb_table_name;
975
976
  TableIdentifier_to_innodb_name(identifier, &innodb_table_name);
1283.3.23 by Stewart Smith
Add basic DROP TABLE support to embedded innodb engine.
977
978
  innodb_schema_transaction= ib_trx_begin(IB_TRX_REPEATABLE_READ);
1283.15.18 by Stewart Smith
lock schema in drop table (needed for drop table to work
979
  innodb_err= ib_schema_lock_exclusive(innodb_schema_transaction);
980
  if (innodb_err != DB_SUCCESS)
981
  {
982
    ib_err_t rollback_err= ib_trx_rollback(innodb_schema_transaction);
983
984
    push_warning_printf(&session, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
985
                        ER_CANT_DELETE_FILE,
986
                        _("Cannot Lock Embedded InnoDB Data Dictionary. InnoDB Error %d (%s)\n"),
987
                        innodb_err, ib_strerror(innodb_err));
988
989
    assert (rollback_err == DB_SUCCESS);
990
991
    return HA_ERR_GENERIC;
992
  }
1283.3.23 by Stewart Smith
Add basic DROP TABLE support to embedded innodb engine.
993
1283.17.31 by Stewart Smith
fix up store/read table message for TableIdentifier
994
  if (delete_table_message_from_innodb(innodb_schema_transaction, innodb_table_name.c_str()) != DB_SUCCESS)
1283.3.26 by Stewart Smith
basic store/read/delete table proto from embedded innodb table. This makes CREATE TABLE 100% crash safe. This also makes SHOW CREATE TABLE work for embedded innodb tables.
995
  {
1283.19.28 by Stewart Smith
fixup error checking
996
    ib_schema_unlock(innodb_schema_transaction);
1283.17.22 by Stewart Smith
fix up doDropTable for schema transaction
997
    ib_err_t rollback_err= ib_trx_rollback(innodb_schema_transaction);
998
    assert(rollback_err == DB_SUCCESS);
1283.3.26 by Stewart Smith
basic store/read/delete table proto from embedded innodb table. This makes CREATE TABLE 100% crash safe. This also makes SHOW CREATE TABLE work for embedded innodb tables.
999
    return HA_ERR_GENERIC;
1000
  }
1001
1283.15.22 by Stewart Smith
fix up drop table for new bits of storage engine API r.e. TableIdentifier
1002
  innodb_err= ib_table_drop(innodb_schema_transaction, innodb_table_name.c_str());
1283.3.23 by Stewart Smith
Add basic DROP TABLE support to embedded innodb engine.
1003
1004
  if (innodb_err == DB_TABLE_NOT_FOUND)
1005
  {
1283.15.17 by Stewart Smith
assert out on rollback errors in error states in drop table
1006
    innodb_err= ib_trx_rollback(innodb_schema_transaction);
1007
    assert(innodb_err == DB_SUCCESS);
1283.3.23 by Stewart Smith
Add basic DROP TABLE support to embedded innodb engine.
1008
    return ENOENT;
1009
  }
1010
  else if (innodb_err != DB_SUCCESS)
1011
  {
1283.15.17 by Stewart Smith
assert out on rollback errors in error states in drop table
1012
    ib_err_t rollback_err= ib_trx_rollback(innodb_schema_transaction);
1283.3.23 by Stewart Smith
Add basic DROP TABLE support to embedded innodb engine.
1013
1014
    push_warning_printf(&session, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
1015
                        ER_CANT_DELETE_FILE,
1016
                        _("Cannot DROP table %s. InnoDB Error %d (%s)\n"),
1283.15.22 by Stewart Smith
fix up drop table for new bits of storage engine API r.e. TableIdentifier
1017
                        innodb_table_name.c_str(),
1283.3.23 by Stewart Smith
Add basic DROP TABLE support to embedded innodb engine.
1018
                        innodb_err, ib_strerror(innodb_err));
1283.15.17 by Stewart Smith
assert out on rollback errors in error states in drop table
1019
1020
    assert(rollback_err == DB_SUCCESS);
1021
1283.3.23 by Stewart Smith
Add basic DROP TABLE support to embedded innodb engine.
1022
    return HA_ERR_GENERIC;
1023
  }
1024
1025
  innodb_err= ib_trx_commit(innodb_schema_transaction);
1026
  if (innodb_err != DB_SUCCESS)
1027
  {
1283.15.17 by Stewart Smith
assert out on rollback errors in error states in drop table
1028
    ib_err_t rollback_err= ib_trx_rollback(innodb_schema_transaction);
1283.3.23 by Stewart Smith
Add basic DROP TABLE support to embedded innodb engine.
1029
1030
    push_warning_printf(&session, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
1031
                        ER_CANT_DELETE_FILE,
1032
                        _("Cannot DROP table %s. InnoDB Error %d (%s)\n"),
1283.15.22 by Stewart Smith
fix up drop table for new bits of storage engine API r.e. TableIdentifier
1033
                        innodb_table_name.c_str(),
1283.3.23 by Stewart Smith
Add basic DROP TABLE support to embedded innodb engine.
1034
                        innodb_err, ib_strerror(innodb_err));
1283.15.17 by Stewart Smith
assert out on rollback errors in error states in drop table
1035
1036
    assert(rollback_err == DB_SUCCESS);
1283.3.23 by Stewart Smith
Add basic DROP TABLE support to embedded innodb engine.
1037
    return HA_ERR_GENERIC;
1038
  }
1039
1040
  return 0;
1283.3.1 by Stewart Smith
Skeleton embedded_innodb plugin. Does nothing.
1041
}
1042
1283.30.12 by Stewart Smith
fix rename table for new prototype as well as that table names are read from the proto instead of from getTableNames, which means on rename we must read the table proto, modify ita nd then store it again.
1043
static ib_err_t rename_table_message(ib_trx_t transaction, TableIdentifier &from_identifier, TableIdentifier &to_identifier)
1283.28.2 by Stewart Smith
add basic RENAME TABLE support for Embedded InnoDB. Also add a basic test, and copy over the rename.test test and run it against embedded innodb.
1044
{
1045
  ib_crsr_t cursor;
1046
  ib_tpl_t search_tuple;
1047
  ib_tpl_t read_tuple;
1048
  ib_tpl_t update_tuple;
1049
  int res;
1050
  ib_err_t err;
1051
  ib_err_t rollback_err;
1283.30.12 by Stewart Smith
fix rename table for new prototype as well as that table names are read from the proto instead of from getTableNames, which means on rename we must read the table proto, modify ita nd then store it again.
1052
  const char *message;
1053
  ib_ulint_t message_len;
1054
  drizzled::message::Table table_message;
1055
  string from_innodb_table_name;
1056
  string to_innodb_table_name;
1057
  const char *from;
1058
  const char *to;
1059
  string serialized_message;
1060
  ib_col_meta_t col_meta;
1061
1062
  TableIdentifier_to_innodb_name(from_identifier, &from_innodb_table_name);
1063
  TableIdentifier_to_innodb_name(to_identifier, &to_innodb_table_name);
1064
1065
  from= from_innodb_table_name.c_str();
1066
  to= to_innodb_table_name.c_str();
1283.28.2 by Stewart Smith
add basic RENAME TABLE support for Embedded InnoDB. Also add a basic test, and copy over the rename.test test and run it against embedded innodb.
1067
1068
  err= ib_cursor_open_table(INNODB_TABLE_DEFINITIONS_TABLE, transaction, &cursor);
1069
  if (err != DB_SUCCESS)
1070
  {
1071
    rollback_err= ib_trx_rollback(transaction);
1072
    assert(rollback_err == DB_SUCCESS);
1073
    return err;
1074
  }
1075
1076
  search_tuple= ib_clust_search_tuple_create(cursor);
1077
  read_tuple= ib_clust_read_tuple_create(cursor);
1078
1079
  err= ib_col_set_value(search_tuple, 0, from, strlen(from));
1080
  if (err != DB_SUCCESS)
1081
    goto rollback;
1082
1083
//  ib_cursor_set_match_mode(cursor, IB_EXACT_MATCH);
1084
1085
  err= ib_cursor_moveto(cursor, search_tuple, IB_CUR_GE, &res);
1086
  if (err == DB_RECORD_NOT_FOUND || res != 0)
1087
    goto rollback;
1088
1089
  err= ib_cursor_read_row(cursor, read_tuple);
1090
  if (err == DB_RECORD_NOT_FOUND || res != 0)
1091
    goto rollback;
1092
1283.30.12 by Stewart Smith
fix rename table for new prototype as well as that table names are read from the proto instead of from getTableNames, which means on rename we must read the table proto, modify ita nd then store it again.
1093
  message= (const char*)ib_col_get_value(read_tuple, 1);
1094
  message_len= ib_col_get_meta(read_tuple, 1, &col_meta);
1095
1096
  if (table_message.ParseFromArray(message, message_len) == false)
1097
    goto rollback;
1098
1099
  table_message.set_name(to_identifier.getTableName());
1100
  table_message.set_schema(to_identifier.getSchemaName());
1101
1283.28.2 by Stewart Smith
add basic RENAME TABLE support for Embedded InnoDB. Also add a basic test, and copy over the rename.test test and run it against embedded innodb.
1102
  update_tuple= ib_clust_read_tuple_create(cursor);
1103
1104
  err= ib_tuple_copy(update_tuple, read_tuple);
1105
  assert(err == DB_SUCCESS);
1106
1107
  err= ib_col_set_value(update_tuple, 0, to, strlen(to));
1283.30.12 by Stewart Smith
fix rename table for new prototype as well as that table names are read from the proto instead of from getTableNames, which means on rename we must read the table proto, modify ita nd then store it again.
1108
1109
  table_message.SerializeToString(&serialized_message);
1110
1111
  err= ib_col_set_value(update_tuple, 1, serialized_message.c_str(),
1112
                        serialized_message.length());
1113
1283.28.2 by Stewart Smith
add basic RENAME TABLE support for Embedded InnoDB. Also add a basic test, and copy over the rename.test test and run it against embedded innodb.
1114
  err= ib_cursor_update_row(cursor, read_tuple, update_tuple);
1115
1116
1117
  ib_tuple_delete(update_tuple);
1118
  ib_tuple_delete(read_tuple);
1119
  ib_tuple_delete(search_tuple);
1120
1121
  err= ib_cursor_close(cursor);
1122
1123
rollback:
1124
  return err;
1125
}
1126
1283.30.12 by Stewart Smith
fix rename table for new prototype as well as that table names are read from the proto instead of from getTableNames, which means on rename we must read the table proto, modify ita nd then store it again.
1127
int EmbeddedInnoDBEngine::doRenameTable(drizzled::Session &session,
1128
                                        drizzled::TableIdentifier &from,
1129
                                        drizzled::TableIdentifier &to)
1283.28.2 by Stewart Smith
add basic RENAME TABLE support for Embedded InnoDB. Also add a basic test, and copy over the rename.test test and run it against embedded innodb.
1130
{
1131
  ib_trx_t innodb_schema_transaction;
1132
  ib_err_t err;
1283.30.12 by Stewart Smith
fix rename table for new prototype as well as that table names are read from the proto instead of from getTableNames, which means on rename we must read the table proto, modify ita nd then store it again.
1133
  string from_innodb_table_name;
1134
  string to_innodb_table_name;
1135
1136
  TableIdentifier_to_innodb_name(from, &from_innodb_table_name);
1137
  TableIdentifier_to_innodb_name(to, &to_innodb_table_name);
1283.28.2 by Stewart Smith
add basic RENAME TABLE support for Embedded InnoDB. Also add a basic test, and copy over the rename.test test and run it against embedded innodb.
1138
1139
  innodb_schema_transaction= ib_trx_begin(IB_TRX_REPEATABLE_READ);
1140
  err= ib_schema_lock_exclusive(innodb_schema_transaction);
1141
  if (err != DB_SUCCESS)
1142
  {
1283.30.12 by Stewart Smith
fix rename table for new prototype as well as that table names are read from the proto instead of from getTableNames, which means on rename we must read the table proto, modify ita nd then store it again.
1143
    push_warning_printf(&session, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
1283.28.2 by Stewart Smith
add basic RENAME TABLE support for Embedded InnoDB. Also add a basic test, and copy over the rename.test test and run it against embedded innodb.
1144
                        ER_CANT_DELETE_FILE,
1145
                        _("Cannot Lock Embedded InnoDB Data Dictionary. InnoDB Error %d (%s)\n"),
1146
                        err, ib_strerror(err));
1147
1148
    goto rollback;
1149
  }
1150
1151
  err= ib_table_rename(innodb_schema_transaction,
1283.30.12 by Stewart Smith
fix rename table for new prototype as well as that table names are read from the proto instead of from getTableNames, which means on rename we must read the table proto, modify ita nd then store it again.
1152
                       from_innodb_table_name.c_str(),
1153
                       to_innodb_table_name.c_str());
1283.28.2 by Stewart Smith
add basic RENAME TABLE support for Embedded InnoDB. Also add a basic test, and copy over the rename.test test and run it against embedded innodb.
1154
  if (err != DB_SUCCESS)
1155
    goto rollback;
1156
1283.30.12 by Stewart Smith
fix rename table for new prototype as well as that table names are read from the proto instead of from getTableNames, which means on rename we must read the table proto, modify ita nd then store it again.
1157
  err= rename_table_message(innodb_schema_transaction, from, to);
1158
1283.28.2 by Stewart Smith
add basic RENAME TABLE support for Embedded InnoDB. Also add a basic test, and copy over the rename.test test and run it against embedded innodb.
1159
  if (err != DB_SUCCESS)
1160
    goto rollback;
1161
1162
  err= ib_trx_commit(innodb_schema_transaction);
1163
  if (err != DB_SUCCESS)
1164
    goto rollback;
1165
1166
  return 0;
1167
rollback:
1168
  ib_err_t rollback_err= ib_schema_unlock(innodb_schema_transaction);
1169
  assert(rollback_err == DB_SUCCESS);
1170
  rollback_err= ib_trx_rollback(innodb_schema_transaction);
1171
  assert(rollback_err == DB_SUCCESS);
1172
  return -1;
1173
}
1174
1283.16.32 by Stewart Smith
implement both doGetTableNames and doGetTableIdentifiers through a common function
1175
void EmbeddedInnoDBEngine::getTableNamesInSchemaFromInnoDB(
1176
                                 drizzled::SchemaIdentifier &schema,
1177
                                 drizzled::plugin::TableNameList *set_of_names,
1178
                                 drizzled::TableIdentifiers *identifiers)
1283.3.24 by Stewart Smith
add SHOW TABLES support to embedded innodb engine
1179
{
1180
  ib_trx_t   transaction;
1181
  ib_crsr_t  cursor;
1283.16.30 by Stewart Smith
merge trunk
1182
  string search_string(schema.getLower());
1283.3.24 by Stewart Smith
add SHOW TABLES support to embedded innodb engine
1183
1184
  search_string.append("/");
1185
1186
  transaction = ib_trx_begin(IB_TRX_REPEATABLE_READ);
1283.16.18 by Stewart Smith
check error codse in doGetTableNames for embedded innodb
1187
  ib_err_t innodb_err= ib_schema_lock_exclusive(transaction);
1188
  assert(innodb_err == DB_SUCCESS); /* FIXME: doGetTableNames needs to be able to return error */
1189
1190
1191
  innodb_err= ib_cursor_open_table("SYS_TABLES", transaction, &cursor);
1192
  assert(innodb_err == DB_SUCCESS); /* FIXME */
1193
1283.3.24 by Stewart Smith
add SHOW TABLES support to embedded innodb engine
1194
  ib_tpl_t read_tuple;
1283.16.19 by Stewart Smith
use search tuple in doGetTableNames to scan SYS_TABLES using an index read instead of full table scan.
1195
  ib_tpl_t search_tuple;
1283.3.24 by Stewart Smith
add SHOW TABLES support to embedded innodb engine
1196
1197
  read_tuple= ib_clust_read_tuple_create(cursor);
1283.16.19 by Stewart Smith
use search tuple in doGetTableNames to scan SYS_TABLES using an index read instead of full table scan.
1198
  search_tuple= ib_clust_search_tuple_create(cursor);
1199
1200
  innodb_err= ib_col_set_value(search_tuple, 0, search_string.c_str(),
1201
                               search_string.length());
1202
  assert (innodb_err == DB_SUCCESS); // FIXME
1203
1204
  int res;
1205
  innodb_err = ib_cursor_moveto(cursor, search_tuple, IB_CUR_GE, &res);
1206
  // fixme: check error above
1283.3.24 by Stewart Smith
add SHOW TABLES support to embedded innodb engine
1207
1283.16.18 by Stewart Smith
check error codse in doGetTableNames for embedded innodb
1208
  while (innodb_err == DB_SUCCESS)
1283.3.24 by Stewart Smith
add SHOW TABLES support to embedded innodb engine
1209
  {
1283.16.18 by Stewart Smith
check error codse in doGetTableNames for embedded innodb
1210
    innodb_err= ib_cursor_read_row(cursor, read_tuple);
1283.3.24 by Stewart Smith
add SHOW TABLES support to embedded innodb engine
1211
1212
    const char *table_name;
1213
    int table_name_len;
1214
    ib_col_meta_t column_metadata;
1215
1216
    table_name= (const char*)ib_col_get_value(read_tuple, 0);
1217
    table_name_len=  ib_col_get_meta(read_tuple, 0, &column_metadata);
1218
1219
    if (search_string.compare(0, search_string.length(),
1220
                              table_name, search_string.length()) == 0)
1221
    {
1222
      const char *just_table_name= strchr(table_name, '/');
1223
      assert(just_table_name);
1224
      just_table_name++; /* skip over '/' */
1283.16.32 by Stewart Smith
implement both doGetTableNames and doGetTableIdentifiers through a common function
1225
      if (set_of_names)
1226
        set_of_names->insert(just_table_name);
1227
      if (identifiers)
1228
        identifiers->push_back(TableIdentifier(schema.getLower(), just_table_name));
1283.3.24 by Stewart Smith
add SHOW TABLES support to embedded innodb engine
1229
    }
1230
1231
1283.16.18 by Stewart Smith
check error codse in doGetTableNames for embedded innodb
1232
    innodb_err= ib_cursor_next(cursor);
1283.3.24 by Stewart Smith
add SHOW TABLES support to embedded innodb engine
1233
    read_tuple= ib_tuple_clear(read_tuple);
1234
  }
1235
1236
  ib_tuple_delete(read_tuple);
1283.16.19 by Stewart Smith
use search tuple in doGetTableNames to scan SYS_TABLES using an index read instead of full table scan.
1237
  ib_tuple_delete(search_tuple);
1283.3.24 by Stewart Smith
add SHOW TABLES support to embedded innodb engine
1238
1283.16.18 by Stewart Smith
check error codse in doGetTableNames for embedded innodb
1239
  innodb_err= ib_cursor_close(cursor);
1240
  assert(innodb_err == DB_SUCCESS); // FIXME
1283.3.24 by Stewart Smith
add SHOW TABLES support to embedded innodb engine
1241
1283.16.18 by Stewart Smith
check error codse in doGetTableNames for embedded innodb
1242
  innodb_err= ib_trx_commit(transaction);
1243
  assert(innodb_err == DB_SUCCESS); // FIXME
1283.3.24 by Stewart Smith
add SHOW TABLES support to embedded innodb engine
1244
}
1245
1283.16.32 by Stewart Smith
implement both doGetTableNames and doGetTableIdentifiers through a common function
1246
void EmbeddedInnoDBEngine::doGetTableNames(drizzled::CachedDirectory &,
1247
                                           drizzled::SchemaIdentifier &schema,
1248
                                           drizzled::plugin::TableNameList &set_of_names)
1249
{
1250
  getTableNamesInSchemaFromInnoDB(schema, &set_of_names, NULL);
1251
}
1252
1253
void EmbeddedInnoDBEngine::doGetTableIdentifiers(drizzled::CachedDirectory &,
1254
                                                 drizzled::SchemaIdentifier &schema,
1255
                                                 drizzled::TableIdentifiers &identifiers)
1256
{
1257
  getTableNamesInSchemaFromInnoDB(schema, NULL, &identifiers);
1258
}
1259
1283.17.11 by Stewart Smith
change data_dictionary.innodb_table_proto to data_dictionary.innodb_table_definition
1260
static int read_table_message_from_innodb(const char* table_name, drizzled::message::Table *table_message)
1283.3.26 by Stewart Smith
basic store/read/delete table proto from embedded innodb table. This makes CREATE TABLE 100% crash safe. This also makes SHOW CREATE TABLE work for embedded innodb tables.
1261
{
1262
  ib_trx_t transaction;
1263
  ib_tpl_t search_tuple;
1264
  ib_tpl_t read_tuple;
1265
  ib_crsr_t cursor;
1283.17.11 by Stewart Smith
change data_dictionary.innodb_table_proto to data_dictionary.innodb_table_definition
1266
  const char *message;
1267
  ib_ulint_t message_len;
1283.3.26 by Stewart Smith
basic store/read/delete table proto from embedded innodb table. This makes CREATE TABLE 100% crash safe. This also makes SHOW CREATE TABLE work for embedded innodb tables.
1268
  ib_col_meta_t col_meta;
1269
  int res;
1270
  ib_err_t err;
1283.19.28 by Stewart Smith
fixup error checking
1271
  ib_err_t rollback_err;
1283.3.26 by Stewart Smith
basic store/read/delete table proto from embedded innodb table. This makes CREATE TABLE 100% crash safe. This also makes SHOW CREATE TABLE work for embedded innodb tables.
1272
1273
  transaction= ib_trx_begin(IB_TRX_REPEATABLE_READ);
1283.19.28 by Stewart Smith
fixup error checking
1274
  err= ib_schema_lock_exclusive(transaction);
1275
  if (err != DB_SUCCESS)
1276
  {
1277
    rollback_err= ib_trx_rollback(transaction);
1278
    assert(rollback_err == DB_SUCCESS);
1279
    return err;
1280
  }
1281
1282
  err= ib_cursor_open_table(INNODB_TABLE_DEFINITIONS_TABLE, transaction, &cursor);
1283
  if (err != DB_SUCCESS)
1284
  {
1285
    rollback_err= ib_trx_rollback(transaction);
1286
    assert(rollback_err == DB_SUCCESS);
1287
    return err;
1288
  }
1289
1283.3.26 by Stewart Smith
basic store/read/delete table proto from embedded innodb table. This makes CREATE TABLE 100% crash safe. This also makes SHOW CREATE TABLE work for embedded innodb tables.
1290
  search_tuple= ib_clust_search_tuple_create(cursor);
1283.17.5 by Stewart Smith
generate a basic table proto for data_dictionary/innodb_table_proto system table.
1291
  read_tuple= ib_clust_read_tuple_create(cursor);
1283.3.26 by Stewart Smith
basic store/read/delete table proto from embedded innodb table. This makes CREATE TABLE 100% crash safe. This also makes SHOW CREATE TABLE work for embedded innodb tables.
1292
1283.19.28 by Stewart Smith
fixup error checking
1293
  err= ib_col_set_value(search_tuple, 0, table_name, strlen(table_name));
1294
  if (err != DB_SUCCESS)
1295
    goto rollback;
1283.3.26 by Stewart Smith
basic store/read/delete table proto from embedded innodb table. This makes CREATE TABLE 100% crash safe. This also makes SHOW CREATE TABLE work for embedded innodb tables.
1296
1297
//  ib_cursor_set_match_mode(cursor, IB_EXACT_MATCH);
1298
1299
  err= ib_cursor_moveto(cursor, search_tuple, IB_CUR_GE, &res);
1300
  if (err == DB_RECORD_NOT_FOUND || res != 0)
1301
    goto rollback;
1302
1303
  err= ib_cursor_read_row(cursor, read_tuple);
1304
  if (err == DB_RECORD_NOT_FOUND || res != 0)
1305
    goto rollback;
1306
1283.17.11 by Stewart Smith
change data_dictionary.innodb_table_proto to data_dictionary.innodb_table_definition
1307
  message= (const char*)ib_col_get_value(read_tuple, 1);
1308
  message_len= ib_col_get_meta(read_tuple, 1, &col_meta);
1283.3.26 by Stewart Smith
basic store/read/delete table proto from embedded innodb table. This makes CREATE TABLE 100% crash safe. This also makes SHOW CREATE TABLE work for embedded innodb tables.
1309
1283.17.11 by Stewart Smith
change data_dictionary.innodb_table_proto to data_dictionary.innodb_table_definition
1310
  if (table_message->ParseFromArray(message, message_len) == false)
1283.3.26 by Stewart Smith
basic store/read/delete table proto from embedded innodb table. This makes CREATE TABLE 100% crash safe. This also makes SHOW CREATE TABLE work for embedded innodb tables.
1311
    goto rollback;
1312
1313
  ib_tuple_delete(search_tuple);
1314
  ib_tuple_delete(read_tuple);
1283.19.28 by Stewart Smith
fixup error checking
1315
  err= ib_cursor_close(cursor);
1316
  if (err != DB_SUCCESS)
1317
    goto rollback_close_err;
1318
  err= ib_trx_commit(transaction);
1319
  if (err != DB_SUCCESS)
1320
    goto rollback_close_err;
1283.3.26 by Stewart Smith
basic store/read/delete table proto from embedded innodb table. This makes CREATE TABLE 100% crash safe. This also makes SHOW CREATE TABLE work for embedded innodb tables.
1321
1322
  return 0;
1323
1324
rollback:
1283.17.5 by Stewart Smith
generate a basic table proto for data_dictionary/innodb_table_proto system table.
1325
  ib_tuple_delete(search_tuple);
1326
  ib_tuple_delete(read_tuple);
1283.19.28 by Stewart Smith
fixup error checking
1327
  rollback_err= ib_cursor_close(cursor);
1328
  assert(rollback_err == DB_SUCCESS);
1329
rollback_close_err:
1283.3.26 by Stewart Smith
basic store/read/delete table proto from embedded innodb table. This makes CREATE TABLE 100% crash safe. This also makes SHOW CREATE TABLE work for embedded innodb tables.
1330
  ib_schema_unlock(transaction);
1283.19.28 by Stewart Smith
fixup error checking
1331
  rollback_err= ib_trx_rollback(transaction);
1332
  assert(rollback_err == DB_SUCCESS);
1283.17.5 by Stewart Smith
generate a basic table proto for data_dictionary/innodb_table_proto system table.
1333
1283.17.12 by Stewart Smith
use define to set the name of the innodb_table_definitions table instead of repeating it 5 times through the code
1334
  if (strcmp(table_name, INNODB_TABLE_DEFINITIONS_TABLE) == 0)
1283.17.5 by Stewart Smith
generate a basic table proto for data_dictionary/innodb_table_proto system table.
1335
  {
1475.2.9 by Stewart Smith
fix many compile failures that people introduced in embedded_innodb because it's not built by default.. i.e. plugin=disabled is EPIC FAIL
1336
    message::Engine *engine= table_message->mutable_engine();
1283.17.5 by Stewart Smith
generate a basic table proto for data_dictionary/innodb_table_proto system table.
1337
    engine->set_name("InnoDB");
1283.17.29 by Stewart Smith
store (bogus) values for creation_timestamp and update_timestamp in the table proto for data_dictionary.innodb_table_definitions
1338
    table_message->set_name("innodb_table_definitions");
1283.17.31 by Stewart Smith
fix up store/read table message for TableIdentifier
1339
    table_message->set_schema("data_dictionary");
1283.17.5 by Stewart Smith
generate a basic table proto for data_dictionary/innodb_table_proto system table.
1340
    table_message->set_type(message::Table::STANDARD);
1283.17.29 by Stewart Smith
store (bogus) values for creation_timestamp and update_timestamp in the table proto for data_dictionary.innodb_table_definitions
1341
    table_message->set_creation_timestamp(0);
1342
    table_message->set_update_timestamp(0);
1283.17.5 by Stewart Smith
generate a basic table proto for data_dictionary/innodb_table_proto system table.
1343
1283.17.26 by Stewart Smith
fix up table message table proto for collation to always be binary.
1344
    message::Table::TableOptions *options= table_message->mutable_options();
1345
    options->set_collation_id(my_charset_bin.number);
1346
    options->set_collation(my_charset_bin.name);
1347
1283.17.5 by Stewart Smith
generate a basic table proto for data_dictionary/innodb_table_proto system table.
1348
    message::Table::Field *field= table_message->add_field();
1349
    field->set_name("table_name");
1350
    field->set_type(message::Table::Field::VARCHAR);
1351
    message::Table::Field::StringFieldOptions *stropt= field->mutable_string_options();
1352
    stropt->set_length(IB_MAX_TABLE_NAME_LEN);
1283.19.2 by Stewart Smith
read the count of the number of tables in the data_dictionary/innodb_table_proto table. Currently don't report the existence of an index on the table as we don't have index scan yet
1353
    stropt->set_collation_id(my_charset_bin.number);
1283.17.26 by Stewart Smith
fix up table message table proto for collation to always be binary.
1354
    stropt->set_collation(my_charset_bin.name);
1283.17.5 by Stewart Smith
generate a basic table proto for data_dictionary/innodb_table_proto system table.
1355
1356
    field= table_message->add_field();
1283.17.11 by Stewart Smith
change data_dictionary.innodb_table_proto to data_dictionary.innodb_table_definition
1357
    field->set_name("message");
1283.17.5 by Stewart Smith
generate a basic table proto for data_dictionary/innodb_table_proto system table.
1358
    field->set_type(message::Table::Field::BLOB);
1283.17.26 by Stewart Smith
fix up table message table proto for collation to always be binary.
1359
    stropt= field->mutable_string_options();
1360
    stropt->set_collation_id(my_charset_bin.number);
1361
    stropt->set_collation(my_charset_bin.name);
1283.17.5 by Stewart Smith
generate a basic table proto for data_dictionary/innodb_table_proto system table.
1362
1363
    message::Table::Index *index= table_message->add_indexes();
1364
    index->set_name("PRIMARY");
1365
    index->set_is_primary(true);
1366
    index->set_is_unique(true);
1367
    index->set_type(message::Table::Index::BTREE);
1368
    index->set_key_length(IB_MAX_TABLE_NAME_LEN);
1369
    message::Table::Index::IndexPart *part= index->add_index_part();
1370
    part->set_fieldnr(0);
1371
    part->set_compare_length(IB_MAX_TABLE_NAME_LEN);
1283.3.48 by Stewart Smith
since index reads work, we can expose the primary key of data_dictionary.innodb_table_proto to the sql server.
1372
1283.17.5 by Stewart Smith
generate a basic table proto for data_dictionary/innodb_table_proto system table.
1373
    return 0;
1374
  }
1283.3.26 by Stewart Smith
basic store/read/delete table proto from embedded innodb table. This makes CREATE TABLE 100% crash safe. This also makes SHOW CREATE TABLE work for embedded innodb tables.
1375
1376
  return -1;
1377
}
1378
1283.3.1 by Stewart Smith
Skeleton embedded_innodb plugin. Does nothing.
1379
int EmbeddedInnoDBEngine::doGetTableDefinition(Session&,
1283.14.19 by Stewart Smith
fix up table exists for new bits of storage engine API r.e. TableIdentifier
1380
                                               TableIdentifier &identifier,
1381
                                               drizzled::message::Table &table)
1283.3.1 by Stewart Smith
Skeleton embedded_innodb plugin. Does nothing.
1382
{
1283.3.22 by Stewart Smith
to really work with drop table, doGetTableDefinition must fill out the Engine part of the protobuf.
1383
  ib_crsr_t innodb_cursor= NULL;
1283.14.19 by Stewart Smith
fix up table exists for new bits of storage engine API r.e. TableIdentifier
1384
  string innodb_table_name;
1385
1386
  TableIdentifier_to_innodb_name(identifier, &innodb_table_name);
1387
1388
  if (ib_cursor_open_table(innodb_table_name.c_str(), NULL, &innodb_cursor) != DB_SUCCESS)
1283.3.20 by Stewart Smith
*really* simple embeddded_innodb check if a table exists in doGetTableDefinition.
1389
    return ENOENT;
1390
1283.17.21 by Stewart Smith
fix up ib_cursor_close() error checking in doGetTableDefinition
1391
  ib_err_t err= ib_cursor_close(innodb_cursor);
1392
1393
  assert (err == DB_SUCCESS);
1283.3.20 by Stewart Smith
*really* simple embeddded_innodb check if a table exists in doGetTableDefinition.
1394
1283.17.31 by Stewart Smith
fix up store/read table message for TableIdentifier
1395
  read_table_message_from_innodb(innodb_table_name.c_str(), &table);
1283.3.22 by Stewart Smith
to really work with drop table, doGetTableDefinition must fill out the Engine part of the protobuf.
1396
1283.3.20 by Stewart Smith
*really* simple embeddded_innodb check if a table exists in doGetTableDefinition.
1397
  return EEXIST;
1283.3.1 by Stewart Smith
Skeleton embedded_innodb plugin. Does nothing.
1398
}
1399
1283.14.19 by Stewart Smith
fix up table exists for new bits of storage engine API r.e. TableIdentifier
1400
bool EmbeddedInnoDBEngine::doDoesTableExist(Session &,
1401
                                            TableIdentifier& identifier)
1283.11.19 by Stewart Smith
fix up create table for new bits of storage engine API r.e. TableIdentifier
1402
{
1283.14.19 by Stewart Smith
fix up table exists for new bits of storage engine API r.e. TableIdentifier
1403
  ib_crsr_t innodb_cursor;
1404
  string innodb_table_name;
1405
1406
  TableIdentifier_to_innodb_name(identifier, &innodb_table_name);
1407
1408
  if (ib_cursor_open_table(innodb_table_name.c_str(), NULL, &innodb_cursor) != DB_SUCCESS)
1409
    return false;
1410
1411
  ib_err_t err= ib_cursor_close(innodb_cursor);
1412
  assert(err == DB_SUCCESS);
1413
1414
  return true;
1283.11.19 by Stewart Smith
fix up create table for new bits of storage engine API r.e. TableIdentifier
1415
}
1416
1283.3.1 by Stewart Smith
Skeleton embedded_innodb plugin. Does nothing.
1417
const char *EmbeddedInnoDBCursor::index_type(uint32_t)
1418
{
1419
  return("BTREE");
1420
}
1421
1283.28.1 by Stewart Smith
basic UPDATE row for Embedded InnoDB Engine.
1422
static ib_err_t write_row_to_innodb_tuple(Field **fields, ib_tpl_t tuple)
1283.3.1 by Stewart Smith
Skeleton embedded_innodb plugin. Does nothing.
1423
{
1283.28.1 by Stewart Smith
basic UPDATE row for Embedded InnoDB Engine.
1424
  int colnr= 0;
1539.1.2 by Brian Aker
Fix Hades build error.
1425
  ib_err_t err= DB_ERROR;
1283.28.1 by Stewart Smith
basic UPDATE row for Embedded InnoDB Engine.
1426
1427
  for (Field **field= fields; *field; field++, colnr++)
1283.3.27 by Stewart Smith
basic code to insert a integer
1428
  {
1283.39.11 by Stewart Smith
fix write_row_to_innodb_tuple for proper WriteSet behaviour. oh my the API is bonghits.
1429
    if (! (**field).isWriteSet() && (**field).is_null())
1430
      continue;
1431
1283.12.31 by Stewart Smith
fix storing of NULL in embedded innodb. Need to explicitly set column value to IB_SQL_NULL
1432
    if ((**field).is_null())
1433
    {
1434
      err= ib_col_set_value(tuple, colnr, NULL, IB_SQL_NULL);
1435
      assert(err == DB_SUCCESS);
1436
      continue;
1437
    }
1438
1283.12.7 by Stewart Smith
store VARCHAR columns correctly. Don't store the length bytes. instead use and abuse Field_varstring::val_str() to get the length and pointer to data to tell innodb.
1439
    if ((**field).type() == DRIZZLE_TYPE_VARCHAR)
1440
    {
1441
      /* To get around the length bytes (1 or 2) at (**field).ptr
1442
         we can use Field_varstring::val_str to a String
1443
         to get a pointer to the real string without copying it.
1444
      */
1445
      String str;
1446
      (**field).setReadSet();
1447
      (**field).val_str(&str);
1448
      err= ib_col_set_value(tuple, colnr, str.ptr(), str.length());
1449
    }
1283.35.27 by Stewart Smith
add ENUM SQL type support to Embedded InnoDB
1450
    else if ((**field).type() == DRIZZLE_TYPE_ENUM)
1451
    {
1452
      if ((*field)->data_length() == 1)
1453
        err= ib_tuple_write_u8(tuple, colnr, *((ib_u8_t*)(*field)->ptr));
1454
      else if ((*field)->data_length() == 2)
1455
        err= ib_tuple_write_u16(tuple, colnr, *((ib_u16_t*)(*field)->ptr));
1456
      else
1457
      {
1458
        assert((*field)->data_length() <= 2);
1459
      }
1460
    }
1283.35.45 by Stewart Smith
enable DATE type for embedded_innodb.
1461
    else if ((**field).type() == DRIZZLE_TYPE_DATE)
1462
    {
1463
      (**field).setReadSet();
1464
      err= ib_tuple_write_u32(tuple, colnr, (*field)->val_int());
1465
    }
1283.60.5 by Stewart Smith
add BLOB support to embedded_innodb along with a simple test.
1466
    else if ((**field).type() == DRIZZLE_TYPE_BLOB)
1467
    {
1468
      Field_blob *blob= reinterpret_cast<Field_blob*>(*field);
1469
      unsigned char* blob_ptr;
1470
      uint32_t blob_length= blob->get_length();
1471
      blob->get_ptr(&blob_ptr);
1472
      err= ib_col_set_value(tuple, colnr, blob_ptr, blob_length);
1473
    }
1283.12.7 by Stewart Smith
store VARCHAR columns correctly. Don't store the length bytes. instead use and abuse Field_varstring::val_str() to get the length and pointer to data to tell innodb.
1474
    else
1475
    {
1476
      err= ib_col_set_value(tuple, colnr, (*field)->ptr, (*field)->data_length());
1477
    }
1478
1283.12.15 by Stewart Smith
style fixups: == and spaces
1479
    assert (err == DB_SUCCESS);
1283.3.27 by Stewart Smith
basic code to insert a integer
1480
  }
1481
1283.28.1 by Stewart Smith
basic UPDATE row for Embedded InnoDB Engine.
1482
  return err;
1483
}
1484
1283.37.4 by Stewart Smith
fix embedded_innodb auto_increment for negative values (just strange really).
1485
static uint64_t innobase_get_int_col_max_value(const Field* field)
1486
{
1487
  uint64_t	max_value = 0;
1488
1489
  switch(field->key_type()) {
1490
    /* TINY */
1491
  case HA_KEYTYPE_BINARY:
1492
    max_value = 0xFFULL;
1493
    break;
1494
    /* MEDIUM */
1495
  case HA_KEYTYPE_UINT24:
1496
    max_value = 0xFFFFFFULL;
1497
    break;
1498
    /* LONG */
1499
  case HA_KEYTYPE_ULONG_INT:
1500
    max_value = 0xFFFFFFFFULL;
1501
    break;
1502
  case HA_KEYTYPE_LONG_INT:
1503
    max_value = 0x7FFFFFFFULL;
1504
    break;
1505
    /* BIG */
1506
  case HA_KEYTYPE_ULONGLONG:
1507
    max_value = 0xFFFFFFFFFFFFFFFFULL;
1508
    break;
1509
  case HA_KEYTYPE_LONGLONG:
1510
    max_value = 0x7FFFFFFFFFFFFFFFULL;
1511
    break;
1512
  case HA_KEYTYPE_DOUBLE:
1513
    /* We use the maximum as per IEEE754-2008 standard, 2^53 */
1514
    max_value = 0x20000000000000ULL;
1515
    break;
1516
  default:
1517
    assert(false);
1518
  }
1519
1520
  return(max_value);
1521
}
1522
1283.39.8 by Stewart Smith
add support for REPLACE to embedded_innodb. On duplicate key on insert if we have HA_EXTRA_WRITE_CAN_REPLACE set, then we delete the row and insert.
1523
int EmbeddedInnoDBCursor::doInsertRecord(unsigned char *record)
1283.28.1 by Stewart Smith
basic UPDATE row for Embedded InnoDB Engine.
1524
{
1283.36.13 by Stewart Smith
basic auto_increment implementation for embedded_innodb. On startup, fetch the maximum value for the auto_increment column (or what's in the table message as the auto_increment value). Use an atomic variable in the embedded-innodb table share to keep track of the auto_increment_value. We can then use atomic ops to get an autoinc value (or several) as well as update it in the event of inserting a larger number. Currently there's a bug (well, difference in behaviour) around inserting -1 into an auto-inc field where the table already has a value 'higher' than that and then asking for another auto-inc value. Check the auto_increment test case failure for it. This will be fixed in a later commit.
1525
  ib_err_t err;
1526
  int ret= 0;
1527
1528
  ib_trx_t transaction= *get_trx(ha_session());
1529
1530
  tuple= ib_clust_read_tuple_create(cursor);
1531
1532
  ib_cursor_attach_trx(cursor, transaction);
1533
1534
  err= ib_cursor_first(cursor);
1283.36.24 by Stewart Smith
fix CREATE SELECT for Embedded Innodb. Special case of DB_MISSING_HISTORY due to transaction started before destination table exists.
1535
  if (current_session->lex->sql_command == SQLCOM_CREATE_TABLE
1536
      && err == DB_MISSING_HISTORY)
1537
  {
1538
    /* See https://bugs.launchpad.net/drizzle/+bug/556978
1539
     *
1540
     * In CREATE SELECT, transaction is started in ::store_lock
1541
     * at the start of the statement, before the table is created.
1542
     * This means the table doesn't exist in our snapshot,
1543
     * and we get a DB_MISSING_HISTORY error on ib_cursor_first().
1544
     * The way to get around this is to here, restart the transaction
1545
     * and continue.
1546
     *
1547
     * yuck.
1548
     */
1549
1550
    EmbeddedInnoDBEngine *innodb_engine= static_cast<EmbeddedInnoDBEngine*>(engine);
1551
    err= ib_cursor_reset(cursor);
1552
    innodb_engine->doCommit(current_session, true);
1553
    innodb_engine->doStartTransaction(current_session, START_TRANS_NO_OPTIONS);
1554
    transaction= *get_trx(ha_session());
1555
    assert(err == DB_SUCCESS);
1556
    ib_cursor_attach_trx(cursor, transaction);
1557
    err= ib_cursor_first(cursor);
1558
  }
1559
1283.36.13 by Stewart Smith
basic auto_increment implementation for embedded_innodb. On startup, fetch the maximum value for the auto_increment column (or what's in the table message as the auto_increment value). Use an atomic variable in the embedded-innodb table share to keep track of the auto_increment_value. We can then use atomic ops to get an autoinc value (or several) as well as update it in the event of inserting a larger number. Currently there's a bug (well, difference in behaviour) around inserting -1 into an auto-inc field where the table already has a value 'higher' than that and then asking for another auto-inc value. Check the auto_increment test case failure for it. This will be fixed in a later commit.
1560
  assert(err == DB_SUCCESS || err == DB_END_OF_INDEX);
1561
1562
1283.28.1 by Stewart Smith
basic UPDATE row for Embedded InnoDB Engine.
1563
  if (table->next_number_field)
1283.36.13 by Stewart Smith
basic auto_increment implementation for embedded_innodb. On startup, fetch the maximum value for the auto_increment column (or what's in the table message as the auto_increment value). Use an atomic variable in the embedded-innodb table share to keep track of the auto_increment_value. We can then use atomic ops to get an autoinc value (or several) as well as update it in the event of inserting a larger number. Currently there's a bug (well, difference in behaviour) around inserting -1 into an auto-inc field where the table already has a value 'higher' than that and then asking for another auto-inc value. Check the auto_increment test case failure for it. This will be fixed in a later commit.
1564
  {
1283.28.1 by Stewart Smith
basic UPDATE row for Embedded InnoDB Engine.
1565
    update_auto_increment();
1566
1283.36.13 by Stewart Smith
basic auto_increment implementation for embedded_innodb. On startup, fetch the maximum value for the auto_increment column (or what's in the table message as the auto_increment value). Use an atomic variable in the embedded-innodb table share to keep track of the auto_increment_value. We can then use atomic ops to get an autoinc value (or several) as well as update it in the event of inserting a larger number. Currently there's a bug (well, difference in behaviour) around inserting -1 into an auto-inc field where the table already has a value 'higher' than that and then asking for another auto-inc value. Check the auto_increment test case failure for it. This will be fixed in a later commit.
1567
    uint64_t temp_auto= table->next_number_field->val_int();
1568
1283.37.4 by Stewart Smith
fix embedded_innodb auto_increment for negative values (just strange really).
1569
    if (temp_auto <= innobase_get_int_col_max_value(table->next_number_field))
1283.36.13 by Stewart Smith
basic auto_increment implementation for embedded_innodb. On startup, fetch the maximum value for the auto_increment column (or what's in the table message as the auto_increment value). Use an atomic variable in the embedded-innodb table share to keep track of the auto_increment_value. We can then use atomic ops to get an autoinc value (or several) as well as update it in the event of inserting a larger number. Currently there's a bug (well, difference in behaviour) around inserting -1 into an auto-inc field where the table already has a value 'higher' than that and then asking for another auto-inc value. Check the auto_increment test case failure for it. This will be fixed in a later commit.
1570
    {
1283.37.4 by Stewart Smith
fix embedded_innodb auto_increment for negative values (just strange really).
1571
      while (true)
1283.36.13 by Stewart Smith
basic auto_increment implementation for embedded_innodb. On startup, fetch the maximum value for the auto_increment column (or what's in the table message as the auto_increment value). Use an atomic variable in the embedded-innodb table share to keep track of the auto_increment_value. We can then use atomic ops to get an autoinc value (or several) as well as update it in the event of inserting a larger number. Currently there's a bug (well, difference in behaviour) around inserting -1 into an auto-inc field where the table already has a value 'higher' than that and then asking for another auto-inc value. Check the auto_increment test case failure for it. This will be fixed in a later commit.
1572
      {
1283.37.4 by Stewart Smith
fix embedded_innodb auto_increment for negative values (just strange really).
1573
        uint64_t fetched_auto= share->auto_increment_value;
1574
1575
        if (temp_auto >= fetched_auto)
1576
        {
1577
          uint64_t store_value= temp_auto+1;
1578
          if (store_value == 0)
1579
            store_value++;
1580
1581
          if (share->auto_increment_value.compare_and_swap(store_value, fetched_auto) == fetched_auto)
1582
            break;
1583
        }
1584
        else
1283.36.13 by Stewart Smith
basic auto_increment implementation for embedded_innodb. On startup, fetch the maximum value for the auto_increment column (or what's in the table message as the auto_increment value). Use an atomic variable in the embedded-innodb table share to keep track of the auto_increment_value. We can then use atomic ops to get an autoinc value (or several) as well as update it in the event of inserting a larger number. Currently there's a bug (well, difference in behaviour) around inserting -1 into an auto-inc field where the table already has a value 'higher' than that and then asking for another auto-inc value. Check the auto_increment test case failure for it. This will be fixed in a later commit.
1585
          break;
1586
      }
1587
    }
1588
1589
  }
1283.28.1 by Stewart Smith
basic UPDATE row for Embedded InnoDB Engine.
1590
1591
  write_row_to_innodb_tuple(table->field, tuple);
1592
1283.35.97 by Stewart Smith
support tables without an explicit primary key in embedded_innodb by creating a hidden auto_increment primary key. We also have to support tables without an explicit primary key but with an auto increment, so we have our own hidden one. yes, it hurts.
1593
  if (share->has_hidden_primary_key)
1594
  {
1532.1.15 by Brian Aker
Partial encapsulation of TableShare from Table.
1595
    err= ib_tuple_write_u64(tuple, table->getShare()->fields, share->hidden_pkey_auto_increment_value.fetch_and_increment());
1283.35.97 by Stewart Smith
support tables without an explicit primary key in embedded_innodb by creating a hidden auto_increment primary key. We also have to support tables without an explicit primary key but with an auto increment, so we have our own hidden one. yes, it hurts.
1596
  }
1597
1283.3.27 by Stewart Smith
basic code to insert a integer
1598
  err= ib_cursor_insert_row(cursor, tuple);
1283.3.39 by Stewart Smith
return HA_ERR_FOUND_DUPP_KEY on duplicate key error from embedded innodb.
1599
1600
  if (err == DB_DUPLICATE_KEY)
1283.39.8 by Stewart Smith
add support for REPLACE to embedded_innodb. On duplicate key on insert if we have HA_EXTRA_WRITE_CAN_REPLACE set, then we delete the row and insert.
1601
  {
1602
    if (write_can_replace)
1603
    {
1532.1.15 by Brian Aker
Partial encapsulation of TableShare from Table.
1604
      store_key_value_from_innodb(table->key_info + table->getShare()->primary_key,
1283.39.8 by Stewart Smith
add support for REPLACE to embedded_innodb. On duplicate key on insert if we have HA_EXTRA_WRITE_CAN_REPLACE set, then we delete the row and insert.
1605
                                  ref, ref_length, record);
1606
1607
      ib_tpl_t search_tuple= ib_clust_search_tuple_create(cursor);
1608
1609
      fill_ib_search_tpl_from_drizzle_key(search_tuple,
1610
                                          table->key_info + 0,
1611
                                          ref, ref_length);
1612
1613
      int res;
1614
      err= ib_cursor_moveto(cursor, search_tuple, IB_CUR_GE, &res);
1615
      assert(err == DB_SUCCESS);
1616
      ib_tuple_delete(search_tuple);
1617
1618
      tuple= ib_tuple_clear(tuple);
1619
      err= ib_cursor_delete_row(cursor);
1620
1621
      err= ib_cursor_first(cursor);
1622
      assert(err == DB_SUCCESS || err == DB_END_OF_INDEX);
1623
1624
      write_row_to_innodb_tuple(table->field, tuple);
1625
1626
      err= ib_cursor_insert_row(cursor, tuple);
1627
      assert(err==DB_SUCCESS); // probably be nice and process errors
1628
    }
1629
    else
1630
      ret= HA_ERR_FOUND_DUPP_KEY;
1631
  }
1283.35.97 by Stewart Smith
support tables without an explicit primary key in embedded_innodb by creating a hidden auto_increment primary key. We also have to support tables without an explicit primary key but with an auto increment, so we have our own hidden one. yes, it hurts.
1632
  else if (err != DB_SUCCESS)
1633
    ret= -1;
1283.3.27 by Stewart Smith
basic code to insert a integer
1634
1283.19.28 by Stewart Smith
fixup error checking
1635
  tuple= ib_tuple_clear(tuple);
1283.3.36 by Stewart Smith
'correctly' deal with transaction in an autocommit type way. this means queries like 'insert select' work as we're always in the correct transactional context.
1636
  ib_tuple_delete(tuple);
1283.19.28 by Stewart Smith
fixup error checking
1637
  err= ib_cursor_reset(cursor);
1283.3.27 by Stewart Smith
basic code to insert a integer
1638
1283.3.39 by Stewart Smith
return HA_ERR_FOUND_DUPP_KEY on duplicate key error from embedded innodb.
1639
  return ret;
1283.3.1 by Stewart Smith
Skeleton embedded_innodb plugin. Does nothing.
1640
}
1641
1283.39.11 by Stewart Smith
fix write_row_to_innodb_tuple for proper WriteSet behaviour. oh my the API is bonghits.
1642
int EmbeddedInnoDBCursor::doUpdateRecord(const unsigned char *,
1643
                                         unsigned char *)
1283.28.1 by Stewart Smith
basic UPDATE row for Embedded InnoDB Engine.
1644
{
1645
  ib_tpl_t update_tuple;
1646
  ib_err_t err;
1647
1648
  update_tuple= ib_clust_read_tuple_create(cursor);
1649
1650
  err= ib_tuple_copy(update_tuple, tuple);
1651
  assert(err == DB_SUCCESS);
1652
1283.35.40 by Stewart Smith
update timestamp column for ON UPDATE NOW() in embedded_innodb
1653
  if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE)
1654
    table->timestamp_field->set_time();
1655
1283.28.1 by Stewart Smith
basic UPDATE row for Embedded InnoDB Engine.
1656
  write_row_to_innodb_tuple(table->field, update_tuple);
1657
1658
  err= ib_cursor_update_row(cursor, tuple, update_tuple);
1659
1660
  ib_tuple_delete(update_tuple);
1283.60.4 by Stewart Smith
Change when we call ib_cursor_next/prev. Instead of calling it after reading
1661
1662
  advance_cursor= true;
1283.28.1 by Stewart Smith
basic UPDATE row for Embedded InnoDB Engine.
1663
1664
  if (err == DB_SUCCESS)
1665
    return 0;
1283.36.13 by Stewart Smith
basic auto_increment implementation for embedded_innodb. On startup, fetch the maximum value for the auto_increment column (or what's in the table message as the auto_increment value). Use an atomic variable in the embedded-innodb table share to keep track of the auto_increment_value. We can then use atomic ops to get an autoinc value (or several) as well as update it in the event of inserting a larger number. Currently there's a bug (well, difference in behaviour) around inserting -1 into an auto-inc field where the table already has a value 'higher' than that and then asking for another auto-inc value. Check the auto_increment test case failure for it. This will be fixed in a later commit.
1666
  else if (err == DB_DUPLICATE_KEY)
1667
    return HA_ERR_FOUND_DUPP_KEY;
1283.28.1 by Stewart Smith
basic UPDATE row for Embedded InnoDB Engine.
1668
  else
1669
    return -1;
1670
}
1671
1475.2.4 by Stewart Smith
fix update_record nad delete_record in embedded_innodb to be doUpdateRecord and doDeleteRecord
1672
int EmbeddedInnoDBCursor::doDeleteRecord(const unsigned char *)
1283.3.53 by Stewart Smith
support delete_row() in Embedded InnoDB. We move to the previous record in the cursor as after any of the read methods, the cursor always points to the *next* record to be read.
1673
{
1283.3.78 by Stewart Smith
fix up error code checking
1674
  ib_err_t err;
1675
1676
  err= ib_cursor_delete_row(cursor);
1677
  if (err != DB_SUCCESS)
1678
    return -1; // FIXME
1679
1283.60.4 by Stewart Smith
Change when we call ib_cursor_next/prev. Instead of calling it after reading
1680
  advance_cursor= true;
1283.3.53 by Stewart Smith
support delete_row() in Embedded InnoDB. We move to the previous record in the cursor as after any of the read methods, the cursor always points to the *next* record to be read.
1681
  return 0;
1682
}
1683
1283.3.79 by Stewart Smith
implement TRUNCATE TABLE for Embedded Innodb using the (fast) ib_cursor_truncate() call instead of deleting each row individually.
1684
int EmbeddedInnoDBCursor::delete_all_rows(void)
1685
{
1686
  /* I *think* ib_truncate is non-transactional....
1687
     so only support TRUNCATE and not DELETE FROM t;
1688
     (this is what ha_innodb does)
1689
  */
1690
  if (session_sql_command(ha_session()) != SQLCOM_TRUNCATE)
1691
    return HA_ERR_WRONG_COMMAND;
1692
1693
  ib_id_t id;
1694
  ib_err_t err;
1695
1283.3.80 by Stewart Smith
add basic transactional support to Embedded InnoDB engine.
1696
  ib_trx_t transaction= ib_trx_begin(IB_TRX_REPEATABLE_READ);
1283.3.79 by Stewart Smith
implement TRUNCATE TABLE for Embedded Innodb using the (fast) ib_cursor_truncate() call instead of deleting each row individually.
1697
1698
  ib_cursor_attach_trx(cursor, transaction);
1699
1700
  err= ib_schema_lock_exclusive(transaction);
1701
  if (err != DB_SUCCESS)
1702
  {
1703
    ib_err_t rollback_err= ib_trx_rollback(transaction);
1704
1705
    push_warning_printf(ha_session(), DRIZZLE_ERROR::WARN_LEVEL_ERROR,
1706
                        ER_CANT_DELETE_FILE,
1707
                        _("Cannot Lock Embedded InnoDB Data Dictionary. InnoDB Error %d (%s)\n"),
1708
                        err, ib_strerror(err));
1709
1710
    assert (rollback_err == DB_SUCCESS);
1711
1712
    return HA_ERR_GENERIC;
1713
  }
1714
1283.39.9 by Stewart Smith
TRUNCATE TABLE should reset auto increment value
1715
  share->auto_increment_value.fetch_and_store(1);
1716
1283.3.79 by Stewart Smith
implement TRUNCATE TABLE for Embedded Innodb using the (fast) ib_cursor_truncate() call instead of deleting each row individually.
1717
  err= ib_cursor_truncate(&cursor, &id);
1718
  if (err != DB_SUCCESS)
1719
    goto err;
1720
1721
  ib_schema_unlock(transaction);
1722
  /* ib_cursor_truncate commits on success */
1723
1724
  err= ib_cursor_open_table_using_id(id, NULL, &cursor);
1725
  if (err != DB_SUCCESS)
1726
    goto err;
1727
1728
  return 0;
1729
1730
err:
1731
  ib_schema_unlock(transaction);
1732
  ib_err_t rollback_err= ib_trx_rollback(transaction);
1733
  assert(rollback_err == DB_SUCCESS);
1734
  return err;
1735
}
1736
1491.1.10 by Jay Pipes
ha_rnd_init -> startTableScan, rnd_init -> doStartTableScan, ha_rnd_end -> endTableScan, rnd_end -> doEndTableScan
1737
int EmbeddedInnoDBCursor::doStartTableScan(bool)
1283.3.1 by Stewart Smith
Skeleton embedded_innodb plugin. Does nothing.
1738
{
1283.36.13 by Stewart Smith
basic auto_increment implementation for embedded_innodb. On startup, fetch the maximum value for the auto_increment column (or what's in the table message as the auto_increment value). Use an atomic variable in the embedded-innodb table share to keep track of the auto_increment_value. We can then use atomic ops to get an autoinc value (or several) as well as update it in the event of inserting a larger number. Currently there's a bug (well, difference in behaviour) around inserting -1 into an auto-inc field where the table already has a value 'higher' than that and then asking for another auto-inc value. Check the auto_increment test case failure for it. This will be fixed in a later commit.
1739
  ib_trx_t transaction;
1740
1283.60.11 by Stewart Smith
doStartTableScan() can be called twice in a row without a doEndTableScan()
1741
  if (in_table_scan)
1742
    doEndTableScan();
1743
  in_table_scan= true;
1744
1283.36.13 by Stewart Smith
basic auto_increment implementation for embedded_innodb. On startup, fetch the maximum value for the auto_increment column (or what's in the table message as the auto_increment value). Use an atomic variable in the embedded-innodb table share to keep track of the auto_increment_value. We can then use atomic ops to get an autoinc value (or several) as well as update it in the event of inserting a larger number. Currently there's a bug (well, difference in behaviour) around inserting -1 into an auto-inc field where the table already has a value 'higher' than that and then asking for another auto-inc value. Check the auto_increment test case failure for it. This will be fixed in a later commit.
1745
  transaction= *get_trx(ha_session());
1283.3.36 by Stewart Smith
'correctly' deal with transaction in an autocommit type way. this means queries like 'insert select' work as we're always in the correct transactional context.
1746
1510.4.2 by Jay Pipes
Fixes Bug #552420. Because the copied-to table in ALTER TABLE is temporary, mysql_lock_tables() is not called, and the automatic StorageEngine::startStatement() is also not called. So, we call it manually to ensure transactional engines have a notification of a new statement/transaction.
1747
  assert(transaction != NULL);
1748
1283.3.36 by Stewart Smith
'correctly' deal with transaction in an autocommit type way. this means queries like 'insert select' work as we're always in the correct transactional context.
1749
  ib_cursor_attach_trx(cursor, transaction);
1750
1751
  tuple= ib_clust_read_tuple_create(cursor);
1752
1283.19.28 by Stewart Smith
fixup error checking
1753
  ib_err_t err= ib_cursor_first(cursor);
1754
  if (err != DB_SUCCESS && err != DB_END_OF_INDEX)
1755
    return -1; // FIXME
1283.3.28 by Stewart Smith
simple rnd_init/rnd_next implementation for embedded innodb. It now works for inserting 1 row with an int column and selecting that row back (at least).
1756
1283.60.4 by Stewart Smith
Change when we call ib_cursor_next/prev. Instead of calling it after reading
1757
  advance_cursor= false;
1758
1283.3.1 by Stewart Smith
Skeleton embedded_innodb plugin. Does nothing.
1759
  return(0);
1760
}
1761
1283.60.10 by Stewart Smith
the memory management for BLOBS is completely insane. For certain types of index lookups we *must* do a copy and clear it *only* in ::reset() or ::extra(). This patch fixes up any valgrind warnings/assertions for embedded_innodb executing type_blob test.
1762
int read_row_from_innodb(unsigned char* buf, ib_crsr_t cursor, ib_tpl_t tuple, Table* table, bool has_hidden_primary_key, uint64_t *hidden_pkey, drizzled::memory::Root **blobroot)
1283.3.1 by Stewart Smith
Skeleton embedded_innodb plugin. Does nothing.
1763
{
1283.3.28 by Stewart Smith
simple rnd_init/rnd_next implementation for embedded innodb. It now works for inserting 1 row with an int column and selecting that row back (at least).
1764
  ib_err_t err;
1283.36.1 by Stewart Smith
fix read_row_from_innodb to respect which buffer the row should be written into from innodb by using the amazing Field::move_field_offset() call properly.
1765
  ptrdiff_t row_offset= buf - table->record[0];
1283.3.28 by Stewart Smith
simple rnd_init/rnd_next implementation for embedded innodb. It now works for inserting 1 row with an int column and selecting that row back (at least).
1766
1767
  err= ib_cursor_read_row(cursor, tuple);
1768
1769
  if (err != DB_SUCCESS) // FIXME
1770
    return HA_ERR_END_OF_FILE;
1771
1772
  int colnr= 0;
1773
1283.60.8 by Stewart Smith
A ::position() call requires teh primary key in the record buffer, so we must *always* read the primary key in the various read methods in case we get a ::position() call. This was showing up in the simple ORDER BY test in type_blob_func.test
1774
  /* We need the primary key for ::position() to work */
1775
  if (table->s->primary_key != MAX_KEY)
1776
    table->mark_columns_used_by_index_no_reset(table->s->primary_key);
1777
1283.3.28 by Stewart Smith
simple rnd_init/rnd_next implementation for embedded innodb. It now works for inserting 1 row with an int column and selecting that row back (at least).
1778
  for (Field **field=table->field ; *field ; field++, colnr++)
1779
  {
1283.19.3 by Stewart Smith
fix up rnd_next for reading tables a bit more properly: respect readset, set writeset (to assert we're getting everything). Also use the Field::store() method to store the result in the Drizzle row buffer. This means the Field classes look after things like the length bytes.
1780
    if (! (**field).isReadSet())
1781
      continue;
1782
1283.36.1 by Stewart Smith
fix read_row_from_innodb to respect which buffer the row should be written into from innodb by using the amazing Field::move_field_offset() call properly.
1783
    (**field).move_field_offset(row_offset);
1784
1283.19.3 by Stewart Smith
fix up rnd_next for reading tables a bit more properly: respect readset, set writeset (to assert we're getting everything). Also use the Field::store() method to store the result in the Drizzle row buffer. This means the Field classes look after things like the length bytes.
1785
    (**field).setWriteSet();
1786
1787
    uint32_t length= ib_col_get_len(tuple, colnr);
1788
    if (length == IB_SQL_NULL)
1283.19.33 by Stewart Smith
fix reading null values from embedded innodb. don't try and retrieve a value for a column taht is null
1789
    {
1283.19.3 by Stewart Smith
fix up rnd_next for reading tables a bit more properly: respect readset, set writeset (to assert we're getting everything). Also use the Field::store() method to store the result in the Drizzle row buffer. This means the Field classes look after things like the length bytes.
1790
      (**field).set_null();
1283.19.33 by Stewart Smith
fix reading null values from embedded innodb. don't try and retrieve a value for a column taht is null
1791
      continue;
1792
    }
1283.19.3 by Stewart Smith
fix up rnd_next for reading tables a bit more properly: respect readset, set writeset (to assert we're getting everything). Also use the Field::store() method to store the result in the Drizzle row buffer. This means the Field classes look after things like the length bytes.
1793
    else
1283.19.5 by Stewart Smith
retrieve non-VARCHAR columns properly from embedded InnoDB. We should just shunt the bytes around except if we need to do things with strings...
1794
      (**field).set_notnull();
1795
1796
    if ((**field).type() == DRIZZLE_TYPE_VARCHAR)
1283.19.3 by Stewart Smith
fix up rnd_next for reading tables a bit more properly: respect readset, set writeset (to assert we're getting everything). Also use the Field::store() method to store the result in the Drizzle row buffer. This means the Field classes look after things like the length bytes.
1797
    {
1798
      (*field)->store((const char*)ib_col_get_value(tuple, colnr),
1799
                      length,
1800
                      &my_charset_bin);
1283.19.5 by Stewart Smith
retrieve non-VARCHAR columns properly from embedded InnoDB. We should just shunt the bytes around except if we need to do things with strings...
1801
    }
1283.35.45 by Stewart Smith
enable DATE type for embedded_innodb.
1802
    else if ((**field).type() == DRIZZLE_TYPE_DATE)
1803
    {
1804
      uint32_t date_read;
1805
      err= ib_tuple_read_u32(tuple, colnr, &date_read);
1806
      (*field)->store(date_read);
1807
    }
1283.60.5 by Stewart Smith
add BLOB support to embedded_innodb along with a simple test.
1808
    else if ((**field).type() == DRIZZLE_TYPE_BLOB)
1809
    {
1283.60.10 by Stewart Smith
the memory management for BLOBS is completely insane. For certain types of index lookups we *must* do a copy and clear it *only* in ::reset() or ::extra(). This patch fixes up any valgrind warnings/assertions for embedded_innodb executing type_blob test.
1810
      if (blobroot == NULL)
1811
        (reinterpret_cast<Field_blob*>(*field))->set_ptr(length,
1812
                                      (unsigned char*)ib_col_get_value(tuple,
1813
                                                                       colnr));
1814
      else
1815
      {
1816
        if (*blobroot == NULL)
1817
        {
1818
          *blobroot= new drizzled::memory::Root();
1819
          (**blobroot).init_alloc_root();
1820
        }
1821
1822
        unsigned char *blob_ptr= (unsigned char*)(**blobroot).alloc_root(length);
1823
        memcpy(blob_ptr, ib_col_get_value(tuple, colnr), length);
1824
        (reinterpret_cast<Field_blob*>(*field))->set_ptr(length, blob_ptr);
1825
      }
1283.60.5 by Stewart Smith
add BLOB support to embedded_innodb along with a simple test.
1826
    }
1283.19.5 by Stewart Smith
retrieve non-VARCHAR columns properly from embedded InnoDB. We should just shunt the bytes around except if we need to do things with strings...
1827
    else
1828
    {
1829
      ib_col_copy_value(tuple, colnr, (*field)->ptr, (*field)->data_length());
1283.19.3 by Stewart Smith
fix up rnd_next for reading tables a bit more properly: respect readset, set writeset (to assert we're getting everything). Also use the Field::store() method to store the result in the Drizzle row buffer. This means the Field classes look after things like the length bytes.
1830
    }
1283.36.1 by Stewart Smith
fix read_row_from_innodb to respect which buffer the row should be written into from innodb by using the amazing Field::move_field_offset() call properly.
1831
1832
    (**field).move_field_offset(-row_offset);
1833
1283.3.28 by Stewart Smith
simple rnd_init/rnd_next implementation for embedded innodb. It now works for inserting 1 row with an int column and selecting that row back (at least).
1834
  }
1835
1283.35.97 by Stewart Smith
support tables without an explicit primary key in embedded_innodb by creating a hidden auto_increment primary key. We also have to support tables without an explicit primary key but with an auto increment, so we have our own hidden one. yes, it hurts.
1836
  if (has_hidden_primary_key)
1837
  {
1838
    err= ib_tuple_read_u64(tuple, colnr, hidden_pkey);
1839
  }
1840
1283.3.43 by Stewart Smith
refactor out rnd_next() into read_row_from_innodb() and a call to ib_cursor_next(). This allows us to make the row reading code generic for index scans/lookups.
1841
  return 0;
1842
}
1843
1283.36.1 by Stewart Smith
fix read_row_from_innodb to respect which buffer the row should be written into from innodb by using the amazing Field::move_field_offset() call properly.
1844
int EmbeddedInnoDBCursor::rnd_next(unsigned char *buf)
1283.3.43 by Stewart Smith
refactor out rnd_next() into read_row_from_innodb() and a call to ib_cursor_next(). This allows us to make the row reading code generic for index scans/lookups.
1845
{
1846
  ib_err_t err;
1847
  int ret;
1848
1283.60.4 by Stewart Smith
Change when we call ib_cursor_next/prev. Instead of calling it after reading
1849
  if (advance_cursor)
1850
    err= ib_cursor_next(cursor);
1851
1283.28.1 by Stewart Smith
basic UPDATE row for Embedded InnoDB Engine.
1852
  tuple= ib_tuple_clear(tuple);
1283.35.97 by Stewart Smith
support tables without an explicit primary key in embedded_innodb by creating a hidden auto_increment primary key. We also have to support tables without an explicit primary key but with an auto increment, so we have our own hidden one. yes, it hurts.
1853
  ret= read_row_from_innodb(buf, cursor, tuple, table,
1854
                            share->has_hidden_primary_key,
1855
                            &hidden_autoinc_pkey_position);
1283.3.43 by Stewart Smith
refactor out rnd_next() into read_row_from_innodb() and a call to ib_cursor_next(). This allows us to make the row reading code generic for index scans/lookups.
1856
1283.60.4 by Stewart Smith
Change when we call ib_cursor_next/prev. Instead of calling it after reading
1857
  advance_cursor= true;
1283.3.43 by Stewart Smith
refactor out rnd_next() into read_row_from_innodb() and a call to ib_cursor_next(). This allows us to make the row reading code generic for index scans/lookups.
1858
  return ret;
1283.3.28 by Stewart Smith
simple rnd_init/rnd_next implementation for embedded innodb. It now works for inserting 1 row with an int column and selecting that row back (at least).
1859
}
1860
1491.1.10 by Jay Pipes
ha_rnd_init -> startTableScan, rnd_init -> doStartTableScan, ha_rnd_end -> endTableScan, rnd_end -> doEndTableScan
1861
int EmbeddedInnoDBCursor::doEndTableScan()
1283.3.28 by Stewart Smith
simple rnd_init/rnd_next implementation for embedded innodb. It now works for inserting 1 row with an int column and selecting that row back (at least).
1862
{
1283.19.28 by Stewart Smith
fixup error checking
1863
  ib_err_t err;
1864
1283.3.36 by Stewart Smith
'correctly' deal with transaction in an autocommit type way. this means queries like 'insert select' work as we're always in the correct transactional context.
1865
  ib_tuple_delete(tuple);
1283.19.28 by Stewart Smith
fixup error checking
1866
  err= ib_cursor_reset(cursor);
1867
  assert(err == DB_SUCCESS);
1283.60.11 by Stewart Smith
doStartTableScan() can be called twice in a row without a doEndTableScan()
1868
  in_table_scan= false;
1283.3.28 by Stewart Smith
simple rnd_init/rnd_next implementation for embedded innodb. It now works for inserting 1 row with an int column and selecting that row back (at least).
1869
  return 0;
1870
}
1283.3.1 by Stewart Smith
Skeleton embedded_innodb plugin. Does nothing.
1871
1283.36.1 by Stewart Smith
fix read_row_from_innodb to respect which buffer the row should be written into from innodb by using the amazing Field::move_field_offset() call properly.
1872
int EmbeddedInnoDBCursor::rnd_pos(unsigned char *buf, unsigned char *pos)
1283.3.1 by Stewart Smith
Skeleton embedded_innodb plugin. Does nothing.
1873
{
1283.28.29 by Stewart Smith
implement rnd_pos for embedded_innodb. Also fix up fill_ib_search_tpl_froM_drizzle_key for primary keys that aren't all at the start of the table. It turns out that the clustered index search tuple numbers columns just in the clustered index, not anything to do with column numbers in the table.
1874
  ib_err_t err;
1875
  int res;
1283.60.7 by Stewart Smith
improve error handling in EmbeddedInnoDBCursor::rnd_pos()
1876
  int ret= 0;
1283.28.29 by Stewart Smith
implement rnd_pos for embedded_innodb. Also fix up fill_ib_search_tpl_froM_drizzle_key for primary keys that aren't all at the start of the table. It turns out that the clustered index search tuple numbers columns just in the clustered index, not anything to do with column numbers in the table.
1877
  ib_tpl_t search_tuple= ib_clust_search_tuple_create(cursor);
1878
1283.35.97 by Stewart Smith
support tables without an explicit primary key in embedded_innodb by creating a hidden auto_increment primary key. We also have to support tables without an explicit primary key but with an auto increment, so we have our own hidden one. yes, it hurts.
1879
  if (share->has_hidden_primary_key)
1880
  {
1283.60.7 by Stewart Smith
improve error handling in EmbeddedInnoDBCursor::rnd_pos()
1881
    err= ib_col_set_value(search_tuple, 0,
1283.60.9 by Stewart Smith
fix (rather embarrassing) bug where with a hidden primary key in rnd_pos() we would go to the row in ref rather tahn the parameter pos. If we had a style of m_ prefix for members, this would not have been a problem.
1882
                          ((uint64_t*)(pos)), sizeof(uint64_t));
1283.35.97 by Stewart Smith
support tables without an explicit primary key in embedded_innodb by creating a hidden auto_increment primary key. We also have to support tables without an explicit primary key but with an auto increment, so we have our own hidden one. yes, it hurts.
1883
  }
1884
  else
1885
  {
1886
    fill_ib_search_tpl_from_drizzle_key(search_tuple,
1887
                                        table->key_info + 0,
1888
                                        pos, ref_length);
1889
  }
1283.28.29 by Stewart Smith
implement rnd_pos for embedded_innodb. Also fix up fill_ib_search_tpl_froM_drizzle_key for primary keys that aren't all at the start of the table. It turns out that the clustered index search tuple numbers columns just in the clustered index, not anything to do with column numbers in the table.
1890
1891
  err= ib_cursor_moveto(cursor, search_tuple, IB_CUR_GE, &res);
1892
  assert(err == DB_SUCCESS);
1283.60.7 by Stewart Smith
improve error handling in EmbeddedInnoDBCursor::rnd_pos()
1893
1894
  assert(res==0);
1895
  if (res != 0)
1896
    ret= -1;
1897
1283.28.29 by Stewart Smith
implement rnd_pos for embedded_innodb. Also fix up fill_ib_search_tpl_froM_drizzle_key for primary keys that aren't all at the start of the table. It turns out that the clustered index search tuple numbers columns just in the clustered index, not anything to do with column numbers in the table.
1898
  ib_tuple_delete(search_tuple);
1899
1900
  tuple= ib_tuple_clear(tuple);
1283.60.7 by Stewart Smith
improve error handling in EmbeddedInnoDBCursor::rnd_pos()
1901
1902
  if (ret == 0)
1903
    ret= read_row_from_innodb(buf, cursor, tuple, table,
1904
                              share->has_hidden_primary_key,
1905
                              &hidden_autoinc_pkey_position);
1283.28.29 by Stewart Smith
implement rnd_pos for embedded_innodb. Also fix up fill_ib_search_tpl_froM_drizzle_key for primary keys that aren't all at the start of the table. It turns out that the clustered index search tuple numbers columns just in the clustered index, not anything to do with column numbers in the table.
1906
1283.60.4 by Stewart Smith
Change when we call ib_cursor_next/prev. Instead of calling it after reading
1907
  advance_cursor= true;
1283.28.29 by Stewart Smith
implement rnd_pos for embedded_innodb. Also fix up fill_ib_search_tpl_froM_drizzle_key for primary keys that aren't all at the start of the table. It turns out that the clustered index search tuple numbers columns just in the clustered index, not anything to do with column numbers in the table.
1908
1283.60.7 by Stewart Smith
improve error handling in EmbeddedInnoDBCursor::rnd_pos()
1909
  return(ret);
1283.3.1 by Stewart Smith
Skeleton embedded_innodb plugin. Does nothing.
1910
}
1911
1475.2.9 by Stewart Smith
fix many compile failures that people introduced in embedded_innodb because it's not built by default.. i.e. plugin=disabled is EPIC FAIL
1912
static void store_key_value_from_innodb(KeyInfo *key_info, unsigned char* ref, int ref_len, const unsigned char *record)
1283.28.25 by Stewart Smith
simple ::position() implementation for embedded innodb. include simple test (that does call it).
1913
{
1475.2.9 by Stewart Smith
fix many compile failures that people introduced in embedded_innodb because it's not built by default.. i.e. plugin=disabled is EPIC FAIL
1914
  KeyPartInfo* key_part= key_info->key_part;
1915
  KeyPartInfo* end= key_info->key_part + key_info->key_parts;
1283.28.25 by Stewart Smith
simple ::position() implementation for embedded innodb. include simple test (that does call it).
1916
  unsigned char* ref_start= ref;
1917
1918
  memset(ref, 0, ref_len);
1919
1920
  for (; key_part != end; key_part++)
1921
  {
1922
    char is_null= 0;
1923
1924
    if(key_part->null_bit)
1925
    {
1926
      *ref= is_null= record[key_part->null_offset] & key_part->null_bit;
1927
      ref++;
1928
    }
1929
1930
    Field *field= key_part->field;
1931
1932
    if (field->type() == DRIZZLE_TYPE_VARCHAR)
1933
    {
1934
      if (is_null)
1935
      {
1936
        ref+= key_part->length + 2; /* 2 bytes for length */
1937
        continue;
1938
      }
1939
1940
      String str;
1941
      field->val_str(&str);
1942
1943
      *ref++= (char)(str.length() & 0x000000ff);
1944
      *ref++= (char)((str.length()>>8) & 0x000000ff);
1945
1946
      memcpy(ref, str.ptr(), str.length());
1283.28.28 by Stewart Smith
fix up store_key_value_from_innodb for embedded_innodb ::position() with varchar columns that weren't full.
1947
      ref+= key_part->length;
1283.28.25 by Stewart Smith
simple ::position() implementation for embedded innodb. include simple test (that does call it).
1948
    }
1949
    // FIXME: blobs.
1950
    else
1951
    {
1952
      if (is_null)
1953
      {
1954
        ref+= key_part->length;
1955
        continue;
1956
      }
1957
1958
      memcpy(ref, record+key_part->offset, key_part->length);
1959
      ref+= key_part->length;
1960
    }
1961
1962
  }
1963
1964
  assert(ref == ref_start + ref_len);
1965
}
1966
1967
void EmbeddedInnoDBCursor::position(const unsigned char *record)
1968
{
1532.1.15 by Brian Aker
Partial encapsulation of TableShare from Table.
1969
  if (table->getShare()->primary_key != MAX_KEY)
1970
    store_key_value_from_innodb(table->key_info + table->getShare()->primary_key,
1283.35.97 by Stewart Smith
support tables without an explicit primary key in embedded_innodb by creating a hidden auto_increment primary key. We also have to support tables without an explicit primary key but with an auto increment, so we have our own hidden one. yes, it hurts.
1971
                                ref, ref_length, record);
1972
  else
1973
    *((uint64_t*) ref)= hidden_autoinc_pkey_position;
1283.3.1 by Stewart Smith
Skeleton embedded_innodb plugin. Does nothing.
1974
  return;
1975
}
1976
1283.3.42 by Stewart Smith
basic index scan of embedded innodb clustered index
1977
double EmbeddedInnoDBCursor::scan_time()
1978
{
1979
  return 0.1;
1980
}
1283.3.1 by Stewart Smith
Skeleton embedded_innodb plugin. Does nothing.
1981
1982
int EmbeddedInnoDBCursor::info(uint32_t flag)
1983
{
1283.3.42 by Stewart Smith
basic index scan of embedded innodb clustered index
1984
  stats.records= 2;
1283.3.36 by Stewart Smith
'correctly' deal with transaction in an autocommit type way. this means queries like 'insert select' work as we're always in the correct transactional context.
1985
1283.3.1 by Stewart Smith
Skeleton embedded_innodb plugin. Does nothing.
1986
  if (flag & HA_STATUS_AUTO)
1987
    stats.auto_increment_value= 1;
1988
  return(0);
1989
}
1990
1491.1.6 by Jay Pipes
Cursor::ha_index_init() -> Cursor::startIndexScan(). Cursor::ha_index_end() -> Cursor::endIndexScan()
1991
int EmbeddedInnoDBCursor::doStartIndexScan(uint32_t keynr, bool)
1283.3.42 by Stewart Smith
basic index scan of embedded innodb clustered index
1992
{
1283.3.80 by Stewart Smith
add basic transactional support to Embedded InnoDB engine.
1993
  ib_trx_t transaction= *get_trx(ha_session());
1994
1283.3.42 by Stewart Smith
basic index scan of embedded innodb clustered index
1995
  active_index= keynr;
1996
1997
  ib_cursor_attach_trx(cursor, transaction);
1998
1999
  if (active_index == 0)
2000
  {
2001
    tuple= ib_clust_read_tuple_create(cursor);
2002
  }
2003
  else
2004
  {
1283.28.15 by Stewart Smith
support secondary index scan in embedded_innodb. we add a next_innodb_error member to EmbeddedInnodbCursor as unlike clustered indexes, trying to fetch a row after you have gotten DB_END_OF_INDEX results in a much nastier crash than a simple error code.
2005
    ib_err_t err;
2006
    ib_id_t index_id;
1475.2.9 by Stewart Smith
fix many compile failures that people introduced in embedded_innodb because it's not built by default.. i.e. plugin=disabled is EPIC FAIL
2007
    err= ib_index_get_id(table_share->getPath()+2,
1574.1.3 by Brian Aker
Encapsulate Key info in share.
2008
                         table_share->getKeyInfo(keynr).name,
1283.28.15 by Stewart Smith
support secondary index scan in embedded_innodb. we add a next_innodb_error member to EmbeddedInnodbCursor as unlike clustered indexes, trying to fetch a row after you have gotten DB_END_OF_INDEX results in a much nastier crash than a simple error code.
2009
                         &index_id);
2010
    if (err != DB_SUCCESS)
2011
      return -1;
2012
2013
    err= ib_cursor_close(cursor);
2014
    err= ib_cursor_open_index_using_id(index_id, transaction, &cursor);
2015
2016
    if (err != DB_SUCCESS)
2017
      return -1;
2018
2019
    tuple= ib_clust_read_tuple_create(cursor);
2020
    ib_cursor_set_cluster_access(cursor);
1283.3.42 by Stewart Smith
basic index scan of embedded innodb clustered index
2021
  }
2022
1283.60.4 by Stewart Smith
Change when we call ib_cursor_next/prev. Instead of calling it after reading
2023
  advance_cursor= false;
1283.3.42 by Stewart Smith
basic index scan of embedded innodb clustered index
2024
  return 0;
2025
}
2026
1283.28.16 by Stewart Smith
use appropriate ib_srch_mode for index_read. implement ha_rkey_function to ib_sch_mode function.
2027
static ib_srch_mode_t ha_rkey_function_to_ib_srch_mode(drizzled::ha_rkey_function find_flag)
2028
{
2029
  switch (find_flag)
2030
  {
2031
  case HA_READ_KEY_EXACT:
2032
    return IB_CUR_GE;
2033
  case HA_READ_KEY_OR_NEXT:
2034
    return IB_CUR_GE;
2035
  case HA_READ_KEY_OR_PREV:
2036
    return IB_CUR_LE;
2037
  case HA_READ_AFTER_KEY:
2038
    return IB_CUR_G;
2039
  case HA_READ_BEFORE_KEY:
2040
    return IB_CUR_L;
2041
  case HA_READ_PREFIX:
2042
    return IB_CUR_GE;
2043
  case HA_READ_PREFIX_LAST:
2044
    return IB_CUR_LE;
2045
  case HA_READ_PREFIX_LAST_OR_PREV:
2046
    return IB_CUR_LE;
2047
  case HA_READ_MBR_CONTAIN:
2048
  case HA_READ_MBR_INTERSECT:
2049
  case HA_READ_MBR_WITHIN:
2050
  case HA_READ_MBR_DISJOINT:
2051
  case HA_READ_MBR_EQUAL:
2052
    assert(false); /* these just exist in the enum, not used. */
2053
  }
2054
2055
  assert(false);
1530.5.10 by Monty Taylor
Fixed build errors on FreeBSD.
2056
  /* Must return or compiler complains about reaching end of function */
2057
  return (ib_srch_mode_t)0;
1283.28.16 by Stewart Smith
use appropriate ib_srch_mode for index_read. implement ha_rkey_function to ib_sch_mode function.
2058
}
2059
1283.28.17 by Stewart Smith
implement index_read for multi column indexes
2060
static void fill_ib_search_tpl_from_drizzle_key(ib_tpl_t search_tuple,
1475.2.9 by Stewart Smith
fix many compile failures that people introduced in embedded_innodb because it's not built by default.. i.e. plugin=disabled is EPIC FAIL
2061
                                                const drizzled::KeyInfo *key_info,
1283.28.17 by Stewart Smith
implement index_read for multi column indexes
2062
                                                const unsigned char *key_ptr,
2063
                                                uint32_t key_len)
2064
{
1475.2.9 by Stewart Smith
fix many compile failures that people introduced in embedded_innodb because it's not built by default.. i.e. plugin=disabled is EPIC FAIL
2065
  KeyPartInfo *key_part= key_info->key_part;
2066
  KeyPartInfo *end= key_part + key_info->key_parts;
1283.28.17 by Stewart Smith
implement index_read for multi column indexes
2067
  const unsigned char *buff= key_ptr;
2068
  ib_err_t err;
2069
1283.28.29 by Stewart Smith
implement rnd_pos for embedded_innodb. Also fix up fill_ib_search_tpl_froM_drizzle_key for primary keys that aren't all at the start of the table. It turns out that the clustered index search tuple numbers columns just in the clustered index, not anything to do with column numbers in the table.
2070
  int fieldnr= 0;
2071
1283.28.17 by Stewart Smith
implement index_read for multi column indexes
2072
  for(; key_part != end && buff < key_ptr + key_len; key_part++)
2073
  {
2074
    Field *field= key_part->field;
2075
    bool is_null= false;
2076
2077
    if (key_part->null_bit)
2078
    {
2079
      is_null= *buff;
2080
      if (is_null)
2081
      {
1283.28.29 by Stewart Smith
implement rnd_pos for embedded_innodb. Also fix up fill_ib_search_tpl_froM_drizzle_key for primary keys that aren't all at the start of the table. It turns out that the clustered index search tuple numbers columns just in the clustered index, not anything to do with column numbers in the table.
2082
        err= ib_col_set_value(search_tuple, fieldnr, NULL, IB_SQL_NULL);
1283.28.17 by Stewart Smith
implement index_read for multi column indexes
2083
        assert(err == DB_SUCCESS);
2084
      }
2085
      buff++;
2086
    }
2087
2088
    if (field->type() == DRIZZLE_TYPE_VARCHAR)
2089
    {
2090
      if (is_null)
2091
      {
2092
        buff+= key_part->length + 2; /* 2 bytes length */
2093
        continue;
2094
      }
2095
2096
      int length= *buff + (*(buff + 1) << 8);
1283.28.29 by Stewart Smith
implement rnd_pos for embedded_innodb. Also fix up fill_ib_search_tpl_froM_drizzle_key for primary keys that aren't all at the start of the table. It turns out that the clustered index search tuple numbers columns just in the clustered index, not anything to do with column numbers in the table.
2097
      buff+=2;
2098
      err= ib_col_set_value(search_tuple, fieldnr, buff, length);
1283.28.17 by Stewart Smith
implement index_read for multi column indexes
2099
      assert(err == DB_SUCCESS);
2100
1283.28.29 by Stewart Smith
implement rnd_pos for embedded_innodb. Also fix up fill_ib_search_tpl_froM_drizzle_key for primary keys that aren't all at the start of the table. It turns out that the clustered index search tuple numbers columns just in the clustered index, not anything to do with column numbers in the table.
2101
      buff+= key_part->length;
1283.28.17 by Stewart Smith
implement index_read for multi column indexes
2102
    }
1283.35.45 by Stewart Smith
enable DATE type for embedded_innodb.
2103
    else if (field->type() == DRIZZLE_TYPE_DATE)
2104
    {
1283.46.3 by Stewart Smith
simplify filling search tuple for DATE types in embedded_innodb
2105
      uint32_t date_int= static_cast<uint32_t>(field->val_int());
1283.35.45 by Stewart Smith
enable DATE type for embedded_innodb.
2106
      err= ib_col_set_value(search_tuple, fieldnr, &date_int, 4);
2107
      buff+= key_part->length;
2108
    }
1283.28.17 by Stewart Smith
implement index_read for multi column indexes
2109
    // FIXME: BLOBs
2110
    else
2111
    {
2112
      if (is_null)
2113
      {
2114
        buff+= key_part->length;
2115
        continue;
2116
      }
2117
1283.28.29 by Stewart Smith
implement rnd_pos for embedded_innodb. Also fix up fill_ib_search_tpl_froM_drizzle_key for primary keys that aren't all at the start of the table. It turns out that the clustered index search tuple numbers columns just in the clustered index, not anything to do with column numbers in the table.
2118
      err= ib_col_set_value(search_tuple, fieldnr,
1283.28.17 by Stewart Smith
implement index_read for multi column indexes
2119
                            buff, key_part->length);
2120
      assert(err == DB_SUCCESS);
2121
2122
      buff+= key_part->length;
2123
    }
1283.28.29 by Stewart Smith
implement rnd_pos for embedded_innodb. Also fix up fill_ib_search_tpl_froM_drizzle_key for primary keys that aren't all at the start of the table. It turns out that the clustered index search tuple numbers columns just in the clustered index, not anything to do with column numbers in the table.
2124
2125
    fieldnr++;
1283.28.17 by Stewart Smith
implement index_read for multi column indexes
2126
  }
2127
2128
  assert(buff == key_ptr + key_len);
2129
}
2130
1283.60.10 by Stewart Smith
the memory management for BLOBS is completely insane. For certain types of index lookups we *must* do a copy and clear it *only* in ::reset() or ::extra(). This patch fixes up any valgrind warnings/assertions for embedded_innodb executing type_blob test.
2131
int EmbeddedInnoDBCursor::innodb_index_read(unsigned char *buf,
2132
                                            const unsigned char *key_ptr,
2133
                                            uint32_t key_len,
2134
                                            drizzled::ha_rkey_function find_flag,
2135
                                            bool allocate_blobs)
1283.3.52 by Stewart Smith
simple index_read() for embedded innodb. Add a test for first column beivng primary key and index lookups/scans.
2136
{
2137
  ib_tpl_t search_tuple;
2138
  int res;
2139
  ib_err_t err;
2140
  int ret;
1283.28.16 by Stewart Smith
use appropriate ib_srch_mode for index_read. implement ha_rkey_function to ib_sch_mode function.
2141
  ib_srch_mode_t search_mode;
1283.3.52 by Stewart Smith
simple index_read() for embedded innodb. Add a test for first column beivng primary key and index lookups/scans.
2142
1283.28.16 by Stewart Smith
use appropriate ib_srch_mode for index_read. implement ha_rkey_function to ib_sch_mode function.
2143
  search_mode= ha_rkey_function_to_ib_srch_mode(find_flag);
2144
1283.28.17 by Stewart Smith
implement index_read for multi column indexes
2145
  if (active_index == 0)
2146
    search_tuple= ib_clust_search_tuple_create(cursor);
2147
  else
2148
    search_tuple= ib_sec_search_tuple_create(cursor);
1283.3.52 by Stewart Smith
simple index_read() for embedded innodb. Add a test for first column beivng primary key and index lookups/scans.
2149
1283.28.17 by Stewart Smith
implement index_read for multi column indexes
2150
  fill_ib_search_tpl_from_drizzle_key(search_tuple,
2151
                                      table->key_info + active_index,
2152
                                      key_ptr, key_len);
1283.3.52 by Stewart Smith
simple index_read() for embedded innodb. Add a test for first column beivng primary key and index lookups/scans.
2153
1283.28.16 by Stewart Smith
use appropriate ib_srch_mode for index_read. implement ha_rkey_function to ib_sch_mode function.
2154
  err= ib_cursor_moveto(cursor, search_tuple, search_mode, &res);
1283.28.17 by Stewart Smith
implement index_read for multi column indexes
2155
  ib_tuple_delete(search_tuple);
2156
1283.60.14 by Stewart Smith
we actually don't need to check the result, just set status correctly
2157
  if ((err == DB_RECORD_NOT_FOUND || err == DB_END_OF_INDEX))
1283.60.12 by Stewart Smith
check that we really did move to the right row in EmbeddedInnoDBCursor::innodb_index_read(). This emans type_blob test now passes. We need to update table->status as well here.
2158
  {
1283.60.14 by Stewart Smith
we actually don't need to check the result, just set status correctly
2159
    table->status= STATUS_NOT_FOUND;
1283.60.12 by Stewart Smith
check that we really did move to the right row in EmbeddedInnoDBCursor::innodb_index_read(). This emans type_blob test now passes. We need to update table->status as well here.
2160
    return HA_ERR_KEY_NOT_FOUND;
2161
  }
2162
2163
  assert(err==DB_SUCCESS);
1283.3.52 by Stewart Smith
simple index_read() for embedded innodb. Add a test for first column beivng primary key and index lookups/scans.
2164
1283.28.1 by Stewart Smith
basic UPDATE row for Embedded InnoDB Engine.
2165
  tuple= ib_tuple_clear(tuple);
1283.35.97 by Stewart Smith
support tables without an explicit primary key in embedded_innodb by creating a hidden auto_increment primary key. We also have to support tables without an explicit primary key but with an auto increment, so we have our own hidden one. yes, it hurts.
2166
  ret= read_row_from_innodb(buf, cursor, tuple, table,
2167
                            share->has_hidden_primary_key,
1283.60.10 by Stewart Smith
the memory management for BLOBS is completely insane. For certain types of index lookups we *must* do a copy and clear it *only* in ::reset() or ::extra(). This patch fixes up any valgrind warnings/assertions for embedded_innodb executing type_blob test.
2168
                            &hidden_autoinc_pkey_position,
2169
                            (allocate_blobs)? &blobroot : NULL);
1283.60.12 by Stewart Smith
check that we really did move to the right row in EmbeddedInnoDBCursor::innodb_index_read(). This emans type_blob test now passes. We need to update table->status as well here.
2170
  if (ret == 0)
2171
    table->status= 0;
2172
  else
2173
    table->status= STATUS_NOT_FOUND;
2174
1283.60.4 by Stewart Smith
Change when we call ib_cursor_next/prev. Instead of calling it after reading
2175
  advance_cursor= true;
1283.3.52 by Stewart Smith
simple index_read() for embedded innodb. Add a test for first column beivng primary key and index lookups/scans.
2176
1283.60.12 by Stewart Smith
check that we really did move to the right row in EmbeddedInnoDBCursor::innodb_index_read(). This emans type_blob test now passes. We need to update table->status as well here.
2177
  return ret;
1283.3.52 by Stewart Smith
simple index_read() for embedded innodb. Add a test for first column beivng primary key and index lookups/scans.
2178
}
1283.3.1 by Stewart Smith
Skeleton embedded_innodb plugin. Does nothing.
2179
1283.60.10 by Stewart Smith
the memory management for BLOBS is completely insane. For certain types of index lookups we *must* do a copy and clear it *only* in ::reset() or ::extra(). This patch fixes up any valgrind warnings/assertions for embedded_innodb executing type_blob test.
2180
int EmbeddedInnoDBCursor::index_read(unsigned char *buf,
2181
                                     const unsigned char *key_ptr,
2182
                                     uint32_t key_len,
2183
                                     drizzled::ha_rkey_function find_flag)
2184
{
2185
  return innodb_index_read(buf, key_ptr, key_len, find_flag, false);
2186
}
2187
2188
/* This is straight from cursor.cc, but it's private there :( */
2189
uint32_t EmbeddedInnoDBCursor::calculate_key_len(uint32_t key_position,
2190
                                                 key_part_map keypart_map_arg)
2191
{
2192
  /* works only with key prefixes */
2193
  assert(((keypart_map_arg + 1) & keypart_map_arg) == 0);
2194
1574.1.3 by Brian Aker
Encapsulate Key info in share.
2195
  KeyPartInfo *key_part_found= table->s->getKeyInfo(key_position).key_part;
2196
  KeyPartInfo *end_key_part_found= key_part_found + table->s->getKeyInfo(key_position).key_parts;
1283.60.10 by Stewart Smith
the memory management for BLOBS is completely insane. For certain types of index lookups we *must* do a copy and clear it *only* in ::reset() or ::extra(). This patch fixes up any valgrind warnings/assertions for embedded_innodb executing type_blob test.
2197
  uint32_t length= 0;
2198
2199
  while (key_part_found < end_key_part_found && keypart_map_arg)
2200
  {
2201
    length+= key_part_found->store_length;
2202
    keypart_map_arg >>= 1;
2203
    key_part_found++;
2204
  }
2205
  return length;
2206
}
2207
2208
2209
int EmbeddedInnoDBCursor::innodb_index_read_map(unsigned char * buf,
2210
                                                const unsigned char *key,
2211
                                                key_part_map keypart_map,
2212
                                                enum ha_rkey_function find_flag,
2213
                                                bool allocate_blobs)
2214
{
2215
  uint32_t key_len= calculate_key_len(active_index, keypart_map);
2216
  return  innodb_index_read(buf, key, key_len, find_flag, allocate_blobs);
2217
}
2218
2219
int EmbeddedInnoDBCursor::index_read_idx_map(unsigned char * buf,
2220
                                             uint32_t index,
2221
                                             const unsigned char * key,
2222
                                             key_part_map keypart_map,
2223
                                             enum ha_rkey_function find_flag)
2224
{
2225
  int error, error1;
2226
  error= doStartIndexScan(index, 0);
2227
  if (!error)
2228
  {
2229
    error= innodb_index_read_map(buf, key, keypart_map, find_flag, true);
2230
    error1= doEndIndexScan();
2231
  }
2232
  return error ?  error : error1;
2233
}
2234
2235
int EmbeddedInnoDBCursor::reset()
2236
{
2237
  if (blobroot)
2238
    blobroot->free_root(MYF(0));
2239
2240
  return 0;
2241
}
2242
1283.36.1 by Stewart Smith
fix read_row_from_innodb to respect which buffer the row should be written into from innodb by using the amazing Field::move_field_offset() call properly.
2243
int EmbeddedInnoDBCursor::index_next(unsigned char *buf)
1283.3.1 by Stewart Smith
Skeleton embedded_innodb plugin. Does nothing.
2244
{
1283.3.43 by Stewart Smith
refactor out rnd_next() into read_row_from_innodb() and a call to ib_cursor_next(). This allows us to make the row reading code generic for index scans/lookups.
2245
  int ret= HA_ERR_END_OF_FILE;
1283.28.15 by Stewart Smith
support secondary index scan in embedded_innodb. we add a next_innodb_error member to EmbeddedInnodbCursor as unlike clustered indexes, trying to fetch a row after you have gotten DB_END_OF_INDEX results in a much nastier crash than a simple error code.
2246
1283.60.4 by Stewart Smith
Change when we call ib_cursor_next/prev. Instead of calling it after reading
2247
  if (advance_cursor)
2248
  {
2249
    ib_err_t err= ib_cursor_next(cursor);
2250
    if (err == DB_END_OF_INDEX)
2251
      return HA_ERR_END_OF_FILE;
2252
  }
1283.28.15 by Stewart Smith
support secondary index scan in embedded_innodb. we add a next_innodb_error member to EmbeddedInnodbCursor as unlike clustered indexes, trying to fetch a row after you have gotten DB_END_OF_INDEX results in a much nastier crash than a simple error code.
2253
2254
  tuple= ib_tuple_clear(tuple);
1283.35.97 by Stewart Smith
support tables without an explicit primary key in embedded_innodb by creating a hidden auto_increment primary key. We also have to support tables without an explicit primary key but with an auto increment, so we have our own hidden one. yes, it hurts.
2255
  ret= read_row_from_innodb(buf, cursor, tuple, table,
2256
                            share->has_hidden_primary_key,
2257
                            &hidden_autoinc_pkey_position);
1283.3.42 by Stewart Smith
basic index scan of embedded innodb clustered index
2258
1283.60.4 by Stewart Smith
Change when we call ib_cursor_next/prev. Instead of calling it after reading
2259
  advance_cursor= true;
1283.3.43 by Stewart Smith
refactor out rnd_next() into read_row_from_innodb() and a call to ib_cursor_next(). This allows us to make the row reading code generic for index scans/lookups.
2260
  return ret;
1283.3.1 by Stewart Smith
Skeleton embedded_innodb plugin. Does nothing.
2261
}
2262
1491.1.6 by Jay Pipes
Cursor::ha_index_init() -> Cursor::startIndexScan(). Cursor::ha_index_end() -> Cursor::endIndexScan()
2263
int EmbeddedInnoDBCursor::doEndIndexScan()
1283.3.42 by Stewart Smith
basic index scan of embedded innodb clustered index
2264
{
2265
  active_index= MAX_KEY;
2266
1491.1.10 by Jay Pipes
ha_rnd_init -> startTableScan, rnd_init -> doStartTableScan, ha_rnd_end -> endTableScan, rnd_end -> doEndTableScan
2267
  return doEndTableScan();
1283.3.42 by Stewart Smith
basic index scan of embedded innodb clustered index
2268
}
1283.3.1 by Stewart Smith
Skeleton embedded_innodb plugin. Does nothing.
2269
1283.36.1 by Stewart Smith
fix read_row_from_innodb to respect which buffer the row should be written into from innodb by using the amazing Field::move_field_offset() call properly.
2270
int EmbeddedInnoDBCursor::index_prev(unsigned char *buf)
1283.3.1 by Stewart Smith
Skeleton embedded_innodb plugin. Does nothing.
2271
{
1283.3.44 by Stewart Smith
reverse index scanning for embedded innodb. support index_last and index_prev
2272
  int ret= HA_ERR_END_OF_FILE;
2273
  ib_err_t err;
2274
1283.60.4 by Stewart Smith
Change when we call ib_cursor_next/prev. Instead of calling it after reading
2275
  if (advance_cursor)
2276
    err= ib_cursor_prev(cursor);
2277
1283.3.44 by Stewart Smith
reverse index scanning for embedded innodb. support index_last and index_prev
2278
  if (active_index == 0)
2279
  {
1283.28.1 by Stewart Smith
basic UPDATE row for Embedded InnoDB Engine.
2280
    tuple= ib_tuple_clear(tuple);
1283.35.97 by Stewart Smith
support tables without an explicit primary key in embedded_innodb by creating a hidden auto_increment primary key. We also have to support tables without an explicit primary key but with an auto increment, so we have our own hidden one. yes, it hurts.
2281
    ret= read_row_from_innodb(buf, cursor, tuple, table,
2282
                              share->has_hidden_primary_key,
2283
                              &hidden_autoinc_pkey_position);
1283.3.44 by Stewart Smith
reverse index scanning for embedded innodb. support index_last and index_prev
2284
  }
2285
1283.60.4 by Stewart Smith
Change when we call ib_cursor_next/prev. Instead of calling it after reading
2286
  advance_cursor= true;
2287
1283.3.44 by Stewart Smith
reverse index scanning for embedded innodb. support index_last and index_prev
2288
  return ret;
1283.3.1 by Stewart Smith
Skeleton embedded_innodb plugin. Does nothing.
2289
}
2290
2291
1283.36.1 by Stewart Smith
fix read_row_from_innodb to respect which buffer the row should be written into from innodb by using the amazing Field::move_field_offset() call properly.
2292
int EmbeddedInnoDBCursor::index_first(unsigned char *buf)
1283.3.1 by Stewart Smith
Skeleton embedded_innodb plugin. Does nothing.
2293
{
1283.3.43 by Stewart Smith
refactor out rnd_next() into read_row_from_innodb() and a call to ib_cursor_next(). This allows us to make the row reading code generic for index scans/lookups.
2294
  int ret= HA_ERR_END_OF_FILE;
2295
  ib_err_t err;
2296
1283.21.21 by Stewart Smith
fix up error code checking
2297
  err= ib_cursor_first(cursor);
2298
  if (err != DB_SUCCESS)
2299
  {
2300
    if (err == DB_END_OF_INDEX)
2301
      return HA_ERR_END_OF_FILE;
2302
    else
2303
      return -1; // FIXME
2304
  }
1283.3.42 by Stewart Smith
basic index scan of embedded innodb clustered index
2305
1283.28.15 by Stewart Smith
support secondary index scan in embedded_innodb. we add a next_innodb_error member to EmbeddedInnodbCursor as unlike clustered indexes, trying to fetch a row after you have gotten DB_END_OF_INDEX results in a much nastier crash than a simple error code.
2306
  tuple= ib_tuple_clear(tuple);
1283.35.97 by Stewart Smith
support tables without an explicit primary key in embedded_innodb by creating a hidden auto_increment primary key. We also have to support tables without an explicit primary key but with an auto increment, so we have our own hidden one. yes, it hurts.
2307
  ret= read_row_from_innodb(buf, cursor, tuple, table,
2308
                            share->has_hidden_primary_key,
2309
                            &hidden_autoinc_pkey_position);
1283.60.4 by Stewart Smith
Change when we call ib_cursor_next/prev. Instead of calling it after reading
2310
2311
  advance_cursor= true;
1283.3.42 by Stewart Smith
basic index scan of embedded innodb clustered index
2312
1283.3.43 by Stewart Smith
refactor out rnd_next() into read_row_from_innodb() and a call to ib_cursor_next(). This allows us to make the row reading code generic for index scans/lookups.
2313
  return ret;
1283.3.1 by Stewart Smith
Skeleton embedded_innodb plugin. Does nothing.
2314
}
2315
2316
1283.36.1 by Stewart Smith
fix read_row_from_innodb to respect which buffer the row should be written into from innodb by using the amazing Field::move_field_offset() call properly.
2317
int EmbeddedInnoDBCursor::index_last(unsigned char *buf)
1283.3.1 by Stewart Smith
Skeleton embedded_innodb plugin. Does nothing.
2318
{
1283.3.44 by Stewart Smith
reverse index scanning for embedded innodb. support index_last and index_prev
2319
  int ret= HA_ERR_END_OF_FILE;
2320
  ib_err_t err;
2321
1283.21.21 by Stewart Smith
fix up error code checking
2322
  err= ib_cursor_last(cursor);
2323
  if (err != DB_SUCCESS)
2324
  {
2325
    if (err == DB_END_OF_INDEX)
2326
      return HA_ERR_END_OF_FILE;
2327
    else
2328
      return -1; // FIXME
2329
  }
1283.3.44 by Stewart Smith
reverse index scanning for embedded innodb. support index_last and index_prev
2330
2331
  if (active_index == 0)
2332
  {
1283.28.1 by Stewart Smith
basic UPDATE row for Embedded InnoDB Engine.
2333
    tuple= ib_tuple_clear(tuple);
1283.35.97 by Stewart Smith
support tables without an explicit primary key in embedded_innodb by creating a hidden auto_increment primary key. We also have to support tables without an explicit primary key but with an auto increment, so we have our own hidden one. yes, it hurts.
2334
    ret= read_row_from_innodb(buf, cursor, tuple, table,
2335
                              share->has_hidden_primary_key,
2336
                              &hidden_autoinc_pkey_position);
1283.60.4 by Stewart Smith
Change when we call ib_cursor_next/prev. Instead of calling it after reading
2337
    advance_cursor= true;
1283.3.44 by Stewart Smith
reverse index scanning for embedded innodb. support index_last and index_prev
2338
  }
2339
2340
  return ret;
1283.3.1 by Stewart Smith
Skeleton embedded_innodb plugin. Does nothing.
2341
}
2342
1283.39.8 by Stewart Smith
add support for REPLACE to embedded_innodb. On duplicate key on insert if we have HA_EXTRA_WRITE_CAN_REPLACE set, then we delete the row and insert.
2343
int EmbeddedInnoDBCursor::extra(enum ha_extra_function operation)
2344
{
2345
  switch (operation)
2346
  {
1283.60.10 by Stewart Smith
the memory management for BLOBS is completely insane. For certain types of index lookups we *must* do a copy and clear it *only* in ::reset() or ::extra(). This patch fixes up any valgrind warnings/assertions for embedded_innodb executing type_blob test.
2347
  case HA_EXTRA_FLUSH:
2348
    if (blobroot)
2349
      blobroot->free_root(MYF(0));
2350
    break;
1283.39.8 by Stewart Smith
add support for REPLACE to embedded_innodb. On duplicate key on insert if we have HA_EXTRA_WRITE_CAN_REPLACE set, then we delete the row and insert.
2351
  case HA_EXTRA_WRITE_CAN_REPLACE:
2352
    write_can_replace= true;
2353
    break;
2354
  case HA_EXTRA_WRITE_CANNOT_REPLACE:
2355
    write_can_replace= false;
2356
    break;
2357
  default:
2358
    break;
2359
  }
2360
2361
  return 0;
2362
}
2363
1283.17.11 by Stewart Smith
change data_dictionary.innodb_table_proto to data_dictionary.innodb_table_definition
2364
static int create_table_message_table()
1283.3.25 by Stewart Smith
basic creating of data_dictionary/innodb_table_proto table on startup
2365
{
2366
  ib_tbl_sch_t schema;
2367
  ib_idx_sch_t index_schema;
2368
  ib_trx_t transaction;
2369
  ib_id_t table_id;
1283.17.34 by Stewart Smith
rework error handling in create_table_message_table() for embedded_innodb to not use transaction uninitialised in teh error case of setting up the table structure for innodb.
2370
  ib_err_t err, rollback_err;
1283.19.28 by Stewart Smith
fixup error checking
2371
  ib_bool_t create_db_err;
2372
2373
  create_db_err= ib_database_create("data_dictionary");
2374
  if (create_db_err != IB_TRUE)
2375
    return -1;
2376
2377
  err= ib_table_schema_create(INNODB_TABLE_DEFINITIONS_TABLE, &schema,
2378
                              IB_TBL_COMPACT, 0);
2379
  if (err != DB_SUCCESS)
2380
    return err;
2381
2382
  err= ib_table_schema_add_col(schema, "table_name", IB_VARCHAR, IB_COL_NONE, 0,
2383
                               IB_MAX_TABLE_NAME_LEN);
2384
  if (err != DB_SUCCESS)
1283.17.34 by Stewart Smith
rework error handling in create_table_message_table() for embedded_innodb to not use transaction uninitialised in teh error case of setting up the table structure for innodb.
2385
    goto free_err;
1283.19.28 by Stewart Smith
fixup error checking
2386
2387
  err= ib_table_schema_add_col(schema, "message", IB_BLOB, IB_COL_NONE, 0, 0);
2388
  if (err != DB_SUCCESS)
1283.17.34 by Stewart Smith
rework error handling in create_table_message_table() for embedded_innodb to not use transaction uninitialised in teh error case of setting up the table structure for innodb.
2389
    goto free_err;
1283.19.28 by Stewart Smith
fixup error checking
2390
2391
  err= ib_table_schema_add_index(schema, "PRIMARY_KEY", &index_schema);
2392
  if (err != DB_SUCCESS)
1283.17.34 by Stewart Smith
rework error handling in create_table_message_table() for embedded_innodb to not use transaction uninitialised in teh error case of setting up the table structure for innodb.
2393
    goto free_err;
1283.19.28 by Stewart Smith
fixup error checking
2394
2395
  err= ib_index_schema_add_col(index_schema, "table_name", 0);
2396
  if (err != DB_SUCCESS)
1283.17.34 by Stewart Smith
rework error handling in create_table_message_table() for embedded_innodb to not use transaction uninitialised in teh error case of setting up the table structure for innodb.
2397
    goto free_err;
1283.19.28 by Stewart Smith
fixup error checking
2398
  err= ib_index_schema_set_clustered(index_schema);
2399
  if (err != DB_SUCCESS)
1283.17.34 by Stewart Smith
rework error handling in create_table_message_table() for embedded_innodb to not use transaction uninitialised in teh error case of setting up the table structure for innodb.
2400
    goto free_err;
1283.3.25 by Stewart Smith
basic creating of data_dictionary/innodb_table_proto table on startup
2401
2402
  transaction= ib_trx_begin(IB_TRX_REPEATABLE_READ);
1283.19.28 by Stewart Smith
fixup error checking
2403
  err= ib_schema_lock_exclusive(transaction);
2404
  if (err != DB_SUCCESS)
2405
    goto rollback;
2406
2407
  err= ib_table_create(transaction, schema, &table_id);
2408
  if (err != DB_SUCCESS)
2409
    goto rollback;
2410
2411
  err= ib_trx_commit(transaction);
2412
  if (err != DB_SUCCESS)
2413
    goto rollback;
1283.3.25 by Stewart Smith
basic creating of data_dictionary/innodb_table_proto table on startup
2414
2415
  ib_table_schema_delete(schema);
2416
2417
  return 0;
1283.19.28 by Stewart Smith
fixup error checking
2418
rollback:
2419
  ib_schema_unlock(transaction);
1283.17.34 by Stewart Smith
rework error handling in create_table_message_table() for embedded_innodb to not use transaction uninitialised in teh error case of setting up the table structure for innodb.
2420
  rollback_err= ib_trx_rollback(transaction);
1283.19.28 by Stewart Smith
fixup error checking
2421
  assert(rollback_err == DB_SUCCESS);
1283.17.34 by Stewart Smith
rework error handling in create_table_message_table() for embedded_innodb to not use transaction uninitialised in teh error case of setting up the table structure for innodb.
2422
free_err:
2423
  ib_table_schema_delete(schema);
1283.19.28 by Stewart Smith
fixup error checking
2424
  return err;
1283.3.25 by Stewart Smith
basic creating of data_dictionary/innodb_table_proto table on startup
2425
}
2426
1283.35.51 by Stewart Smith
add support (and tests) for innodb-checksums configuration variable to embedded_innodb
2427
static bool  innobase_use_checksums= true;
1283.35.52 by Stewart Smith
add data_home_dir configuration option to embedded_innodb
2428
static char*  innobase_data_home_dir      = NULL;
1283.35.71 by Stewart Smith
support log_group_home_dir for embedded_innodb
2429
static char*  innobase_log_group_home_dir   = NULL;
1283.35.53 by Stewart Smith
add innodb_doublewrite configuration option to embedded_innodb along with tests for explicitly disabling and enabling it.
2430
static bool innobase_use_doublewrite= true;
1283.35.54 by Stewart Smith
add innodb_io_capacity configuration option for embedded_innodb. Check that both sysvar is set and that we get the right answer from embedded_innodb
2431
static unsigned long srv_io_capacity= 200;
1283.35.56 by Stewart Smith
support innodb_fast_shutdown configuration for embedded_innodb. Currently the tests miss any ability to check what kind of shutdown was actually done... not sure how to get around that.
2432
static unsigned long innobase_fast_shutdown= 1;
1283.35.57 by Stewart Smith
add innodb_file_per_table option to embedded_innodb. Include a test to see that a file is indeed created for it.
2433
static bool srv_file_per_table= false;
1283.35.79 by Stewart Smith
add adaptive_hash_index toggle configuration option to embedded_innodb
2434
static bool innobase_adaptive_hash_index;
1283.35.81 by Stewart Smith
add innodb_adaptive_flushing config option to embedded_innodb
2435
static bool srv_adaptive_flushing;
1283.35.90 by Stewart Smith
add print_verbose_log to embedded_innodB
2436
static bool innobase_print_verbose_log;
1283.35.91 by Stewart Smith
rollback_on_timeout for embedded_innodb
2437
static bool innobase_rollback_on_timeout;
1283.35.92 by Stewart Smith
support innodb_status_file. We allow it to be switched at runtime (unlike innobase plugin) due to this being supported by libinnodb.
2438
static bool innobase_create_status_file;
1283.35.94 by Stewart Smith
add use_sys_malloc for embedded_innodb
2439
static bool srv_use_sys_malloc;
1283.35.64 by Stewart Smith
add file_format configuration option to embedded_innodb. Also add a simple test for changing it
2440
static char*  innobase_file_format_name   = NULL;
1283.35.69 by Stewart Smith
support innodb_flush_method configuration for embedded_innodb. We don't give as clear error message as innobase currently as we just get back 'invalid option' from libinnodb, not anything more descriptive.
2441
static char*  innobase_unix_file_flush_method   = NULL;
1283.35.65 by Stewart Smith
support innodb_flush_trx_log_at_commit config option for embedded_innodb. Test tests that we set it in libinnodb, not that it actually works (as that's hard).
2442
static unsigned long srv_flush_log_at_trx_commit;
1283.35.72 by Stewart Smith
support max_dirty_pages_pct for embedded_innodb
2443
static unsigned long srv_max_buf_pool_modified_pct;
1283.35.74 by Stewart Smith
add max_purge_lag to embedded_innodb. because we should also support black magic configuration variables.
2444
static unsigned long srv_max_purge_lag;
1283.35.75 by Stewart Smith
add lru_old_blocks_pct and lru_block_access_recency configuration options to embedded_innodb. Exciting and new for Drizzle.
2445
static unsigned long innobase_lru_old_blocks_pct;
2446
static unsigned long innobase_lru_block_access_recency;
1283.35.77 by Stewart Smith
add read_io_threads to embedded_innodb configuration variables
2447
static unsigned long innobase_read_io_threads;
1283.35.78 by Stewart Smith
add write_io_threads config variable to embedded_innodb
2448
static unsigned long innobase_write_io_threads;
1283.35.83 by Stewart Smith
add innodb_autoextend_increment config option to embedded_innodb
2449
static unsigned int srv_auto_extend_increment;
1283.35.88 by Stewart Smith
make lock_wait_timeout work for embedded_innodb. A difference is that it is now global, not a Session variable. I don't think this matters to anyone (but is also a limitation of libinnodb). we don't have a 'default' test due to the fact that dtr sets it as a parameter'
2450
static unsigned long innobase_lock_wait_timeout;
1283.35.93 by Stewart Smith
add sync_spin_loops config option to embedded_innodb
2451
static unsigned long srv_n_spin_wait_rounds;
1283.35.84 by Stewart Smith
add innodb_buffer_pool_size config option to embedded_innodb
2452
static int64_t innobase_buffer_pool_size;
1283.35.76 by Stewart Smith
support innodb_open_files for embedded_innodb
2453
static long innobase_open_files;
1283.35.82 by Stewart Smith
add innodb_additional_mem_pool_size config option to embedded_innodb
2454
static long innobase_additional_mem_pool_size;
1283.35.87 by Stewart Smith
add force_recovery to embedded_innodb
2455
static long innobase_force_recovery;
1283.35.89 by Stewart Smith
add log_buffer_size config option to embedded_innodb
2456
static long innobase_log_buffer_size;
1283.13.7 by Stewart Smith
Add innodb_log_file_size and innodb_log_files_in_group to embedded_innodb. Also make their defaults *exactly* the same as the standard innobase plugin (same goes for innodb_data_file_path). This fixse an incompatibility with the log file sizes between innobase and embedded_innodb that would prevent the server being restarted with the other plugin loaded.
2457
static char  default_innodb_data_file_path[]= "ibdata1:10M:autoextend";
2458
static char* innodb_data_file_path= NULL;
2459
2460
static int64_t innodb_log_file_size;
2461
static int64_t innodb_log_files_in_group;
2462
1530.2.6 by Monty Taylor
Moved plugin::Context to module::Context.
2463
static int embedded_innodb_init(drizzled::module::Context &context)
1283.3.1 by Stewart Smith
Skeleton embedded_innodb plugin. Does nothing.
2464
{
1283.23.3 by Stewart Smith
check return code from ib_init().
2465
  ib_err_t err;
1283.3.9 by Stewart Smith
call basic embedded innodb init functions (ib_init() and ib_startup()). Also shutdown functions.
2466
1283.23.3 by Stewart Smith
check return code from ib_init().
2467
  err= ib_init();
2468
  if (err != DB_SUCCESS)
1283.13.10 by Stewart Smith
check all return codes from ib_cfg in plugin init for embedded innodb. Embedded InnoDB 1.0.6 has warn_unused_result for all of these.
2469
    goto innodb_error;
1283.3.9 by Stewart Smith
call basic embedded innodb init functions (ib_init() and ib_startup()). Also shutdown functions.
2470
1283.35.52 by Stewart Smith
add data_home_dir configuration option to embedded_innodb
2471
  if (innobase_data_home_dir)
2472
  {
2473
    err= ib_cfg_set_text("data_home_dir", innobase_data_home_dir);
2474
    if (err != DB_SUCCESS)
2475
      goto innodb_error;
2476
  }
2477
1283.35.71 by Stewart Smith
support log_group_home_dir for embedded_innodb
2478
  if (innobase_log_group_home_dir)
2479
  {
2480
    err= ib_cfg_set_text("log_group_home_dir", innobase_log_group_home_dir);
2481
    if (err != DB_SUCCESS)
2482
      goto innodb_error;
2483
  }
2484
1283.13.7 by Stewart Smith
Add innodb_log_file_size and innodb_log_files_in_group to embedded_innodb. Also make their defaults *exactly* the same as the standard innobase plugin (same goes for innodb_data_file_path). This fixse an incompatibility with the log file sizes between innobase and embedded_innodb that would prevent the server being restarted with the other plugin loaded.
2485
  if (innodb_data_file_path == NULL)
2486
    innodb_data_file_path= default_innodb_data_file_path;
2487
1283.35.90 by Stewart Smith
add print_verbose_log to embedded_innodB
2488
  if (innobase_print_verbose_log)
2489
    err= ib_cfg_set_bool_on("print_verbose_log");
2490
  else
2491
    err= ib_cfg_set_bool_off("print_verbose_log");
2492
2493
  if (err != DB_SUCCESS)
2494
    goto innodb_error;
2495
1283.35.91 by Stewart Smith
rollback_on_timeout for embedded_innodb
2496
  if (innobase_rollback_on_timeout)
2497
    err= ib_cfg_set_bool_on("rollback_on_timeout");
2498
  else
2499
    err= ib_cfg_set_bool_off("rollback_on_timeout");
2500
2501
  if (err != DB_SUCCESS)
2502
    goto innodb_error;
2503
1283.35.53 by Stewart Smith
add innodb_doublewrite configuration option to embedded_innodb along with tests for explicitly disabling and enabling it.
2504
  if (innobase_use_doublewrite)
2505
    err= ib_cfg_set_bool_on("doublewrite");
2506
  else
2507
    err= ib_cfg_set_bool_off("doublewrite");
2508
2509
  if (err != DB_SUCCESS)
2510
    goto innodb_error;
2511
1283.35.79 by Stewart Smith
add adaptive_hash_index toggle configuration option to embedded_innodb
2512
  if (innobase_adaptive_hash_index)
2513
    err= ib_cfg_set_bool_on("adaptive_hash_index");
2514
  else
2515
    err= ib_cfg_set_bool_off("adaptive_hash_index");
2516
2517
  if (err != DB_SUCCESS)
2518
    goto innodb_error;
2519
1283.35.81 by Stewart Smith
add innodb_adaptive_flushing config option to embedded_innodb
2520
  if (srv_adaptive_flushing)
2521
    err= ib_cfg_set_bool_on("adaptive_flushing");
2522
  else
2523
    err= ib_cfg_set_bool_off("adaptive_flushing");
2524
2525
  if (err != DB_SUCCESS)
2526
    goto innodb_error;
2527
1283.35.82 by Stewart Smith
add innodb_additional_mem_pool_size config option to embedded_innodb
2528
  err= ib_cfg_set_int("additional_mem_pool_size", innobase_additional_mem_pool_size);
2529
  if (err != DB_SUCCESS)
2530
    goto innodb_error;
2531
1283.35.83 by Stewart Smith
add innodb_autoextend_increment config option to embedded_innodb
2532
  err= ib_cfg_set_int("autoextend_increment", srv_auto_extend_increment);
2533
  if (err != DB_SUCCESS)
2534
    goto innodb_error;
2535
1283.35.84 by Stewart Smith
add innodb_buffer_pool_size config option to embedded_innodb
2536
  err= ib_cfg_set_int("buffer_pool_size", innobase_buffer_pool_size);
2537
  if (err != DB_SUCCESS)
2538
    goto innodb_error;
2539
1283.35.54 by Stewart Smith
add innodb_io_capacity configuration option for embedded_innodb. Check that both sysvar is set and that we get the right answer from embedded_innodb
2540
  err= ib_cfg_set_int("io_capacity", srv_io_capacity);
2541
  if (err != DB_SUCCESS)
2542
    goto innodb_error;
2543
1283.35.57 by Stewart Smith
add innodb_file_per_table option to embedded_innodb. Include a test to see that a file is indeed created for it.
2544
  if (srv_file_per_table)
2545
    err= ib_cfg_set_bool_on("file_per_table");
2546
  else
2547
    err= ib_cfg_set_bool_off("file_per_table");
2548
2549
  if (err != DB_SUCCESS)
2550
    goto innodb_error;
2551
1283.35.65 by Stewart Smith
support innodb_flush_trx_log_at_commit config option for embedded_innodb. Test tests that we set it in libinnodb, not that it actually works (as that's hard).
2552
  err= ib_cfg_set_int("flush_log_at_trx_commit", srv_flush_log_at_trx_commit);
2553
  if (err != DB_SUCCESS)
2554
    goto innodb_error;
2555
1283.35.69 by Stewart Smith
support innodb_flush_method configuration for embedded_innodb. We don't give as clear error message as innobase currently as we just get back 'invalid option' from libinnodb, not anything more descriptive.
2556
  if (innobase_unix_file_flush_method)
2557
  {
2558
    err= ib_cfg_set_text("flush_method", innobase_unix_file_flush_method);
2559
    if (err != DB_SUCCESS)
2560
      goto innodb_error;
2561
  }
2562
1283.35.87 by Stewart Smith
add force_recovery to embedded_innodb
2563
  err= ib_cfg_set_int("force_recovery", innobase_force_recovery);
2564
  if (err != DB_SUCCESS)
2565
    goto innodb_error;
2566
1283.13.10 by Stewart Smith
check all return codes from ib_cfg in plugin init for embedded innodb. Embedded InnoDB 1.0.6 has warn_unused_result for all of these.
2567
  err= ib_cfg_set_text("data_file_path", innodb_data_file_path);
2568
  if (err != DB_SUCCESS)
2569
    goto innodb_error;
2570
2571
  err= ib_cfg_set_int("log_file_size", innodb_log_file_size);
2572
  if (err != DB_SUCCESS)
2573
    goto innodb_error;
2574
1283.35.89 by Stewart Smith
add log_buffer_size config option to embedded_innodb
2575
  err= ib_cfg_set_int("log_buffer_size", innobase_log_buffer_size);
2576
  if (err != DB_SUCCESS)
2577
    goto innodb_error;
2578
1283.13.10 by Stewart Smith
check all return codes from ib_cfg in plugin init for embedded innodb. Embedded InnoDB 1.0.6 has warn_unused_result for all of these.
2579
  err= ib_cfg_set_int("log_files_in_group", innodb_log_files_in_group);
2580
  if (err != DB_SUCCESS)
2581
    goto innodb_error;
1283.13.7 by Stewart Smith
Add innodb_log_file_size and innodb_log_files_in_group to embedded_innodb. Also make their defaults *exactly* the same as the standard innobase plugin (same goes for innodb_data_file_path). This fixse an incompatibility with the log file sizes between innobase and embedded_innodb that would prevent the server being restarted with the other plugin loaded.
2582
1283.35.51 by Stewart Smith
add support (and tests) for innodb-checksums configuration variable to embedded_innodb
2583
  err= ib_cfg_set_int("checksums", innobase_use_checksums);
2584
  if (err != DB_SUCCESS)
2585
    goto innodb_error;
2586
1283.35.88 by Stewart Smith
make lock_wait_timeout work for embedded_innodb. A difference is that it is now global, not a Session variable. I don't think this matters to anyone (but is also a limitation of libinnodb). we don't have a 'default' test due to the fact that dtr sets it as a parameter'
2587
  err= ib_cfg_set_int("lock_wait_timeout", innobase_lock_wait_timeout);
2588
  if (err != DB_SUCCESS)
2589
    goto innodb_error;
2590
1283.35.72 by Stewart Smith
support max_dirty_pages_pct for embedded_innodb
2591
  err= ib_cfg_set_int("max_dirty_pages_pct", srv_max_buf_pool_modified_pct);
2592
  if (err != DB_SUCCESS)
2593
    goto innodb_error;
2594
1283.35.74 by Stewart Smith
add max_purge_lag to embedded_innodb. because we should also support black magic configuration variables.
2595
  err= ib_cfg_set_int("max_purge_lag", srv_max_purge_lag);
2596
  if (err != DB_SUCCESS)
2597
    goto innodb_error;
2598
1283.35.76 by Stewart Smith
support innodb_open_files for embedded_innodb
2599
  err= ib_cfg_set_int("open_files", innobase_open_files);
2600
  if (err != DB_SUCCESS)
2601
    goto innodb_error;
2602
1283.35.77 by Stewart Smith
add read_io_threads to embedded_innodb configuration variables
2603
  err= ib_cfg_set_int("read_io_threads", innobase_read_io_threads);
2604
  if (err != DB_SUCCESS)
2605
    goto innodb_error;
2606
1283.35.78 by Stewart Smith
add write_io_threads config variable to embedded_innodb
2607
  err= ib_cfg_set_int("write_io_threads", innobase_write_io_threads);
2608
  if (err != DB_SUCCESS)
2609
    goto innodb_error;
2610
1283.35.93 by Stewart Smith
add sync_spin_loops config option to embedded_innodb
2611
  err= ib_cfg_set_int("sync_spin_loops", srv_n_spin_wait_rounds);
2612
  if (err != DB_SUCCESS)
2613
    goto innodb_error;
2614
1283.35.94 by Stewart Smith
add use_sys_malloc for embedded_innodb
2615
  if (srv_use_sys_malloc)
2616
    err= ib_cfg_set_bool_on("use_sys_malloc");
2617
  else
2618
    err= ib_cfg_set_bool_off("use_sys_malloc");
2619
2620
  if (err != DB_SUCCESS)
2621
    goto innodb_error;
2622
1283.52.3 by Stewart Smith
remove mem leak as well as properly show the default innodb_file_format.
2623
  err= ib_startup(innobase_file_format_name);
1283.3.9 by Stewart Smith
call basic embedded innodb init functions (ib_init() and ib_startup()). Also shutdown functions.
2624
  if (err != DB_SUCCESS)
1283.13.10 by Stewart Smith
check all return codes from ib_cfg in plugin init for embedded innodb. Embedded InnoDB 1.0.6 has warn_unused_result for all of these.
2625
    goto innodb_error;
1283.3.9 by Stewart Smith
call basic embedded innodb init functions (ib_init() and ib_startup()). Also shutdown functions.
2626
1283.17.11 by Stewart Smith
change data_dictionary.innodb_table_proto to data_dictionary.innodb_table_definition
2627
  create_table_message_table();
1283.3.25 by Stewart Smith
basic creating of data_dictionary/innodb_table_proto table on startup
2628
1283.3.11 by Stewart Smith
Name the EMBEDDED_INNODB plugin as InnoDB and add two variables (data_file_path and lock_wait_timeout) to make test-run.pl happy.
2629
  embedded_innodb_engine= new EmbeddedInnoDBEngine("InnoDB");
1283.4.16 by Stewart Smith
fix up plugin initialisation and add doRenameTable empty function as it's now pure virtual
2630
  context.add(embedded_innodb_engine);
1283.3.1 by Stewart Smith
Skeleton embedded_innodb plugin. Does nothing.
2631
1283.7.15 by Stewart Smith
merge plugin init with trunk: plugin::Context instead of Registry
2632
  libinnodb_version_func_initialize(context);
1283.10.24 by Stewart Smith
merge trunk
2633
  libinnodb_datadict_dump_func_initialize(context);
1283.31.11 by Stewart Smith
merge trunk
2634
  config_table_function_initialize(context);
1283.32.9 by Stewart Smith
merge trunk
2635
  status_table_function_initialize(context);
1283.3.5 by Stewart Smith
add LIBINNODB_VERSION() function
2636
1283.3.1 by Stewart Smith
Skeleton embedded_innodb plugin. Does nothing.
2637
  return 0;
1283.13.10 by Stewart Smith
check all return codes from ib_cfg in plugin init for embedded innodb. Embedded InnoDB 1.0.6 has warn_unused_result for all of these.
2638
innodb_error:
2639
  fprintf(stderr, _("Error starting Embedded InnoDB %d (%s)\n"),
2640
          err, ib_strerror(err));
2641
  return -1;
1283.3.1 by Stewart Smith
Skeleton embedded_innodb plugin. Does nothing.
2642
}
2643
1283.23.10 by Stewart Smith
merge libinnodb init/de-init with trunk
2644
2645
EmbeddedInnoDBEngine::~EmbeddedInnoDBEngine()
1283.3.1 by Stewart Smith
Skeleton embedded_innodb plugin. Does nothing.
2646
{
1283.23.10 by Stewart Smith
merge libinnodb init/de-init with trunk
2647
  ib_err_t err;
1283.35.56 by Stewart Smith
support innodb_fast_shutdown configuration for embedded_innodb. Currently the tests miss any ability to check what kind of shutdown was actually done... not sure how to get around that.
2648
  ib_shutdown_t shutdown_flag= IB_SHUTDOWN_NORMAL;
2649
2650
  if (innobase_fast_shutdown == 1)
2651
    shutdown_flag= IB_SHUTDOWN_NO_IBUFMERGE_PURGE;
2652
  else if (innobase_fast_shutdown == 2)
2653
    shutdown_flag= IB_SHUTDOWN_NO_BUFPOOL_FLUSH;
2654
2655
  err= ib_shutdown(shutdown_flag);
1283.3.9 by Stewart Smith
call basic embedded innodb init functions (ib_init() and ib_startup()). Also shutdown functions.
2656
2657
  if (err != DB_SUCCESS)
2658
  {
1283.23.10 by Stewart Smith
merge libinnodb init/de-init with trunk
2659
    fprintf(stderr,"Error %d shutting down Embedded InnoDB!\n", err);
1283.3.9 by Stewart Smith
call basic embedded innodb init functions (ib_init() and ib_startup()). Also shutdown functions.
2660
  }
1283.3.1 by Stewart Smith
Skeleton embedded_innodb plugin. Does nothing.
2661
}
2662
1283.35.64 by Stewart Smith
add file_format configuration option to embedded_innodb. Also add a simple test for changing it
2663
static char innodb_file_format_name_storage[100];
2664
2665
static int innodb_file_format_name_validate(Session*, drizzle_sys_var*,
2666
                                            void *save,
2667
                                            drizzle_value *value)
2668
{
2669
  ib_err_t err;
2670
  char buff[100];
2671
  int len= sizeof(buff);
2672
  const char *format= value->val_str(value, buff, &len);
2673
2674
  *static_cast<const char**>(save)= NULL;
2675
2676
  if (format == NULL)
2677
    return 1;
2678
2679
  err= ib_cfg_set_text("file_format", format);
2680
2681
  if (err == DB_SUCCESS)
2682
  {
2683
    strncpy(innodb_file_format_name_storage, format, sizeof(innodb_file_format_name_storage));;
1283.52.2 by Stewart Smith
fix setting of \0 for innodb_file_format. compiler warnings FTW:
2684
    innodb_file_format_name_storage[sizeof(innodb_file_format_name_storage)-1]= 0;
1283.35.64 by Stewart Smith
add file_format configuration option to embedded_innodb. Also add a simple test for changing it
2685
2686
    *static_cast<const char**>(save)= innodb_file_format_name_storage;
2687
    return 0;
2688
  }
2689
  else
2690
    return 1;
2691
}
2692
2693
static void innodb_file_format_name_update(Session*, drizzle_sys_var*,
2694
                                           void *var_ptr,
2695
                                           const void *save)
2696
2697
{
2698
  const char* format;
2699
2700
  assert(var_ptr != NULL);
2701
  assert(save != NULL);
2702
2703
  format= *static_cast<const char*const*>(save);
2704
2705
  /* Format is already set in validate */
2706
    strncpy(innodb_file_format_name_storage, format, sizeof(innodb_file_format_name_storage));;
1283.52.2 by Stewart Smith
fix setting of \0 for innodb_file_format. compiler warnings FTW:
2707
    innodb_file_format_name_storage[sizeof(innodb_file_format_name_storage)-1]= 0;
1283.35.64 by Stewart Smith
add file_format configuration option to embedded_innodb. Also add a simple test for changing it
2708
2709
  *static_cast<const char**>(var_ptr)= innodb_file_format_name_storage;
2710
}
2711
1283.35.75 by Stewart Smith
add lru_old_blocks_pct and lru_block_access_recency configuration options to embedded_innodb. Exciting and new for Drizzle.
2712
static void innodb_lru_old_blocks_pct_update(Session*, drizzle_sys_var*,
2713
                                             void *,
2714
                                             const void *save)
2715
2716
{
2717
  unsigned long pct;
2718
2719
  pct= *static_cast<const unsigned long*>(save);
2720
2721
  ib_err_t err= ib_cfg_set_int("lru_old_blocks_pct", pct);
2722
  if (err == DB_SUCCESS)
2723
    innobase_lru_old_blocks_pct= pct;
2724
}
2725
2726
static void innodb_lru_block_access_recency_update(Session*, drizzle_sys_var*,
2727
                                                   void *,
2728
                                                   const void *save)
2729
2730
{
2731
  unsigned long ms;
2732
2733
  ms= *static_cast<const unsigned long*>(save);
2734
2735
  ib_err_t err= ib_cfg_set_int("lru_block_access_recency", ms);
2736
2737
  if (err == DB_SUCCESS)
2738
    innobase_lru_block_access_recency= ms;
2739
}
2740
1283.35.92 by Stewart Smith
support innodb_status_file. We allow it to be switched at runtime (unlike innobase plugin) due to this being supported by libinnodb.
2741
static void innodb_status_file_update(Session*, drizzle_sys_var*,
2742
                                      void *,
2743
                                      const void *save)
2744
2745
{
2746
  bool status_file_enabled;
2747
  ib_err_t err;
2748
2749
  status_file_enabled= *static_cast<const bool*>(save);
2750
2751
2752
  if (status_file_enabled)
2753
    err= ib_cfg_set_bool_on("status_file");
2754
  else
2755
    err= ib_cfg_set_bool_off("status_file");
2756
2757
  if (err == DB_SUCCESS)
2758
    innobase_create_status_file= status_file_enabled;
2759
}
2760
1283.35.79 by Stewart Smith
add adaptive_hash_index toggle configuration option to embedded_innodb
2761
static DRIZZLE_SYSVAR_BOOL(adaptive_hash_index, innobase_adaptive_hash_index,
2762
  PLUGIN_VAR_NOCMDARG,
2763
  "Enable InnoDB adaptive hash index (enabled by default).  ",
2764
  NULL, NULL, true);
1283.35.75 by Stewart Smith
add lru_old_blocks_pct and lru_block_access_recency configuration options to embedded_innodb. Exciting and new for Drizzle.
2765
1283.35.81 by Stewart Smith
add innodb_adaptive_flushing config option to embedded_innodb
2766
static DRIZZLE_SYSVAR_BOOL(adaptive_flushing, srv_adaptive_flushing,
2767
  PLUGIN_VAR_NOCMDARG,
2768
  "Attempt flushing dirty pages to avoid IO bursts at checkpoints.",
2769
  NULL, NULL, true);
2770
1283.35.82 by Stewart Smith
add innodb_additional_mem_pool_size config option to embedded_innodb
2771
static DRIZZLE_SYSVAR_LONG(additional_mem_pool_size, innobase_additional_mem_pool_size,
2772
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
2773
  "Size of a memory pool InnoDB uses to store data dictionary information and other internal data structures.",
2774
  NULL, NULL, 8*1024*1024L, 512*1024L, LONG_MAX, 1024);
2775
1283.35.83 by Stewart Smith
add innodb_autoextend_increment config option to embedded_innodb
2776
static DRIZZLE_SYSVAR_UINT(autoextend_increment, srv_auto_extend_increment,
2777
  PLUGIN_VAR_RQCMDARG,
2778
  "Data file autoextend increment in megabytes",
2779
  NULL, NULL, 8L, 1L, 1000L, 0);
2780
1283.35.84 by Stewart Smith
add innodb_buffer_pool_size config option to embedded_innodb
2781
static DRIZZLE_SYSVAR_LONGLONG(buffer_pool_size, innobase_buffer_pool_size,
2782
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
2783
  "The size of the memory buffer InnoDB uses to cache data and indexes of its tables.",
2784
  NULL, NULL, 128*1024*1024L, 5*1024*1024L, INT64_MAX, 1024*1024L);
2785
1283.35.51 by Stewart Smith
add support (and tests) for innodb-checksums configuration variable to embedded_innodb
2786
static DRIZZLE_SYSVAR_BOOL(checksums, innobase_use_checksums,
2787
  PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
2788
  "Enable InnoDB checksums validation (enabled by default). "
2789
  "Disable with --skip-innodb-checksums.",
2790
  NULL, NULL, true);
2791
1283.35.52 by Stewart Smith
add data_home_dir configuration option to embedded_innodb
2792
static DRIZZLE_SYSVAR_STR(data_home_dir, innobase_data_home_dir,
2793
  PLUGIN_VAR_READONLY,
2794
  "The common part for InnoDB table spaces.",
2795
  NULL, NULL, NULL);
2796
1283.35.53 by Stewart Smith
add innodb_doublewrite configuration option to embedded_innodb along with tests for explicitly disabling and enabling it.
2797
static DRIZZLE_SYSVAR_BOOL(doublewrite, innobase_use_doublewrite,
2798
  PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
2799
  "Enable InnoDB doublewrite buffer (enabled by default). "
2800
  "Disable with --skip-innodb-doublewrite.",
2801
  NULL, NULL, true);
2802
1283.35.54 by Stewart Smith
add innodb_io_capacity configuration option for embedded_innodb. Check that both sysvar is set and that we get the right answer from embedded_innodb
2803
static DRIZZLE_SYSVAR_ULONG(io_capacity, srv_io_capacity,
2804
  PLUGIN_VAR_RQCMDARG,
2805
  "Number of IOPs the server can do. Tunes the background IO rate",
2806
  NULL, NULL, 200, 100, ~0L, 0);
2807
1283.35.56 by Stewart Smith
support innodb_fast_shutdown configuration for embedded_innodb. Currently the tests miss any ability to check what kind of shutdown was actually done... not sure how to get around that.
2808
static DRIZZLE_SYSVAR_ULONG(fast_shutdown, innobase_fast_shutdown,
2809
  PLUGIN_VAR_OPCMDARG,
2810
  "Speeds up the shutdown process of the InnoDB storage engine. Possible "
2811
  "values are 0, 1 (faster)"
2812
  " or 2 (fastest - crash-like)"
2813
  ".",
2814
  NULL, NULL, 1, 0, 2, 0);
2815
1283.35.57 by Stewart Smith
add innodb_file_per_table option to embedded_innodb. Include a test to see that a file is indeed created for it.
2816
static DRIZZLE_SYSVAR_BOOL(file_per_table, srv_file_per_table,
2817
  PLUGIN_VAR_NOCMDARG,
2818
  "Stores each InnoDB table to an .ibd file in the database dir.",
2819
  NULL, NULL, false);
2820
1283.35.64 by Stewart Smith
add file_format configuration option to embedded_innodb. Also add a simple test for changing it
2821
static DRIZZLE_SYSVAR_STR(file_format, innobase_file_format_name,
2822
  PLUGIN_VAR_RQCMDARG,
2823
  "File format to use for new tables in .ibd files.",
2824
  innodb_file_format_name_validate,
1283.52.3 by Stewart Smith
remove mem leak as well as properly show the default innodb_file_format.
2825
  innodb_file_format_name_update, "Barracuda");
1283.35.64 by Stewart Smith
add file_format configuration option to embedded_innodb. Also add a simple test for changing it
2826
1283.35.65 by Stewart Smith
support innodb_flush_trx_log_at_commit config option for embedded_innodb. Test tests that we set it in libinnodb, not that it actually works (as that's hard).
2827
static DRIZZLE_SYSVAR_ULONG(flush_log_at_trx_commit, srv_flush_log_at_trx_commit,
2828
  PLUGIN_VAR_OPCMDARG,
2829
  "Set to 0 (write and flush once per second),"
2830
  " 1 (write and flush at each commit)"
2831
  " or 2 (write at commit, flush once per second).",
2832
  NULL, NULL, 1, 0, 2, 0);
2833
1283.35.69 by Stewart Smith
support innodb_flush_method configuration for embedded_innodb. We don't give as clear error message as innobase currently as we just get back 'invalid option' from libinnodb, not anything more descriptive.
2834
static DRIZZLE_SYSVAR_STR(flush_method, innobase_unix_file_flush_method,
2835
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
2836
  "With which method to flush data.", NULL, NULL, NULL);
2837
1283.35.87 by Stewart Smith
add force_recovery to embedded_innodb
2838
static DRIZZLE_SYSVAR_LONG(force_recovery, innobase_force_recovery,
2839
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
2840
  "Helps to save your data in case the disk image of the database becomes corrupt.",
2841
  NULL, NULL, 0, 0, 6, 0);
2842
1283.3.11 by Stewart Smith
Name the EMBEDDED_INNODB plugin as InnoDB and add two variables (data_file_path and lock_wait_timeout) to make test-run.pl happy.
2843
static DRIZZLE_SYSVAR_STR(data_file_path, innodb_data_file_path,
2844
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
1283.13.7 by Stewart Smith
Add innodb_log_file_size and innodb_log_files_in_group to embedded_innodb. Also make their defaults *exactly* the same as the standard innobase plugin (same goes for innodb_data_file_path). This fixse an incompatibility with the log file sizes between innobase and embedded_innodb that would prevent the server being restarted with the other plugin loaded.
2845
  "Path to individual files and their sizes.",
1283.3.11 by Stewart Smith
Name the EMBEDDED_INNODB plugin as InnoDB and add two variables (data_file_path and lock_wait_timeout) to make test-run.pl happy.
2846
  NULL, NULL, NULL);
1283.13.7 by Stewart Smith
Add innodb_log_file_size and innodb_log_files_in_group to embedded_innodb. Also make their defaults *exactly* the same as the standard innobase plugin (same goes for innodb_data_file_path). This fixse an incompatibility with the log file sizes between innobase and embedded_innodb that would prevent the server being restarted with the other plugin loaded.
2847
1283.35.71 by Stewart Smith
support log_group_home_dir for embedded_innodb
2848
static DRIZZLE_SYSVAR_STR(log_group_home_dir, innobase_log_group_home_dir,
2849
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
2850
  "Path to InnoDB log files.", NULL, NULL, NULL);
2851
1283.13.7 by Stewart Smith
Add innodb_log_file_size and innodb_log_files_in_group to embedded_innodb. Also make their defaults *exactly* the same as the standard innobase plugin (same goes for innodb_data_file_path). This fixse an incompatibility with the log file sizes between innobase and embedded_innodb that would prevent the server being restarted with the other plugin loaded.
2852
static DRIZZLE_SYSVAR_LONGLONG(log_file_size, innodb_log_file_size,
2853
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
2854
  "Size of each log file in a log group.",
2855
  NULL, NULL, 5*1024*1024L, 1*1024*1024L, INT64_MAX, 1024*1024L);
2856
2857
static DRIZZLE_SYSVAR_LONGLONG(log_files_in_group, innodb_log_files_in_group,
2858
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
2859
  "Number of log files in the log group. InnoDB writes to the files in a circular fashion. Value 3 is recommended here.",
2860
  NULL, NULL, 2, 2, 100, 0);
2861
1283.35.88 by Stewart Smith
make lock_wait_timeout work for embedded_innodb. A difference is that it is now global, not a Session variable. I don't think this matters to anyone (but is also a limitation of libinnodb). we don't have a 'default' test due to the fact that dtr sets it as a parameter'
2862
static DRIZZLE_SYSVAR_ULONG(lock_wait_timeout, innobase_lock_wait_timeout,
2863
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
2864
  "Timeout in seconds an InnoDB transaction may wait for a lock before being rolled back. Values above 100000000 disable the timeout.",
1283.3.11 by Stewart Smith
Name the EMBEDDED_INNODB plugin as InnoDB and add two variables (data_file_path and lock_wait_timeout) to make test-run.pl happy.
2865
  NULL, NULL, 50, 1, 1024 * 1024 * 1024, 0);
2866
1283.35.89 by Stewart Smith
add log_buffer_size config option to embedded_innodb
2867
static DRIZZLE_SYSVAR_LONG(log_buffer_size, innobase_log_buffer_size,
2868
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
2869
  "The size of the buffer which InnoDB uses to write log to the log files on disk.",
2870
  NULL, NULL, 8*1024*1024L, 256*1024L, LONG_MAX, 1024);
2871
1283.35.75 by Stewart Smith
add lru_old_blocks_pct and lru_block_access_recency configuration options to embedded_innodb. Exciting and new for Drizzle.
2872
static DRIZZLE_SYSVAR_ULONG(lru_old_blocks_pct, innobase_lru_old_blocks_pct,
2873
  PLUGIN_VAR_RQCMDARG,
2874
  "Sets the point in the LRU list from where all pages are classified as "
2875
  "old (Advanced users)",
2876
  NULL,
2877
  innodb_lru_old_blocks_pct_update, 37, 5, 95, 0);
2878
2879
static DRIZZLE_SYSVAR_ULONG(lru_block_access_recency, innobase_lru_block_access_recency,
2880
  PLUGIN_VAR_RQCMDARG,
2881
  "Milliseconds between accesses to a block at which it is made young. "
2882
  "0=disabled (Advanced users)",
2883
  NULL,
2884
  innodb_lru_block_access_recency_update, 0, 0, ULONG_MAX, 0);
2885
2886
1283.35.72 by Stewart Smith
support max_dirty_pages_pct for embedded_innodb
2887
static DRIZZLE_SYSVAR_ULONG(max_dirty_pages_pct, srv_max_buf_pool_modified_pct,
2888
  PLUGIN_VAR_RQCMDARG,
2889
  "Percentage of dirty pages allowed in bufferpool.",
2890
  NULL, NULL, 75, 0, 99, 0);
2891
1283.35.74 by Stewart Smith
add max_purge_lag to embedded_innodb. because we should also support black magic configuration variables.
2892
static DRIZZLE_SYSVAR_ULONG(max_purge_lag, srv_max_purge_lag,
2893
  PLUGIN_VAR_RQCMDARG,
2894
  "Desired maximum length of the purge queue (0 = no limit)",
2895
  NULL, NULL, 0, 0, ~0L, 0);
2896
1283.35.91 by Stewart Smith
rollback_on_timeout for embedded_innodb
2897
static DRIZZLE_SYSVAR_BOOL(rollback_on_timeout, innobase_rollback_on_timeout,
2898
  PLUGIN_VAR_OPCMDARG | PLUGIN_VAR_READONLY,
2899
  "Roll back the complete transaction on lock wait timeout, for 4.x compatibility (disabled by default)",
2900
  NULL, NULL, false);
2901
1283.35.76 by Stewart Smith
support innodb_open_files for embedded_innodb
2902
static DRIZZLE_SYSVAR_LONG(open_files, innobase_open_files,
2903
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
2904
  "How many files at the maximum InnoDB keeps open at the same time.",
2905
  NULL, NULL, 300L, 10L, LONG_MAX, 0);
2906
1283.35.77 by Stewart Smith
add read_io_threads to embedded_innodb configuration variables
2907
static DRIZZLE_SYSVAR_ULONG(read_io_threads, innobase_read_io_threads,
2908
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
2909
  "Number of background read I/O threads in InnoDB.",
2910
  NULL, NULL, 4, 1, 64, 0);
2911
1283.35.78 by Stewart Smith
add write_io_threads config variable to embedded_innodb
2912
static DRIZZLE_SYSVAR_ULONG(write_io_threads, innobase_write_io_threads,
2913
  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
2914
  "Number of background write I/O threads in InnoDB.",
2915
  NULL, NULL, 4, 1, 64, 0);
2916
1283.35.90 by Stewart Smith
add print_verbose_log to embedded_innodB
2917
static DRIZZLE_SYSVAR_BOOL(print_verbose_log, innobase_print_verbose_log,
2918
  PLUGIN_VAR_NOCMDARG,
2919
  "Disable if you want to reduce the number of messages written to the log (default: enabled).",
2920
  NULL, NULL, true);
2921
1283.35.92 by Stewart Smith
support innodb_status_file. We allow it to be switched at runtime (unlike innobase plugin) due to this being supported by libinnodb.
2922
static DRIZZLE_SYSVAR_BOOL(status_file, innobase_create_status_file,
2923
  PLUGIN_VAR_OPCMDARG,
2924
  "Enable SHOW INNODB STATUS output in the log",
2925
  NULL, innodb_status_file_update, false);
2926
1283.35.93 by Stewart Smith
add sync_spin_loops config option to embedded_innodb
2927
static DRIZZLE_SYSVAR_ULONG(sync_spin_loops, srv_n_spin_wait_rounds,
2928
  PLUGIN_VAR_RQCMDARG,
2929
  "Count of spin-loop rounds in InnoDB mutexes (30 by default)",
2930
  NULL, NULL, 30L, 0L, ~0L, 0);
2931
1283.35.94 by Stewart Smith
add use_sys_malloc for embedded_innodb
2932
static DRIZZLE_SYSVAR_BOOL(use_sys_malloc, srv_use_sys_malloc,
2933
  PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
2934
  "Use OS memory allocator instead of InnoDB's internal memory allocator",
2935
  NULL, NULL, true);
2936
1283.3.11 by Stewart Smith
Name the EMBEDDED_INNODB plugin as InnoDB and add two variables (data_file_path and lock_wait_timeout) to make test-run.pl happy.
2937
static drizzle_sys_var* innobase_system_variables[]= {
1283.35.79 by Stewart Smith
add adaptive_hash_index toggle configuration option to embedded_innodb
2938
  DRIZZLE_SYSVAR(adaptive_hash_index),
1283.35.81 by Stewart Smith
add innodb_adaptive_flushing config option to embedded_innodb
2939
  DRIZZLE_SYSVAR(adaptive_flushing),
1283.35.82 by Stewart Smith
add innodb_additional_mem_pool_size config option to embedded_innodb
2940
  DRIZZLE_SYSVAR(additional_mem_pool_size),
1283.35.83 by Stewart Smith
add innodb_autoextend_increment config option to embedded_innodb
2941
  DRIZZLE_SYSVAR(autoextend_increment),
1283.35.84 by Stewart Smith
add innodb_buffer_pool_size config option to embedded_innodb
2942
  DRIZZLE_SYSVAR(buffer_pool_size),
1283.35.51 by Stewart Smith
add support (and tests) for innodb-checksums configuration variable to embedded_innodb
2943
  DRIZZLE_SYSVAR(checksums),
1283.35.52 by Stewart Smith
add data_home_dir configuration option to embedded_innodb
2944
  DRIZZLE_SYSVAR(data_home_dir),
1283.35.53 by Stewart Smith
add innodb_doublewrite configuration option to embedded_innodb along with tests for explicitly disabling and enabling it.
2945
  DRIZZLE_SYSVAR(doublewrite),
1283.35.54 by Stewart Smith
add innodb_io_capacity configuration option for embedded_innodb. Check that both sysvar is set and that we get the right answer from embedded_innodb
2946
  DRIZZLE_SYSVAR(io_capacity),
1283.35.56 by Stewart Smith
support innodb_fast_shutdown configuration for embedded_innodb. Currently the tests miss any ability to check what kind of shutdown was actually done... not sure how to get around that.
2947
  DRIZZLE_SYSVAR(fast_shutdown),
1283.35.57 by Stewart Smith
add innodb_file_per_table option to embedded_innodb. Include a test to see that a file is indeed created for it.
2948
  DRIZZLE_SYSVAR(file_per_table),
1283.35.64 by Stewart Smith
add file_format configuration option to embedded_innodb. Also add a simple test for changing it
2949
  DRIZZLE_SYSVAR(file_format),
1283.35.65 by Stewart Smith
support innodb_flush_trx_log_at_commit config option for embedded_innodb. Test tests that we set it in libinnodb, not that it actually works (as that's hard).
2950
  DRIZZLE_SYSVAR(flush_log_at_trx_commit),
1283.35.69 by Stewart Smith
support innodb_flush_method configuration for embedded_innodb. We don't give as clear error message as innobase currently as we just get back 'invalid option' from libinnodb, not anything more descriptive.
2951
  DRIZZLE_SYSVAR(flush_method),
1283.35.87 by Stewart Smith
add force_recovery to embedded_innodb
2952
  DRIZZLE_SYSVAR(force_recovery),
1283.35.71 by Stewart Smith
support log_group_home_dir for embedded_innodb
2953
  DRIZZLE_SYSVAR(log_group_home_dir),
1283.3.11 by Stewart Smith
Name the EMBEDDED_INNODB plugin as InnoDB and add two variables (data_file_path and lock_wait_timeout) to make test-run.pl happy.
2954
  DRIZZLE_SYSVAR(data_file_path),
2955
  DRIZZLE_SYSVAR(lock_wait_timeout),
1283.13.7 by Stewart Smith
Add innodb_log_file_size and innodb_log_files_in_group to embedded_innodb. Also make their defaults *exactly* the same as the standard innobase plugin (same goes for innodb_data_file_path). This fixse an incompatibility with the log file sizes between innobase and embedded_innodb that would prevent the server being restarted with the other plugin loaded.
2956
  DRIZZLE_SYSVAR(log_file_size),
2957
  DRIZZLE_SYSVAR(log_files_in_group),
1283.35.89 by Stewart Smith
add log_buffer_size config option to embedded_innodb
2958
  DRIZZLE_SYSVAR(log_buffer_size),
1283.35.75 by Stewart Smith
add lru_old_blocks_pct and lru_block_access_recency configuration options to embedded_innodb. Exciting and new for Drizzle.
2959
  DRIZZLE_SYSVAR(lru_old_blocks_pct),
2960
  DRIZZLE_SYSVAR(lru_block_access_recency),
1283.35.72 by Stewart Smith
support max_dirty_pages_pct for embedded_innodb
2961
  DRIZZLE_SYSVAR(max_dirty_pages_pct),
1283.35.74 by Stewart Smith
add max_purge_lag to embedded_innodb. because we should also support black magic configuration variables.
2962
  DRIZZLE_SYSVAR(max_purge_lag),
1283.35.76 by Stewart Smith
support innodb_open_files for embedded_innodb
2963
  DRIZZLE_SYSVAR(open_files),
1283.35.77 by Stewart Smith
add read_io_threads to embedded_innodb configuration variables
2964
  DRIZZLE_SYSVAR(read_io_threads),
1283.35.91 by Stewart Smith
rollback_on_timeout for embedded_innodb
2965
  DRIZZLE_SYSVAR(rollback_on_timeout),
1283.35.78 by Stewart Smith
add write_io_threads config variable to embedded_innodb
2966
  DRIZZLE_SYSVAR(write_io_threads),
1283.35.90 by Stewart Smith
add print_verbose_log to embedded_innodB
2967
  DRIZZLE_SYSVAR(print_verbose_log),
1283.35.92 by Stewart Smith
support innodb_status_file. We allow it to be switched at runtime (unlike innobase plugin) due to this being supported by libinnodb.
2968
  DRIZZLE_SYSVAR(status_file),
1283.35.93 by Stewart Smith
add sync_spin_loops config option to embedded_innodb
2969
  DRIZZLE_SYSVAR(sync_spin_loops),
1283.35.94 by Stewart Smith
add use_sys_malloc for embedded_innodb
2970
  DRIZZLE_SYSVAR(use_sys_malloc),
1283.3.11 by Stewart Smith
Name the EMBEDDED_INNODB plugin as InnoDB and add two variables (data_file_path and lock_wait_timeout) to make test-run.pl happy.
2971
  NULL
2972
};
2973
1283.3.1 by Stewart Smith
Skeleton embedded_innodb plugin. Does nothing.
2974
DRIZZLE_DECLARE_PLUGIN
2975
{
2976
  DRIZZLE_VERSION_ID,
1283.3.11 by Stewart Smith
Name the EMBEDDED_INNODB plugin as InnoDB and add two variables (data_file_path and lock_wait_timeout) to make test-run.pl happy.
2977
  "INNODB",
1283.3.1 by Stewart Smith
Skeleton embedded_innodb plugin. Does nothing.
2978
  "1.0",
2979
  "Stewart Smith",
1283.4.8 by Stewart Smith
fix description of embedded innodB
2980
  "Transactional Storage Engine using the Embedded InnoDB Library",
1283.3.1 by Stewart Smith
Skeleton embedded_innodb plugin. Does nothing.
2981
  PLUGIN_LICENSE_GPL,
2982
  embedded_innodb_init,     /* Plugin Init */
1283.3.11 by Stewart Smith
Name the EMBEDDED_INNODB plugin as InnoDB and add two variables (data_file_path and lock_wait_timeout) to make test-run.pl happy.
2983
  innobase_system_variables, /* system variables */
1283.3.1 by Stewart Smith
Skeleton embedded_innodb plugin. Does nothing.
2984
  NULL                /* config options   */
2985
}
2986
DRIZZLE_DECLARE_PLUGIN_END;