~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/handler.cc

  • Committer: Padraig O'Sullivan
  • Date: 2009-07-30 02:39:13 UTC
  • mto: (1115.3.11 captain)
  • mto: This revision was merged to the branch mainline in revision 1121.
  • Revision ID: osullivan.padraig@gmail.com-20090730023913-o2zuocp32l6btnc2
Removing references to MY_BITMAP throughout the code base and updating calls
to MyBitmap in various places to use the new interface.

Show diffs side-by-side

added added

removed removed

Lines of Context:
18
18
 */
19
19
 
20
20
/**
21
 
  @file Cursor.cc
 
21
  @file handler.cc
22
22
 
23
23
  Handler-calling-functions
24
24
*/
25
25
 
26
 
#include "config.h"
27
 
 
28
 
#include <fcntl.h>
29
 
 
30
 
#include "drizzled/my_hash.h"
 
26
#include "drizzled/server_includes.h"
 
27
#include "mysys/hash.h"
31
28
#include "drizzled/error.h"
32
29
#include "drizzled/gettext.h"
33
30
#include "drizzled/probes.h"
34
31
#include "drizzled/sql_parse.h"
35
 
#include "drizzled/optimizer/cost_vector.h"
 
32
#include "drizzled/cost_vect.h"
36
33
#include "drizzled/session.h"
37
34
#include "drizzled/sql_base.h"
38
35
#include "drizzled/transaction_services.h"
39
 
#include "drizzled/replication_services.h"
40
36
#include "drizzled/lock.h"
41
37
#include "drizzled/item/int.h"
42
38
#include "drizzled/item/empty_string.h"
 
39
#include "drizzled/unireg.h" // for mysql_frm_type
43
40
#include "drizzled/field/timestamp.h"
44
41
#include "drizzled/message/table.pb.h"
45
 
#include "drizzled/plugin/client.h"
46
 
#include "drizzled/internal/my_sys.h"
47
 
#include "drizzled/transaction_services.h"
48
42
 
49
43
using namespace std;
50
44
 
51
 
namespace drizzled
52
 
{
 
45
extern drizzled::TransactionServices transaction_services;
 
46
 
 
47
KEY_CREATE_INFO default_key_create_info= { HA_KEY_ALG_UNDEF, 0, {NULL,0}, {NULL,0} };
 
48
 
 
49
/* number of entries in storage_engines[] */
 
50
uint32_t total_ha= 0;
 
51
/* number of storage engines (from storage_engines[]) that support 2pc */
 
52
uint32_t total_ha_2pc= 0;
 
53
/* size of savepoint storage area (see ha_init) */
 
54
uint32_t savepoint_alloc_size= 0;
 
55
 
 
56
const char *ha_row_type[] = {
 
57
  "", "FIXED", "DYNAMIC", "COMPRESSED", "REDUNDANT", "COMPACT", "PAGE", "?","?","?"
 
58
};
 
59
 
 
60
const char *tx_isolation_names[] =
 
61
{ "READ-UNCOMMITTED", "READ-COMMITTED", "REPEATABLE-READ", "SERIALIZABLE",
 
62
  NULL};
 
63
 
 
64
TYPELIB tx_isolation_typelib= {array_elements(tx_isolation_names)-1,"",
 
65
                               tx_isolation_names, NULL};
 
66
 
 
67
 
 
68
/**
 
69
  Register handler error messages for use with my_error().
 
70
 
 
71
  @retval
 
72
    0           OK
 
73
  @retval
 
74
    !=0         Error
 
75
*/
 
76
 
 
77
int ha_init_errors(void)
 
78
{
 
79
#define SETMSG(nr, msg) errmsgs[(nr) - HA_ERR_FIRST]= (msg)
 
80
  const char    **errmsgs;
 
81
 
 
82
  /* Allocate a pointer array for the error message strings. */
 
83
  /* Zerofill it to avoid uninitialized gaps. */
 
84
  if (! (errmsgs= (const char**) malloc(HA_ERR_ERRORS * sizeof(char*))))
 
85
    return 1;
 
86
  memset(errmsgs, 0, HA_ERR_ERRORS * sizeof(char *));
 
87
 
 
88
  /* Set the dedicated error messages. */
 
89
  SETMSG(HA_ERR_KEY_NOT_FOUND,          ER(ER_KEY_NOT_FOUND));
 
90
  SETMSG(HA_ERR_FOUND_DUPP_KEY,         ER(ER_DUP_KEY));
 
91
  SETMSG(HA_ERR_RECORD_CHANGED,         "Update wich is recoverable");
 
92
  SETMSG(HA_ERR_WRONG_INDEX,            "Wrong index given to function");
 
93
  SETMSG(HA_ERR_CRASHED,                ER(ER_NOT_KEYFILE));
 
94
  SETMSG(HA_ERR_WRONG_IN_RECORD,        ER(ER_CRASHED_ON_USAGE));
 
95
  SETMSG(HA_ERR_OUT_OF_MEM,             "Table handler out of memory");
 
96
  SETMSG(HA_ERR_NOT_A_TABLE,            "Incorrect file format '%.64s'");
 
97
  SETMSG(HA_ERR_WRONG_COMMAND,          "Command not supported");
 
98
  SETMSG(HA_ERR_OLD_FILE,               ER(ER_OLD_KEYFILE));
 
99
  SETMSG(HA_ERR_NO_ACTIVE_RECORD,       "No record read in update");
 
100
  SETMSG(HA_ERR_RECORD_DELETED,         "Intern record deleted");
 
101
  SETMSG(HA_ERR_RECORD_FILE_FULL,       ER(ER_RECORD_FILE_FULL));
 
102
  SETMSG(HA_ERR_INDEX_FILE_FULL,        "No more room in index file '%.64s'");
 
103
  SETMSG(HA_ERR_END_OF_FILE,            "End in next/prev/first/last");
 
104
  SETMSG(HA_ERR_UNSUPPORTED,            ER(ER_ILLEGAL_HA));
 
105
  SETMSG(HA_ERR_TO_BIG_ROW,             "Too big row");
 
106
  SETMSG(HA_WRONG_CREATE_OPTION,        "Wrong create option");
 
107
  SETMSG(HA_ERR_FOUND_DUPP_UNIQUE,      ER(ER_DUP_UNIQUE));
 
108
  SETMSG(HA_ERR_UNKNOWN_CHARSET,        "Can't open charset");
 
109
  SETMSG(HA_ERR_WRONG_MRG_TABLE_DEF,    ER(ER_WRONG_MRG_TABLE));
 
110
  SETMSG(HA_ERR_CRASHED_ON_REPAIR,      ER(ER_CRASHED_ON_REPAIR));
 
111
  SETMSG(HA_ERR_CRASHED_ON_USAGE,       ER(ER_CRASHED_ON_USAGE));
 
112
  SETMSG(HA_ERR_LOCK_WAIT_TIMEOUT,      ER(ER_LOCK_WAIT_TIMEOUT));
 
113
  SETMSG(HA_ERR_LOCK_TABLE_FULL,        ER(ER_LOCK_TABLE_FULL));
 
114
  SETMSG(HA_ERR_READ_ONLY_TRANSACTION,  ER(ER_READ_ONLY_TRANSACTION));
 
115
  SETMSG(HA_ERR_LOCK_DEADLOCK,          ER(ER_LOCK_DEADLOCK));
 
116
  SETMSG(HA_ERR_CANNOT_ADD_FOREIGN,     ER(ER_CANNOT_ADD_FOREIGN));
 
117
  SETMSG(HA_ERR_NO_REFERENCED_ROW,      ER(ER_NO_REFERENCED_ROW_2));
 
118
  SETMSG(HA_ERR_ROW_IS_REFERENCED,      ER(ER_ROW_IS_REFERENCED_2));
 
119
  SETMSG(HA_ERR_NO_SAVEPOINT,           "No savepoint with that name");
 
120
  SETMSG(HA_ERR_NON_UNIQUE_BLOCK_SIZE,  "Non unique key block size");
 
121
  SETMSG(HA_ERR_NO_SUCH_TABLE,          "No such table: '%.64s'");
 
122
  SETMSG(HA_ERR_TABLE_EXIST,            ER(ER_TABLE_EXISTS_ERROR));
 
123
  SETMSG(HA_ERR_NO_CONNECTION,          "Could not connect to storage engine");
 
124
  SETMSG(HA_ERR_TABLE_DEF_CHANGED,      ER(ER_TABLE_DEF_CHANGED));
 
125
  SETMSG(HA_ERR_FOREIGN_DUPLICATE_KEY,  "FK constraint would lead to duplicate key");
 
126
  SETMSG(HA_ERR_TABLE_NEEDS_UPGRADE,    ER(ER_TABLE_NEEDS_UPGRADE));
 
127
  SETMSG(HA_ERR_TABLE_READONLY,         ER(ER_OPEN_AS_READONLY));
 
128
  SETMSG(HA_ERR_AUTOINC_READ_FAILED,    ER(ER_AUTOINC_READ_FAILED));
 
129
  SETMSG(HA_ERR_AUTOINC_ERANGE,         ER(ER_WARN_DATA_OUT_OF_RANGE));
 
130
 
 
131
  /* Register the error messages for use with my_error(). */
 
132
  return my_error_register(errmsgs, HA_ERR_FIRST, HA_ERR_LAST);
 
133
}
 
134
 
 
135
 
 
136
/**
 
137
  Unregister handler error messages.
 
138
 
 
139
  @retval
 
140
    0           OK
 
141
  @retval
 
142
    !=0         Error
 
143
*/
 
144
static int ha_finish_errors(void)
 
145
{
 
146
  const char    **errmsgs;
 
147
 
 
148
  /* Allocate a pointer array for the error message strings. */
 
149
  if (! (errmsgs= my_error_unregister(HA_ERR_FIRST, HA_ERR_LAST)))
 
150
    return 1;
 
151
  free((unsigned char*) errmsgs);
 
152
  return 0;
 
153
}
 
154
 
 
155
int ha_init()
 
156
{
 
157
  int error= 0;
 
158
 
 
159
  assert(total_ha < MAX_HA);
 
160
  /*
 
161
    Check if there is a transaction-capable storage engine besides the
 
162
    binary log (which is considered a transaction-capable storage engine in
 
163
    counting total_ha)
 
164
  */
 
165
  savepoint_alloc_size+= sizeof(SAVEPOINT);
 
166
  return error;
 
167
}
 
168
 
 
169
int ha_end()
 
170
{
 
171
  int error= 0;
 
172
 
 
173
  /*
 
174
    This should be eventualy based  on the graceful shutdown flag.
 
175
    So if flag is equal to HA_PANIC_CLOSE, the deallocate
 
176
    the errors.
 
177
  */
 
178
  if (ha_finish_errors())
 
179
    error= 1;
 
180
 
 
181
  return error;
 
182
}
 
183
 
 
184
 
 
185
 
 
186
/* ========================================================================
 
187
 ======================= TRANSACTIONS ===================================*/
 
188
 
 
189
/**
 
190
  Transaction handling in the server
 
191
  ==================================
 
192
 
 
193
  In each client connection, MySQL maintains two transactional
 
194
  states:
 
195
  - a statement transaction,
 
196
  - a standard, also called normal transaction.
 
197
 
 
198
  Historical note
 
199
  ---------------
 
200
  "Statement transaction" is a non-standard term that comes
 
201
  from the times when MySQL supported BerkeleyDB storage engine.
 
202
 
 
203
  First of all, it should be said that in BerkeleyDB auto-commit
 
204
  mode auto-commits operations that are atomic to the storage
 
205
  engine itself, such as a write of a record, and are too
 
206
  high-granular to be atomic from the application perspective
 
207
  (MySQL). One SQL statement could involve many BerkeleyDB
 
208
  auto-committed operations and thus BerkeleyDB auto-commit was of
 
209
  little use to MySQL.
 
210
 
 
211
  Secondly, instead of SQL standard savepoints, BerkeleyDB
 
212
  provided the concept of "nested transactions". In a nutshell,
 
213
  transactions could be arbitrarily nested, but when the parent
 
214
  transaction was committed or aborted, all its child (nested)
 
215
  transactions were handled committed or aborted as well.
 
216
  Commit of a nested transaction, in turn, made its changes
 
217
  visible, but not durable: it destroyed the nested transaction,
 
218
  all its changes would become available to the parent and
 
219
  currently active nested transactions of this parent.
 
220
 
 
221
  So the mechanism of nested transactions was employed to
 
222
  provide "all or nothing" guarantee of SQL statements
 
223
  required by the standard.
 
224
  A nested transaction would be created at start of each SQL
 
225
  statement, and destroyed (committed or aborted) at statement
 
226
  end. Such nested transaction was internally referred to as
 
227
  a "statement transaction" and gave birth to the term.
 
228
 
 
229
  <Historical note ends>
 
230
 
 
231
  Since then a statement transaction is started for each statement
 
232
  that accesses transactional tables or uses the binary log.  If
 
233
  the statement succeeds, the statement transaction is committed.
 
234
  If the statement fails, the transaction is rolled back. Commits
 
235
  of statement transactions are not durable -- each such
 
236
  transaction is nested in the normal transaction, and if the
 
237
  normal transaction is rolled back, the effects of all enclosed
 
238
  statement transactions are undone as well.  Technically,
 
239
  a statement transaction can be viewed as a savepoint which is
 
240
  maintained automatically in order to make effects of one
 
241
  statement atomic.
 
242
 
 
243
  The normal transaction is started by the user and is ended
 
244
  usually upon a user request as well. The normal transaction
 
245
  encloses transactions of all statements issued between
 
246
  its beginning and its end.
 
247
  In autocommit mode, the normal transaction is equivalent
 
248
  to the statement transaction.
 
249
 
 
250
  Since MySQL supports PSEA (pluggable storage engine
 
251
  architecture), more than one transactional engine can be
 
252
  active at a time. Hence transactions, from the server
 
253
  point of view, are always distributed. In particular,
 
254
  transactional state is maintained independently for each
 
255
  engine. In order to commit a transaction the two phase
 
256
  commit protocol is employed.
 
257
 
 
258
  Not all statements are executed in context of a transaction.
 
259
  Administrative and status information statements do not modify
 
260
  engine data, and thus do not start a statement transaction and
 
261
  also have no effect on the normal transaction. Examples of such
 
262
  statements are SHOW STATUS and RESET SLAVE.
 
263
 
 
264
  Similarly DDL statements are not transactional,
 
265
  and therefore a transaction is [almost] never started for a DDL
 
266
  statement. The difference between a DDL statement and a purely
 
267
  administrative statement though is that a DDL statement always
 
268
  commits the current transaction before proceeding, if there is
 
269
  any.
 
270
 
 
271
  At last, SQL statements that work with non-transactional
 
272
  engines also have no effect on the transaction state of the
 
273
  connection. Even though they are written to the binary log,
 
274
  and the binary log is, overall, transactional, the writes
 
275
  are done in "write-through" mode, directly to the binlog
 
276
  file, followed with a OS cache sync, in other words,
 
277
  bypassing the binlog undo log (translog).
 
278
  They do not commit the current normal transaction.
 
279
  A failure of a statement that uses non-transactional tables
 
280
  would cause a rollback of the statement transaction, but
 
281
  in case there no non-transactional tables are used,
 
282
  no statement transaction is started.
 
283
 
 
284
  Data layout
 
285
  -----------
 
286
 
 
287
  The server stores its transaction-related data in
 
288
  session->transaction. This structure has two members of type
 
289
  Session_TRANS. These members correspond to the statement and
 
290
  normal transactions respectively:
 
291
 
 
292
  - session->transaction.stmt contains a list of engines
 
293
  that are participating in the given statement
 
294
  - session->transaction.all contains a list of engines that
 
295
  have participated in any of the statement transactions started
 
296
  within the context of the normal transaction.
 
297
  Each element of the list contains a pointer to the storage
 
298
  engine, engine-specific transactional data, and engine-specific
 
299
  transaction flags.
 
300
 
 
301
  In autocommit mode session->transaction.all is empty.
 
302
  Instead, data of session->transaction.stmt is
 
303
  used to commit/rollback the normal transaction.
 
304
 
 
305
  The list of registered engines has a few important properties:
 
306
  - no engine is registered in the list twice
 
307
  - engines are present in the list a reverse temporal order --
 
308
  new participants are always added to the beginning of the list.
 
309
 
 
310
  Transaction life cycle
 
311
  ----------------------
 
312
 
 
313
  When a new connection is established, session->transaction
 
314
  members are initialized to an empty state.
 
315
  If a statement uses any tables, all affected engines
 
316
  are registered in the statement engine list. In
 
317
  non-autocommit mode, the same engines are registered in
 
318
  the normal transaction list.
 
319
  At the end of the statement, the server issues a commit
 
320
  or a roll back for all engines in the statement list.
 
321
  At this point transaction flags of an engine, if any, are
 
322
  propagated from the statement list to the list of the normal
 
323
  transaction.
 
324
  When commit/rollback is finished, the statement list is
 
325
  cleared. It will be filled in again by the next statement,
 
326
  and emptied again at the next statement's end.
 
327
 
 
328
  The normal transaction is committed in a similar way
 
329
  (by going over all engines in session->transaction.all list)
 
330
  but at different times:
 
331
  - upon COMMIT SQL statement is issued by the user
 
332
  - implicitly, by the server, at the beginning of a DDL statement
 
333
  or SET AUTOCOMMIT={0|1} statement.
 
334
 
 
335
  The normal transaction can be rolled back as well:
 
336
  - if the user has requested so, by issuing ROLLBACK SQL
 
337
  statement
 
338
  - if one of the storage engines requested a rollback
 
339
  by setting session->transaction_rollback_request. This may
 
340
  happen in case, e.g., when the transaction in the engine was
 
341
  chosen a victim of the internal deadlock resolution algorithm
 
342
  and rolled back internally. When such a situation happens, there
 
343
  is little the server can do and the only option is to rollback
 
344
  transactions in all other participating engines.  In this case
 
345
  the rollback is accompanied by an error sent to the user.
 
346
 
 
347
  As follows from the use cases above, the normal transaction
 
348
  is never committed when there is an outstanding statement
 
349
  transaction. In most cases there is no conflict, since
 
350
  commits of the normal transaction are issued by a stand-alone
 
351
  administrative or DDL statement, thus no outstanding statement
 
352
  transaction of the previous statement exists. Besides,
 
353
  all statements that manipulate with the normal transaction
 
354
  are prohibited in stored functions and triggers, therefore
 
355
  no conflicting situation can occur in a sub-statement either.
 
356
  The remaining rare cases when the server explicitly has
 
357
  to commit the statement transaction prior to committing the normal
 
358
  one cover error-handling scenarios (see for example
 
359
  ?).
 
360
 
 
361
  When committing a statement or a normal transaction, the server
 
362
  either uses the two-phase commit protocol, or issues a commit
 
363
  in each engine independently. The two-phase commit protocol
 
364
  is used only if:
 
365
  - all participating engines support two-phase commit (provide
 
366
    StorageEngine::prepare PSEA API call) and
 
367
  - transactions in at least two engines modify data (i.e. are
 
368
  not read-only).
 
369
 
 
370
  Note that the two phase commit is used for
 
371
  statement transactions, even though they are not durable anyway.
 
372
  This is done to ensure logical consistency of data in a multiple-
 
373
  engine transaction.
 
374
  For example, imagine that some day MySQL supports unique
 
375
  constraint checks deferred till the end of statement. In such
 
376
  case a commit in one of the engines may yield ER_DUP_KEY,
 
377
  and MySQL should be able to gracefully abort statement
 
378
  transactions of other participants.
 
379
 
 
380
  After the normal transaction has been committed,
 
381
  session->transaction.all list is cleared.
 
382
 
 
383
  When a connection is closed, the current normal transaction, if
 
384
  any, is rolled back.
 
385
 
 
386
  Roles and responsibilities
 
387
  --------------------------
 
388
 
 
389
  The server has no way to know that an engine participates in
 
390
  the statement and a transaction has been started
 
391
  in it unless the engine says so. Thus, in order to be
 
392
  a part of a transaction, the engine must "register" itself.
 
393
  This is done by invoking trans_register_ha() server call.
 
394
  Normally the engine registers itself whenever handler::external_lock()
 
395
  is called. trans_register_ha() can be invoked many times: if
 
396
  an engine is already registered, the call does nothing.
 
397
  In case autocommit is not set, the engine must register itself
 
398
  twice -- both in the statement list and in the normal transaction
 
399
  list.
 
400
  In which list to register is a parameter of trans_register_ha().
 
401
 
 
402
  Note, that although the registration interface in itself is
 
403
  fairly clear, the current usage practice often leads to undesired
 
404
  effects. E.g. since a call to trans_register_ha() in most engines
 
405
  is embedded into implementation of handler::external_lock(), some
 
406
  DDL statements start a transaction (at least from the server
 
407
  point of view) even though they are not expected to. E.g.
 
408
  CREATE TABLE does not start a transaction, since
 
409
  handler::external_lock() is never called during CREATE TABLE. But
 
410
  CREATE TABLE ... SELECT does, since handler::external_lock() is
 
411
  called for the table that is being selected from. This has no
 
412
  practical effects currently, but must be kept in mind
 
413
  nevertheless.
 
414
 
 
415
  Once an engine is registered, the server will do the rest
 
416
  of the work.
 
417
 
 
418
  During statement execution, whenever any of data-modifying
 
419
  PSEA API methods is used, e.g. handler::write_row() or
 
420
  handler::update_row(), the read-write flag is raised in the
 
421
  statement transaction for the involved engine.
 
422
  Currently All PSEA calls are "traced", and the data can not be
 
423
  changed in a way other than issuing a PSEA call. Important:
 
424
  unless this invariant is preserved the server will not know that
 
425
  a transaction in a given engine is read-write and will not
 
426
  involve the two-phase commit protocol!
 
427
 
 
428
  At the end of a statement, server call
 
429
  ha_autocommit_or_rollback() is invoked. This call in turn
 
430
  invokes StorageEngine::prepare() for every involved engine.
 
431
  Prepare is followed by a call to StorageEngine::commit_one_phase()
 
432
  If a one-phase commit will suffice, StorageEngine::prepare() is not
 
433
  invoked and the server only calls StorageEngine::commit_one_phase().
 
434
  At statement commit, the statement-related read-write engine
 
435
  flag is propagated to the corresponding flag in the normal
 
436
  transaction.  When the commit is complete, the list of registered
 
437
  engines is cleared.
 
438
 
 
439
  Rollback is handled in a similar fashion.
 
440
 
 
441
  Additional notes on DDL and the normal transaction.
 
442
  ---------------------------------------------------
 
443
 
 
444
  DDLs and operations with non-transactional engines
 
445
  do not "register" in session->transaction lists, and thus do not
 
446
  modify the transaction state. Besides, each DDL in
 
447
  MySQL is prefixed with an implicit normal transaction commit
 
448
  (a call to Session::endActiveTransaction()), and thus leaves nothing
 
449
  to modify.
 
450
  However, as it has been pointed out with CREATE TABLE .. SELECT,
 
451
  some DDL statements can start a *new* transaction.
 
452
 
 
453
  Behaviour of the server in this case is currently badly
 
454
  defined.
 
455
  DDL statements use a form of "semantic" logging
 
456
  to maintain atomicity: if CREATE TABLE .. SELECT failed,
 
457
  the newly created table is deleted.
 
458
  In addition, some DDL statements issue interim transaction
 
459
  commits: e.g. ALTER Table issues a commit after data is copied
 
460
  from the original table to the internal temporary table. Other
 
461
  statements, e.g. CREATE TABLE ... SELECT do not always commit
 
462
  after itself.
 
463
  And finally there is a group of DDL statements such as
 
464
  RENAME/DROP Table that doesn't start a new transaction
 
465
  and doesn't commit.
 
466
 
 
467
  This diversity makes it hard to say what will happen if
 
468
  by chance a stored function is invoked during a DDL --
 
469
  whether any modifications it makes will be committed or not
 
470
  is not clear. Fortunately, SQL grammar of few DDLs allows
 
471
  invocation of a stored function.
 
472
 
 
473
  A consistent behaviour is perhaps to always commit the normal
 
474
  transaction after all DDLs, just like the statement transaction
 
475
  is always committed at the end of all statements.
 
476
*/
 
477
 
 
478
/**
 
479
  Register a storage engine for a transaction.
 
480
 
 
481
  Every storage engine MUST call this function when it starts
 
482
  a transaction or a statement (that is it must be called both for the
 
483
  "beginning of transaction" and "beginning of statement").
 
484
  Only storage engines registered for the transaction/statement
 
485
  will know when to commit/rollback it.
 
486
 
 
487
  @note
 
488
    trans_register_ha is idempotent - storage engine may register many
 
489
    times per transaction.
 
490
 
 
491
*/
 
492
void trans_register_ha(Session *session, bool all, StorageEngine *engine)
 
493
{
 
494
  Session_TRANS *trans;
 
495
  Ha_trx_info *ha_info;
 
496
 
 
497
  if (all)
 
498
  {
 
499
    trans= &session->transaction.all;
 
500
    session->server_status|= SERVER_STATUS_IN_TRANS;
 
501
  }
 
502
  else
 
503
    trans= &session->transaction.stmt;
 
504
 
 
505
  ha_info= session->ha_data[engine->getSlot()].ha_info + static_cast<unsigned>(all);
 
506
 
 
507
  if (ha_info->is_started())
 
508
    return; /* already registered, return */
 
509
 
 
510
  ha_info->register_ha(trans, engine);
 
511
 
 
512
  trans->no_2pc|= not engine->has_2pc();
 
513
  if (session->transaction.xid_state.xid.is_null())
 
514
    session->transaction.xid_state.xid.set(session->query_id);
 
515
}
 
516
 
 
517
/**
 
518
  Check if we can skip the two-phase commit.
 
519
 
 
520
  A helper function to evaluate if two-phase commit is mandatory.
 
521
  As a side effect, propagates the read-only/read-write flags
 
522
  of the statement transaction to its enclosing normal transaction.
 
523
 
 
524
  @retval true   we must run a two-phase commit. Returned
 
525
                 if we have at least two engines with read-write changes.
 
526
  @retval false  Don't need two-phase commit. Even if we have two
 
527
                 transactional engines, we can run two independent
 
528
                 commits if changes in one of the engines are read-only.
 
529
*/
 
530
 
 
531
static
 
532
bool
 
533
ha_check_and_coalesce_trx_read_only(Session *session, Ha_trx_info *ha_list,
 
534
                                    bool all)
 
535
{
 
536
  /* The number of storage engines that have actual changes. */
 
537
  unsigned rw_ha_count= 0;
 
538
  Ha_trx_info *ha_info;
 
539
 
 
540
  for (ha_info= ha_list; ha_info; ha_info= ha_info->next())
 
541
  {
 
542
    if (ha_info->is_trx_read_write())
 
543
      ++rw_ha_count;
 
544
 
 
545
    if (! all)
 
546
    {
 
547
      Ha_trx_info *ha_info_all= &session->ha_data[ha_info->engine()->getSlot()].ha_info[1];
 
548
      assert(ha_info != ha_info_all);
 
549
      /*
 
550
        Merge read-only/read-write information about statement
 
551
        transaction to its enclosing normal transaction. Do this
 
552
        only if in a real transaction -- that is, if we know
 
553
        that ha_info_all is registered in session->transaction.all.
 
554
        Since otherwise we only clutter the normal transaction flags.
 
555
      */
 
556
      if (ha_info_all->is_started()) /* false if autocommit. */
 
557
        ha_info_all->coalesce_trx_with(ha_info);
 
558
    }
 
559
    else if (rw_ha_count > 1)
 
560
    {
 
561
      /*
 
562
        It is a normal transaction, so we don't need to merge read/write
 
563
        information up, and the need for two-phase commit has been
 
564
        already established. Break the loop prematurely.
 
565
      */
 
566
      break;
 
567
    }
 
568
  }
 
569
  return rw_ha_count > 1;
 
570
}
 
571
 
 
572
 
 
573
/**
 
574
  @retval
 
575
    0   ok
 
576
  @retval
 
577
    1   transaction was rolled back
 
578
  @retval
 
579
    2   error during commit, data may be inconsistent
 
580
 
 
581
  @todo
 
582
    Since we don't support nested statement transactions in 5.0,
 
583
    we can't commit or rollback stmt transactions while we are inside
 
584
    stored functions or triggers. So we simply do nothing now.
 
585
    TODO: This should be fixed in later ( >= 5.1) releases.
 
586
*/
 
587
int ha_commit_trans(Session *session, bool all)
 
588
{
 
589
  int error= 0, cookie= 0;
 
590
  /*
 
591
    'all' means that this is either an explicit commit issued by
 
592
    user, or an implicit commit issued by a DDL.
 
593
  */
 
594
  Session_TRANS *trans= all ? &session->transaction.all : &session->transaction.stmt;
 
595
  bool is_real_trans= all || session->transaction.all.ha_list == 0;
 
596
  Ha_trx_info *ha_info= trans->ha_list;
 
597
 
 
598
  /*
 
599
    We must not commit the normal transaction if a statement
 
600
    transaction is pending. Otherwise statement transaction
 
601
    flags will not get propagated to its normal transaction's
 
602
    counterpart.
 
603
  */
 
604
  assert(session->transaction.stmt.ha_list == NULL ||
 
605
              trans == &session->transaction.stmt);
 
606
 
 
607
  if (ha_info)
 
608
  {
 
609
    bool must_2pc;
 
610
 
 
611
    if (is_real_trans && wait_if_global_read_lock(session, 0, 0))
 
612
    {
 
613
      ha_rollback_trans(session, all);
 
614
      return 1;
 
615
    }
 
616
 
 
617
    must_2pc= ha_check_and_coalesce_trx_read_only(session, ha_info, all);
 
618
 
 
619
    if (!trans->no_2pc && must_2pc)
 
620
    {
 
621
      for (; ha_info && !error; ha_info= ha_info->next())
 
622
      {
 
623
        int err;
 
624
        StorageEngine *engine= ha_info->engine();
 
625
        /*
 
626
          Do not call two-phase commit if this particular
 
627
          transaction is read-only. This allows for simpler
 
628
          implementation in engines that are always read-only.
 
629
        */
 
630
        if (! ha_info->is_trx_read_write())
 
631
          continue;
 
632
        /*
 
633
          Sic: we know that prepare() is not NULL since otherwise
 
634
          trans->no_2pc would have been set.
 
635
        */
 
636
        if ((err= engine->prepare(session, all)))
 
637
        {
 
638
          my_error(ER_ERROR_DURING_COMMIT, MYF(0), err);
 
639
          error= 1;
 
640
        }
 
641
        status_var_increment(session->status_var.ha_prepare_count);
 
642
      }
 
643
      if (error)
 
644
      {
 
645
        ha_rollback_trans(session, all);
 
646
        error= 1;
 
647
        goto end;
 
648
      }
 
649
    }
 
650
    error=ha_commit_one_phase(session, all) ? (cookie ? 2 : 1) : 0;
 
651
end:
 
652
    if (is_real_trans)
 
653
      start_waiting_global_read_lock(session);
 
654
  }
 
655
  return error;
 
656
}
 
657
 
 
658
/**
 
659
  @note
 
660
  This function does not care about global read lock. A caller should.
 
661
*/
 
662
int ha_commit_one_phase(Session *session, bool all)
 
663
{
 
664
  int error=0;
 
665
  Session_TRANS *trans=all ? &session->transaction.all : &session->transaction.stmt;
 
666
  bool is_real_trans=all || session->transaction.all.ha_list == 0;
 
667
  Ha_trx_info *ha_info= trans->ha_list, *ha_info_next;
 
668
  if (ha_info)
 
669
  {
 
670
    for (; ha_info; ha_info= ha_info_next)
 
671
    {
 
672
      int err;
 
673
      StorageEngine *engine= ha_info->engine();
 
674
      if ((err= engine->commit(session, all)))
 
675
      {
 
676
        my_error(ER_ERROR_DURING_COMMIT, MYF(0), err);
 
677
        error=1;
 
678
      }
 
679
      status_var_increment(session->status_var.ha_commit_count);
 
680
      ha_info_next= ha_info->next();
 
681
      ha_info->reset(); /* keep it conveniently zero-filled */
 
682
    }
 
683
    trans->ha_list= 0;
 
684
    trans->no_2pc=0;
 
685
    if (is_real_trans)
 
686
      session->transaction.xid_state.xid.null();
 
687
    if (all)
 
688
    {
 
689
      session->variables.tx_isolation=session->session_tx_isolation;
 
690
      session->transaction.cleanup();
 
691
    }
 
692
  }
 
693
  return error;
 
694
}
 
695
 
 
696
 
 
697
int ha_rollback_trans(Session *session, bool all)
 
698
{
 
699
  int error=0;
 
700
  Session_TRANS *trans=all ? &session->transaction.all : &session->transaction.stmt;
 
701
  Ha_trx_info *ha_info= trans->ha_list, *ha_info_next;
 
702
  bool is_real_trans=all || session->transaction.all.ha_list == 0;
 
703
 
 
704
  /*
 
705
    We must not rollback the normal transaction if a statement
 
706
    transaction is pending.
 
707
  */
 
708
  assert(session->transaction.stmt.ha_list == NULL ||
 
709
              trans == &session->transaction.stmt);
 
710
 
 
711
  if (ha_info)
 
712
  {
 
713
    for (; ha_info; ha_info= ha_info_next)
 
714
    {
 
715
      int err;
 
716
      StorageEngine *engine= ha_info->engine();
 
717
      if ((err= engine->rollback(session, all)))
 
718
      { // cannot happen
 
719
        my_error(ER_ERROR_DURING_ROLLBACK, MYF(0), err);
 
720
        error=1;
 
721
      }
 
722
      status_var_increment(session->status_var.ha_rollback_count);
 
723
      ha_info_next= ha_info->next();
 
724
      ha_info->reset(); /* keep it conveniently zero-filled */
 
725
    }
 
726
    trans->ha_list= 0;
 
727
    trans->no_2pc=0;
 
728
    if (is_real_trans)
 
729
      session->transaction.xid_state.xid.null();
 
730
    if (all)
 
731
    {
 
732
      session->variables.tx_isolation=session->session_tx_isolation;
 
733
      session->transaction.cleanup();
 
734
    }
 
735
  }
 
736
  if (all)
 
737
    session->transaction_rollback_request= false;
 
738
 
 
739
  /*
 
740
    If a non-transactional table was updated, warn; don't warn if this is a
 
741
    slave thread (because when a slave thread executes a ROLLBACK, it has
 
742
    been read from the binary log, so it's 100% sure and normal to produce
 
743
    error ER_WARNING_NOT_COMPLETE_ROLLBACK. If we sent the warning to the
 
744
    slave SQL thread, it would not stop the thread but just be printed in
 
745
    the error log; but we don't want users to wonder why they have this
 
746
    message in the error log, so we don't send it.
 
747
  */
 
748
  if (is_real_trans && session->transaction.all.modified_non_trans_table && session->killed != Session::KILL_CONNECTION)
 
749
    push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
 
750
                 ER_WARNING_NOT_COMPLETE_ROLLBACK,
 
751
                 ER(ER_WARNING_NOT_COMPLETE_ROLLBACK));
 
752
  return error;
 
753
}
 
754
 
 
755
/**
 
756
  This is used to commit or rollback a single statement depending on
 
757
  the value of error.
 
758
 
 
759
  @note
 
760
    Note that if the autocommit is on, then the following call inside
 
761
    InnoDB will commit or rollback the whole transaction (= the statement). The
 
762
    autocommit mechanism built into InnoDB is based on counting locks, but if
 
763
    the user has used LOCK TABLES then that mechanism does not know to do the
 
764
    commit.
 
765
*/
 
766
int ha_autocommit_or_rollback(Session *session, int error)
 
767
{
 
768
  if (session->transaction.stmt.ha_list)
 
769
  {
 
770
    if (!error)
 
771
    {
 
772
      if (ha_commit_trans(session, 0))
 
773
        error= 1;
 
774
    }
 
775
    else
 
776
    {
 
777
      (void) ha_rollback_trans(session, 0);
 
778
      if (session->transaction_rollback_request)
 
779
        (void) ha_rollback(session);
 
780
    }
 
781
 
 
782
    session->variables.tx_isolation=session->session_tx_isolation;
 
783
  }
 
784
 
 
785
  return error;
 
786
}
 
787
 
 
788
 
 
789
 
 
790
 
 
791
/**
 
792
  return the list of XID's to a client, the same way SHOW commands do.
 
793
 
 
794
  @note
 
795
    I didn't find in XA specs that an RM cannot return the same XID twice,
 
796
    so mysql_xa_recover does not filter XID's to ensure uniqueness.
 
797
    It can be easily fixed later, if necessary.
 
798
*/
 
799
bool mysql_xa_recover(Session *session)
 
800
{
 
801
  List<Item> field_list;
 
802
  Protocol *protocol= session->protocol;
 
803
  int i=0;
 
804
  XID_STATE *xs;
 
805
 
 
806
  field_list.push_back(new Item_int("formatID", 0, MY_INT32_NUM_DECIMAL_DIGITS));
 
807
  field_list.push_back(new Item_int("gtrid_length", 0, MY_INT32_NUM_DECIMAL_DIGITS));
 
808
  field_list.push_back(new Item_int("bqual_length", 0, MY_INT32_NUM_DECIMAL_DIGITS));
 
809
  field_list.push_back(new Item_empty_string("data",XIDDATASIZE));
 
810
 
 
811
  if (protocol->sendFields(&field_list,
 
812
                           Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
 
813
    return 1;
 
814
 
 
815
  pthread_mutex_lock(&LOCK_xid_cache);
 
816
  while ((xs= (XID_STATE*)hash_element(&xid_cache, i++)))
 
817
  {
 
818
    if (xs->xa_state==XA_PREPARED)
 
819
    {
 
820
      protocol->prepareForResend();
 
821
      protocol->store((int64_t)xs->xid.formatID);
 
822
      protocol->store((int64_t)xs->xid.gtrid_length);
 
823
      protocol->store((int64_t)xs->xid.bqual_length);
 
824
      protocol->store(xs->xid.data, xs->xid.gtrid_length+xs->xid.bqual_length);
 
825
      if (protocol->write())
 
826
      {
 
827
        pthread_mutex_unlock(&LOCK_xid_cache);
 
828
        return 1;
 
829
      }
 
830
    }
 
831
  }
 
832
 
 
833
  pthread_mutex_unlock(&LOCK_xid_cache);
 
834
  session->my_eof();
 
835
  return 0;
 
836
}
 
837
 
 
838
 
 
839
int ha_rollback_to_savepoint(Session *session, SAVEPOINT *sv)
 
840
{
 
841
  int error= 0;
 
842
  Session_TRANS *trans= &session->transaction.all;
 
843
  Ha_trx_info *ha_info, *ha_info_next;
 
844
 
 
845
  trans->no_2pc=0;
 
846
  /*
 
847
    rolling back to savepoint in all storage engines that were part of the
 
848
    transaction when the savepoint was set
 
849
  */
 
850
  for (ha_info= sv->ha_list; ha_info; ha_info= ha_info->next())
 
851
  {
 
852
    int err;
 
853
    StorageEngine *engine= ha_info->engine();
 
854
    assert(engine);
 
855
    if ((err= engine->savepoint_rollback(session,
 
856
                                         (void *)(sv+1))))
 
857
    { // cannot happen
 
858
      my_error(ER_ERROR_DURING_ROLLBACK, MYF(0), err);
 
859
      error= 1;
 
860
    }
 
861
    status_var_increment(session->status_var.ha_savepoint_rollback_count);
 
862
    trans->no_2pc|= not engine->has_2pc();
 
863
  }
 
864
  /*
 
865
    rolling back the transaction in all storage engines that were not part of
 
866
    the transaction when the savepoint was set
 
867
  */
 
868
  for (ha_info= trans->ha_list; ha_info != sv->ha_list;
 
869
       ha_info= ha_info_next)
 
870
  {
 
871
    int err;
 
872
    StorageEngine *engine= ha_info->engine();
 
873
    if ((err= engine->rollback(session, !(0))))
 
874
    { // cannot happen
 
875
      my_error(ER_ERROR_DURING_ROLLBACK, MYF(0), err);
 
876
      error= 1;
 
877
    }
 
878
    status_var_increment(session->status_var.ha_rollback_count);
 
879
    ha_info_next= ha_info->next();
 
880
    ha_info->reset(); /* keep it conveniently zero-filled */
 
881
  }
 
882
  trans->ha_list= sv->ha_list;
 
883
  return error;
 
884
}
 
885
 
 
886
/**
 
887
  @note
 
888
  according to the sql standard (ISO/IEC 9075-2:2003)
 
889
  section "4.33.4 SQL-statements and transaction states",
 
890
  SAVEPOINT is *not* transaction-initiating SQL-statement
 
891
*/
 
892
int ha_savepoint(Session *session, SAVEPOINT *sv)
 
893
{
 
894
  int error= 0;
 
895
  Session_TRANS *trans= &session->transaction.all;
 
896
  Ha_trx_info *ha_info= trans->ha_list;
 
897
  for (; ha_info; ha_info= ha_info->next())
 
898
  {
 
899
    int err;
 
900
    StorageEngine *engine= ha_info->engine();
 
901
    assert(engine);
 
902
#ifdef NOT_IMPLEMENTED /*- TODO (examine this againt the original code base) */
 
903
    if (! engine->savepoint_set)
 
904
    {
 
905
      my_error(ER_CHECK_NOT_IMPLEMENTED, MYF(0), "SAVEPOINT");
 
906
      error= 1;
 
907
      break;
 
908
    } 
 
909
#endif
 
910
    if ((err= engine->savepoint_set(session, (void *)(sv+1))))
 
911
    { // cannot happen
 
912
      my_error(ER_GET_ERRNO, MYF(0), err);
 
913
      error= 1;
 
914
    }
 
915
    status_var_increment(session->status_var.ha_savepoint_count);
 
916
  }
 
917
  /*
 
918
    Remember the list of registered storage engines. All new
 
919
    engines are prepended to the beginning of the list.
 
920
  */
 
921
  sv->ha_list= trans->ha_list;
 
922
  return error;
 
923
}
 
924
 
 
925
int ha_release_savepoint(Session *session, SAVEPOINT *sv)
 
926
{
 
927
  int error= 0;
 
928
  Ha_trx_info *ha_info= sv->ha_list;
 
929
 
 
930
  for (; ha_info; ha_info= ha_info->next())
 
931
  {
 
932
    int err;
 
933
    StorageEngine *engine= ha_info->engine();
 
934
    /* Savepoint life time is enclosed into transaction life time. */
 
935
    assert(engine);
 
936
    if ((err= engine->savepoint_release(session,
 
937
                                        (void *)(sv+1))))
 
938
    { // cannot happen
 
939
      my_error(ER_GET_ERRNO, MYF(0), err);
 
940
      error= 1;
 
941
    }
 
942
  }
 
943
  return error;
 
944
}
 
945
 
 
946
 
 
947
 
 
948
 
53
949
 
54
950
/****************************************************************************
55
 
** General Cursor functions
 
951
** General handler functions
56
952
****************************************************************************/
57
 
Cursor::Cursor(plugin::StorageEngine &engine_arg,
58
 
               TableShare &share_arg)
59
 
  : table_share(&share_arg), table(0),
60
 
    estimation_rows_to_insert(0), engine(&engine_arg),
61
 
    ref(0), in_range_check_pushed_down(false),
62
 
    key_used_on_scan(MAX_KEY), active_index(MAX_KEY),
63
 
    ref_length(sizeof(internal::my_off_t)),
64
 
    inited(NONE),
65
 
    locked(false), implicit_emptied(0),
66
 
    next_insert_id(0), insert_id_for_cur_row(0)
67
 
{ }
68
 
 
69
 
Cursor::~Cursor(void)
 
953
handler::~handler(void)
70
954
{
71
955
  assert(locked == false);
72
956
  /* TODO: assert(inited == NONE); */
73
957
}
74
958
 
75
959
 
76
 
Cursor *Cursor::clone(memory::Root *mem_root)
 
960
handler *handler::clone(MEM_ROOT *mem_root)
77
961
{
78
 
  Cursor *new_handler= table->s->db_type()->getCursor(*table->s, mem_root);
79
 
 
 
962
  handler *new_handler= get_new_handler(table->s, mem_root, table->s->db_type());
80
963
  /*
81
 
    Allocate Cursor->ref here because otherwise ha_open will allocate it
 
964
    Allocate handler->ref here because otherwise ha_open will allocate it
82
965
    on this->table->mem_root and we will not be able to reclaim that memory
83
 
    when the clone Cursor object is destroyed.
 
966
    when the clone handler object is destroyed.
84
967
  */
85
968
  if (!(new_handler->ref= (unsigned char*) alloc_root(mem_root, ALIGN_SIZE(ref_length)*2)))
86
969
    return NULL;
92
975
  return NULL;
93
976
}
94
977
 
95
 
int Cursor::ha_index_init(uint32_t idx, bool sorted)
 
978
int handler::ha_index_init(uint32_t idx, bool sorted)
96
979
{
97
980
  int result;
98
981
  assert(inited == NONE);
102
985
  return result;
103
986
}
104
987
 
105
 
int Cursor::ha_index_end()
 
988
int handler::ha_index_end()
106
989
{
107
990
  assert(inited==INDEX);
108
991
  inited=NONE;
110
993
  return(index_end());
111
994
}
112
995
 
113
 
int Cursor::ha_rnd_init(bool scan)
 
996
int handler::ha_rnd_init(bool scan)
114
997
{
115
998
  int result;
116
999
  assert(inited==NONE || (inited==RND && scan));
119
1002
  return result;
120
1003
}
121
1004
 
122
 
int Cursor::ha_rnd_end()
 
1005
int handler::ha_rnd_end()
123
1006
{
124
1007
  assert(inited==RND);
125
1008
  inited=NONE;
126
1009
  return(rnd_end());
127
1010
}
128
1011
 
129
 
int Cursor::ha_index_or_rnd_end()
 
1012
int handler::ha_index_or_rnd_end()
130
1013
{
131
1014
  return inited == INDEX ? ha_index_end() : inited == RND ? ha_rnd_end() : 0;
132
1015
}
133
1016
 
134
 
void Cursor::ha_start_bulk_insert(ha_rows rows)
 
1017
handler::Table_flags handler::ha_table_flags() const
 
1018
{
 
1019
  return cached_table_flags;
 
1020
}
 
1021
 
 
1022
void handler::ha_start_bulk_insert(ha_rows rows)
135
1023
{
136
1024
  estimation_rows_to_insert= rows;
137
1025
  start_bulk_insert(rows);
138
1026
}
139
1027
 
140
 
int Cursor::ha_end_bulk_insert()
 
1028
int handler::ha_end_bulk_insert()
141
1029
{
142
1030
  estimation_rows_to_insert= 0;
143
1031
  return end_bulk_insert();
144
1032
}
145
1033
 
146
 
void Cursor::change_table_ptr(Table *table_arg, TableShare *share)
 
1034
void handler::change_table_ptr(Table *table_arg, TableShare *share)
147
1035
{
148
1036
  table= table_arg;
149
1037
  table_share= share;
150
1038
}
151
1039
 
152
 
const key_map *Cursor::keys_to_use_for_scanning()
 
1040
const key_map *handler::keys_to_use_for_scanning()
153
1041
{
154
1042
  return &key_map_empty;
155
1043
}
156
1044
 
157
 
bool Cursor::has_transactions()
 
1045
bool handler::has_transactions()
158
1046
{
159
 
  return (table->s->db_type()->check_flag(HTON_BIT_DOES_TRANSACTIONS));
 
1047
  return (ha_table_flags() & HA_NO_TRANSACTIONS) == 0;
160
1048
}
161
1049
 
162
 
void Cursor::ha_statistic_increment(ulong system_status_var::*offset) const
 
1050
void handler::ha_statistic_increment(ulong SSV::*offset) const
163
1051
{
164
1052
  status_var_increment(table->in_use->status_var.*offset);
165
1053
}
166
1054
 
167
 
void **Cursor::ha_data(Session *session) const
 
1055
void **handler::ha_data(Session *session) const
168
1056
{
169
 
  return session->getEngineData(engine);
 
1057
  return session_ha_data(session, engine);
170
1058
}
171
1059
 
172
 
Session *Cursor::ha_session(void) const
 
1060
Session *handler::ha_session(void) const
173
1061
{
174
1062
  assert(!table || !table->in_use || table->in_use == current_session);
175
1063
  return (table && table->in_use) ? table->in_use : current_session;
176
1064
}
177
1065
 
178
1066
 
179
 
bool Cursor::is_fatal_error(int error, uint32_t flags)
 
1067
bool handler::is_fatal_error(int error, uint32_t flags)
180
1068
{
181
1069
  if (!error ||
182
1070
      ((flags & HA_CHECK_DUP_KEY) &&
187
1075
}
188
1076
 
189
1077
 
190
 
ha_rows Cursor::records() { return stats.records; }
191
 
uint64_t Cursor::tableSize() { return stats.index_file_length + stats.data_file_length; }
192
 
uint64_t Cursor::rowSize() { return table->getRecordLength() + table->sizeFields(); }
 
1078
ha_rows handler::records() { return stats.records; }
193
1079
 
194
1080
/**
195
 
  Open database-Cursor.
 
1081
  Open database-handler.
196
1082
 
197
1083
  Try O_RDONLY if cannot open as O_RDWR
198
1084
  Don't wait for locks if not HA_OPEN_WAIT_IF_LOCKED is set
199
1085
*/
200
 
int Cursor::ha_open(Table *table_arg, const char *name, int mode,
 
1086
int handler::ha_open(Table *table_arg, const char *name, int mode,
201
1087
                     int test_if_locked)
202
1088
{
203
1089
  int error;
206
1092
  assert(table->s == table_share);
207
1093
  assert(alloc_root_inited(&table->mem_root));
208
1094
 
209
 
  if ((error=open(name, mode, test_if_locked)))
 
1095
  if ((error=open(name,mode,test_if_locked)))
210
1096
  {
211
1097
    if ((error == EACCES || error == EROFS) && mode == O_RDWR &&
212
 
        (table->db_stat & HA_TRY_READ_ONLY))
 
1098
        (table->db_stat & HA_TRY_READ_ONLY))
213
1099
    {
214
1100
      table->db_stat|=HA_READ_ONLY;
215
1101
      error=open(name,O_RDONLY,test_if_locked);
217
1103
  }
218
1104
  if (error)
219
1105
  {
220
 
    errno= error;                            /* Safeguard */
 
1106
    my_errno= error;                            /* Safeguard */
221
1107
  }
222
1108
  else
223
1109
  {
225
1111
      table->db_stat|=HA_READ_ONLY;
226
1112
    (void) extra(HA_EXTRA_NO_READCHECK);        // Not needed in SQL
227
1113
 
228
 
    /* ref is already allocated for us if we're called from Cursor::clone() */
 
1114
    /* ref is already allocated for us if we're called from handler::clone() */
229
1115
    if (!ref && !(ref= (unsigned char*) alloc_root(&table->mem_root,
230
1116
                                          ALIGN_SIZE(ref_length)*2)))
231
1117
    {
234
1120
    }
235
1121
    else
236
1122
      dup_ref=ref+ALIGN_SIZE(ref_length);
 
1123
    cached_table_flags= table_flags();
237
1124
  }
238
1125
  return error;
239
1126
}
245
1132
  handlers for random position
246
1133
*/
247
1134
 
248
 
int Cursor::rnd_pos_by_record(unsigned char *record)
 
1135
int handler::rnd_pos_by_record(unsigned char *record)
249
1136
{
250
1137
  register int error;
251
1138
 
264
1151
  This is never called for InnoDB tables, as these table types
265
1152
  has the HA_STATS_RECORDS_IS_EXACT set.
266
1153
*/
267
 
int Cursor::read_first_row(unsigned char * buf, uint32_t primary_key)
 
1154
int handler::read_first_row(unsigned char * buf, uint32_t primary_key)
268
1155
{
269
1156
  register int error;
270
1157
 
271
 
  ha_statistic_increment(&system_status_var::ha_read_first_count);
 
1158
  ha_statistic_increment(&SSV::ha_read_first_count);
272
1159
 
273
1160
  /*
274
1161
    If there is very few deleted rows in the table, find the first row by
276
1163
    TODO remove the test for HA_READ_ORDER
277
1164
  */
278
1165
  if (stats.deleted < 10 || primary_key >= MAX_KEY ||
279
 
      !(table->index_flags(primary_key) & HA_READ_ORDER))
 
1166
      !(index_flags(primary_key, 0, 0) & HA_READ_ORDER))
280
1167
  {
281
1168
    (void) ha_rnd_init(1);
282
1169
    while ((error= rnd_next(buf)) == HA_ERR_RECORD_DELETED) ;
316
1203
}
317
1204
 
318
1205
 
319
 
void Cursor::adjust_next_insert_id_after_explicit_value(uint64_t nr)
 
1206
void handler::adjust_next_insert_id_after_explicit_value(uint64_t nr)
320
1207
{
321
1208
  /*
322
1209
    If we have set Session::next_insert_id previously and plan to insert an
390
1277
    reserved for us.
391
1278
 
392
1279
  - In both cases, for the following rows we use those reserved values without
393
 
    calling the Cursor again (we just progress in the interval, computing
 
1280
    calling the handler again (we just progress in the interval, computing
394
1281
    each new value from the previous one). Until we have exhausted them, then
395
1282
    we either take the next provided interval or call get_auto_increment()
396
1283
    again to reserve a new interval.
437
1324
#define AUTO_INC_DEFAULT_NB_MAX_BITS 16
438
1325
#define AUTO_INC_DEFAULT_NB_MAX ((1 << AUTO_INC_DEFAULT_NB_MAX_BITS) - 1)
439
1326
 
440
 
int Cursor::update_auto_increment()
 
1327
int handler::update_auto_increment()
441
1328
{
442
1329
  uint64_t nr, nb_reserved_values;
443
1330
  bool append= false;
482
1369
    else
483
1370
    {
484
1371
      /*
485
 
        Cursor::estimation_rows_to_insert was set by
486
 
        Cursor::ha_start_bulk_insert(); if 0 it means "unknown".
 
1372
        handler::estimation_rows_to_insert was set by
 
1373
        handler::ha_start_bulk_insert(); if 0 it means "unknown".
487
1374
      */
488
1375
      uint32_t nb_already_reserved_intervals=
489
1376
        session->auto_inc_intervals_in_cur_stmt_for_binlog.nb_elements();
585
1472
 
586
1473
 
587
1474
/**
588
 
  Reserves an interval of auto_increment values from the Cursor.
 
1475
  Reserves an interval of auto_increment values from the handler.
589
1476
 
590
1477
  offset and increment means that we want values to be of the form
591
1478
  offset + N * increment, where N>=0 is integer.
596
1483
  @param offset
597
1484
  @param increment
598
1485
  @param nb_desired_values   how many values we want
599
 
  @param first_value         (OUT) the first value reserved by the Cursor
600
 
  @param nb_reserved_values  (OUT) how many values the Cursor reserved
 
1486
  @param first_value         (OUT) the first value reserved by the handler
 
1487
  @param nb_reserved_values  (OUT) how many values the handler reserved
601
1488
*/
602
 
 
603
 
void Cursor::ha_release_auto_increment()
 
1489
void handler::get_auto_increment(uint64_t ,
 
1490
                                 uint64_t ,
 
1491
                                 uint64_t ,
 
1492
                                 uint64_t *first_value,
 
1493
                                 uint64_t *nb_reserved_values)
 
1494
{
 
1495
  uint64_t nr;
 
1496
  int error;
 
1497
 
 
1498
  (void) extra(HA_EXTRA_KEYREAD);
 
1499
  table->mark_columns_used_by_index_no_reset(table->s->next_number_index);
 
1500
  index_init(table->s->next_number_index, 1);
 
1501
  if (table->s->next_number_keypart == 0)
 
1502
  {                                             // Autoincrement at key-start
 
1503
    error=index_last(table->record[1]);
 
1504
    /*
 
1505
      MySQL implicitely assumes such method does locking (as MySQL decides to
 
1506
      use nr+increment without checking again with the handler, in
 
1507
      handler::update_auto_increment()), so reserves to infinite.
 
1508
    */
 
1509
    *nb_reserved_values= UINT64_MAX;
 
1510
  }
 
1511
  else
 
1512
  {
 
1513
    unsigned char key[MAX_KEY_LENGTH];
 
1514
    key_copy(key, table->record[0],
 
1515
             table->key_info + table->s->next_number_index,
 
1516
             table->s->next_number_key_offset);
 
1517
    error= index_read_map(table->record[1], key,
 
1518
                          make_prev_keypart_map(table->s->next_number_keypart),
 
1519
                          HA_READ_PREFIX_LAST);
 
1520
    /*
 
1521
      MySQL needs to call us for next row: assume we are inserting ("a",null)
 
1522
      here, we return 3, and next this statement will want to insert
 
1523
      ("b",null): there is no reason why ("b",3+1) would be the good row to
 
1524
      insert: maybe it already exists, maybe 3+1 is too large...
 
1525
    */
 
1526
    *nb_reserved_values= 1;
 
1527
  }
 
1528
 
 
1529
  if (error)
 
1530
    nr=1;
 
1531
  else
 
1532
    nr= ((uint64_t) table->next_number_field->
 
1533
         val_int_offset(table->s->rec_buff_length)+1);
 
1534
  index_end();
 
1535
  (void) extra(HA_EXTRA_NO_KEYREAD);
 
1536
  *first_value= nr;
 
1537
}
 
1538
 
 
1539
 
 
1540
void handler::ha_release_auto_increment()
604
1541
{
605
1542
  release_auto_increment();
606
1543
  insert_id_for_cur_row= 0;
616
1553
  }
617
1554
}
618
1555
 
619
 
void Cursor::drop_table(const char *)
 
1556
 
 
1557
void handler::print_keydup_error(uint32_t key_nr, const char *msg)
 
1558
{
 
1559
  /* Write the duplicated key in the error message */
 
1560
  char key[MAX_KEY_LENGTH];
 
1561
  String str(key,sizeof(key),system_charset_info);
 
1562
 
 
1563
  if (key_nr == MAX_KEY)
 
1564
  {
 
1565
    /* Key is unknown */
 
1566
    str.copy("", 0, system_charset_info);
 
1567
    my_printf_error(ER_DUP_ENTRY, msg, MYF(0), str.c_ptr(), "*UNKNOWN*");
 
1568
  }
 
1569
  else
 
1570
  {
 
1571
    /* Table is opened and defined at this point */
 
1572
    key_unpack(&str,table,(uint32_t) key_nr);
 
1573
    uint32_t max_length=DRIZZLE_ERRMSG_SIZE-(uint32_t) strlen(msg);
 
1574
    if (str.length() >= max_length)
 
1575
    {
 
1576
      str.length(max_length-4);
 
1577
      str.append(STRING_WITH_LEN("..."));
 
1578
    }
 
1579
    my_printf_error(ER_DUP_ENTRY, msg,
 
1580
                    MYF(0), str.c_ptr(), table->key_info[key_nr].name);
 
1581
  }
 
1582
}
 
1583
 
 
1584
 
 
1585
/**
 
1586
  Print error that we got from handler function.
 
1587
 
 
1588
  @note
 
1589
    In case of delete table it's only safe to use the following parts of
 
1590
    the 'table' structure:
 
1591
    - table->s->path
 
1592
    - table->alias
 
1593
*/
 
1594
void handler::print_error(int error, myf errflag)
 
1595
{
 
1596
  int textno=ER_GET_ERRNO;
 
1597
  switch (error) {
 
1598
  case EACCES:
 
1599
    textno=ER_OPEN_AS_READONLY;
 
1600
    break;
 
1601
  case EAGAIN:
 
1602
    textno=ER_FILE_USED;
 
1603
    break;
 
1604
  case ENOENT:
 
1605
    textno=ER_FILE_NOT_FOUND;
 
1606
    break;
 
1607
  case HA_ERR_KEY_NOT_FOUND:
 
1608
  case HA_ERR_NO_ACTIVE_RECORD:
 
1609
  case HA_ERR_END_OF_FILE:
 
1610
    textno=ER_KEY_NOT_FOUND;
 
1611
    break;
 
1612
  case HA_ERR_WRONG_MRG_TABLE_DEF:
 
1613
    textno=ER_WRONG_MRG_TABLE;
 
1614
    break;
 
1615
  case HA_ERR_FOUND_DUPP_KEY:
 
1616
  {
 
1617
    uint32_t key_nr=get_dup_key(error);
 
1618
    if ((int) key_nr >= 0)
 
1619
    {
 
1620
      print_keydup_error(key_nr, ER(ER_DUP_ENTRY_WITH_KEY_NAME));
 
1621
      return;
 
1622
    }
 
1623
    textno=ER_DUP_KEY;
 
1624
    break;
 
1625
  }
 
1626
  case HA_ERR_FOREIGN_DUPLICATE_KEY:
 
1627
  {
 
1628
    uint32_t key_nr= get_dup_key(error);
 
1629
    if ((int) key_nr >= 0)
 
1630
    {
 
1631
      uint32_t max_length;
 
1632
      /* Write the key in the error message */
 
1633
      char key[MAX_KEY_LENGTH];
 
1634
      String str(key,sizeof(key),system_charset_info);
 
1635
      /* Table is opened and defined at this point */
 
1636
      key_unpack(&str,table,(uint32_t) key_nr);
 
1637
      max_length= (DRIZZLE_ERRMSG_SIZE-
 
1638
                   (uint32_t) strlen(ER(ER_FOREIGN_DUPLICATE_KEY)));
 
1639
      if (str.length() >= max_length)
 
1640
      {
 
1641
        str.length(max_length-4);
 
1642
        str.append(STRING_WITH_LEN("..."));
 
1643
      }
 
1644
      my_error(ER_FOREIGN_DUPLICATE_KEY, MYF(0), table_share->table_name.str,
 
1645
        str.c_ptr(), key_nr+1);
 
1646
      return;
 
1647
    }
 
1648
    textno= ER_DUP_KEY;
 
1649
    break;
 
1650
  }
 
1651
  case HA_ERR_FOUND_DUPP_UNIQUE:
 
1652
    textno=ER_DUP_UNIQUE;
 
1653
    break;
 
1654
  case HA_ERR_RECORD_CHANGED:
 
1655
    textno=ER_CHECKREAD;
 
1656
    break;
 
1657
  case HA_ERR_CRASHED:
 
1658
    textno=ER_NOT_KEYFILE;
 
1659
    break;
 
1660
  case HA_ERR_WRONG_IN_RECORD:
 
1661
    textno= ER_CRASHED_ON_USAGE;
 
1662
    break;
 
1663
  case HA_ERR_CRASHED_ON_USAGE:
 
1664
    textno=ER_CRASHED_ON_USAGE;
 
1665
    break;
 
1666
  case HA_ERR_NOT_A_TABLE:
 
1667
    textno= error;
 
1668
    break;
 
1669
  case HA_ERR_CRASHED_ON_REPAIR:
 
1670
    textno=ER_CRASHED_ON_REPAIR;
 
1671
    break;
 
1672
  case HA_ERR_OUT_OF_MEM:
 
1673
    textno=ER_OUT_OF_RESOURCES;
 
1674
    break;
 
1675
  case HA_ERR_WRONG_COMMAND:
 
1676
    textno=ER_ILLEGAL_HA;
 
1677
    break;
 
1678
  case HA_ERR_OLD_FILE:
 
1679
    textno=ER_OLD_KEYFILE;
 
1680
    break;
 
1681
  case HA_ERR_UNSUPPORTED:
 
1682
    textno=ER_UNSUPPORTED_EXTENSION;
 
1683
    break;
 
1684
  case HA_ERR_RECORD_FILE_FULL:
 
1685
  case HA_ERR_INDEX_FILE_FULL:
 
1686
    textno=ER_RECORD_FILE_FULL;
 
1687
    break;
 
1688
  case HA_ERR_LOCK_WAIT_TIMEOUT:
 
1689
    textno=ER_LOCK_WAIT_TIMEOUT;
 
1690
    break;
 
1691
  case HA_ERR_LOCK_TABLE_FULL:
 
1692
    textno=ER_LOCK_TABLE_FULL;
 
1693
    break;
 
1694
  case HA_ERR_LOCK_DEADLOCK:
 
1695
    textno=ER_LOCK_DEADLOCK;
 
1696
    break;
 
1697
  case HA_ERR_READ_ONLY_TRANSACTION:
 
1698
    textno=ER_READ_ONLY_TRANSACTION;
 
1699
    break;
 
1700
  case HA_ERR_CANNOT_ADD_FOREIGN:
 
1701
    textno=ER_CANNOT_ADD_FOREIGN;
 
1702
    break;
 
1703
  case HA_ERR_ROW_IS_REFERENCED:
 
1704
  {
 
1705
    String str;
 
1706
    get_error_message(error, &str);
 
1707
    my_error(ER_ROW_IS_REFERENCED_2, MYF(0), str.c_ptr_safe());
 
1708
    return;
 
1709
  }
 
1710
  case HA_ERR_NO_REFERENCED_ROW:
 
1711
  {
 
1712
    String str;
 
1713
    get_error_message(error, &str);
 
1714
    my_error(ER_NO_REFERENCED_ROW_2, MYF(0), str.c_ptr_safe());
 
1715
    return;
 
1716
  }
 
1717
  case HA_ERR_TABLE_DEF_CHANGED:
 
1718
    textno=ER_TABLE_DEF_CHANGED;
 
1719
    break;
 
1720
  case HA_ERR_NO_SUCH_TABLE:
 
1721
    my_error(ER_NO_SUCH_TABLE, MYF(0), table_share->db.str,
 
1722
             table_share->table_name.str);
 
1723
    return;
 
1724
  case HA_ERR_RBR_LOGGING_FAILED:
 
1725
    textno= ER_BINLOG_ROW_LOGGING_FAILED;
 
1726
    break;
 
1727
  case HA_ERR_DROP_INDEX_FK:
 
1728
  {
 
1729
    const char *ptr= "???";
 
1730
    uint32_t key_nr= get_dup_key(error);
 
1731
    if ((int) key_nr >= 0)
 
1732
      ptr= table->key_info[key_nr].name;
 
1733
    my_error(ER_DROP_INDEX_FK, MYF(0), ptr);
 
1734
    return;
 
1735
  }
 
1736
  case HA_ERR_TABLE_NEEDS_UPGRADE:
 
1737
    textno=ER_TABLE_NEEDS_UPGRADE;
 
1738
    break;
 
1739
  case HA_ERR_TABLE_READONLY:
 
1740
    textno= ER_OPEN_AS_READONLY;
 
1741
    break;
 
1742
  case HA_ERR_AUTOINC_READ_FAILED:
 
1743
    textno= ER_AUTOINC_READ_FAILED;
 
1744
    break;
 
1745
  case HA_ERR_AUTOINC_ERANGE:
 
1746
    textno= ER_WARN_DATA_OUT_OF_RANGE;
 
1747
    break;
 
1748
  case HA_ERR_LOCK_OR_ACTIVE_TRANSACTION:
 
1749
    my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
 
1750
               ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
 
1751
    return;
 
1752
  default:
 
1753
    {
 
1754
      /* The error was "unknown" to this function.
 
1755
         Ask handler if it has got a message for this error */
 
1756
      bool temporary= false;
 
1757
      String str;
 
1758
      temporary= get_error_message(error, &str);
 
1759
      if (!str.is_empty())
 
1760
      {
 
1761
        const char* engine_name= engine->getName().c_str();
 
1762
        if (temporary)
 
1763
          my_error(ER_GET_TEMPORARY_ERRMSG, MYF(0), error, str.ptr(),
 
1764
                   engine_name);
 
1765
        else
 
1766
          my_error(ER_GET_ERRMSG, MYF(0), error, str.ptr(), engine_name);
 
1767
      }
 
1768
      else
 
1769
      {
 
1770
              my_error(ER_GET_ERRNO,errflag,error);
 
1771
      }
 
1772
      return;
 
1773
    }
 
1774
  }
 
1775
  my_error(textno, errflag, table_share->table_name.str, error);
 
1776
}
 
1777
 
 
1778
 
 
1779
/**
 
1780
  Return an error message specific to this handler.
 
1781
 
 
1782
  @param error  error code previously returned by handler
 
1783
  @param buf    pointer to String where to add error message
 
1784
 
 
1785
  @return
 
1786
    Returns true if this is a temporary error
 
1787
*/
 
1788
bool handler::get_error_message(int , String* )
 
1789
{
 
1790
  return false;
 
1791
}
 
1792
 
 
1793
 
 
1794
/* Code left, but Drizzle has no legacy yet (while MySQL did) */
 
1795
int handler::check_old_types()
 
1796
{
 
1797
  return 0;
 
1798
}
 
1799
 
 
1800
/**
 
1801
  @return
 
1802
    key if error because of duplicated keys
 
1803
*/
 
1804
uint32_t handler::get_dup_key(int error)
 
1805
{
 
1806
  table->file->errkey  = (uint32_t) -1;
 
1807
  if (error == HA_ERR_FOUND_DUPP_KEY || error == HA_ERR_FOREIGN_DUPLICATE_KEY ||
 
1808
      error == HA_ERR_FOUND_DUPP_UNIQUE ||
 
1809
      error == HA_ERR_DROP_INDEX_FK)
 
1810
    info(HA_STATUS_ERRKEY | HA_STATUS_NO_LOCK);
 
1811
  return(table->file->errkey);
 
1812
}
 
1813
 
 
1814
void handler::drop_table(const char *name)
620
1815
{
621
1816
  close();
 
1817
  engine->deleteTable(ha_session(), name);
622
1818
}
623
1819
 
624
1820
 
637
1833
  @retval
638
1834
    HA_ADMIN_NOT_IMPLEMENTED
639
1835
*/
640
 
int Cursor::ha_check(Session *, HA_CHECK_OPT *)
 
1836
int handler::ha_check(Session *, HA_CHECK_OPT *)
641
1837
{
642
1838
  return HA_ADMIN_OK;
643
1839
}
649
1845
 
650
1846
inline
651
1847
void
652
 
Cursor::setTransactionReadWrite()
 
1848
handler::mark_trx_read_write()
653
1849
{
654
 
  ResourceContext *resource_context= ha_session()->getResourceContext(engine);
 
1850
  Ha_trx_info *ha_info= &ha_session()->ha_data[engine->getSlot()].ha_info[0];
655
1851
  /*
656
1852
    When a storage engine method is called, the transaction must
657
1853
    have been started, unless it's a DDL call, for which the
660
1856
    Unfortunately here we can't know know for sure if the engine
661
1857
    has registered the transaction or not, so we must check.
662
1858
  */
663
 
  if (resource_context->isStarted())
 
1859
  if (ha_info->is_started())
664
1860
  {
665
 
    resource_context->markModifiedData();
 
1861
    /*
 
1862
      table_share can be NULL in ha_delete_table(). See implementation
 
1863
      of standalone function ha_delete_table() in sql_base.cc.
 
1864
    */
 
1865
//    if (table_share == NULL || table_share->tmp_table == NO_TMP_TABLE)
 
1866
      ha_info->set_trx_read_write();
666
1867
  }
667
1868
}
668
1869
 
 
1870
/**
 
1871
  Bulk update row: public interface.
 
1872
 
 
1873
  @sa handler::bulk_update_row()
 
1874
*/
 
1875
 
 
1876
int
 
1877
handler::ha_bulk_update_row(const unsigned char *old_data, unsigned char *new_data,
 
1878
                            uint32_t *dup_key_found)
 
1879
{
 
1880
  mark_trx_read_write();
 
1881
 
 
1882
  return bulk_update_row(old_data, new_data, dup_key_found);
 
1883
}
 
1884
 
669
1885
 
670
1886
/**
671
1887
  Delete all rows: public interface.
672
1888
 
673
 
  @sa Cursor::delete_all_rows()
674
 
 
675
 
  @note
676
 
 
677
 
  This is now equalivalent to TRUNCATE TABLE.
 
1889
  @sa handler::delete_all_rows()
678
1890
*/
679
1891
 
680
1892
int
681
 
Cursor::ha_delete_all_rows()
 
1893
handler::ha_delete_all_rows()
682
1894
{
683
 
  setTransactionReadWrite();
684
 
 
685
 
  int result= delete_all_rows();
686
 
 
687
 
  if (result == 0)
688
 
  {
689
 
    /** 
690
 
     * Trigger post-truncate notification to plugins... 
691
 
     *
692
 
     * @todo Make TransactionServices generic to AfterTriggerServices
693
 
     * or similar...
694
 
     */
695
 
    Session *const session= table->in_use;
696
 
    TransactionServices &transaction_services= TransactionServices::singleton();
697
 
    transaction_services.truncateTable(session, table);
698
 
  }
699
 
 
700
 
  return result;
 
1895
  mark_trx_read_write();
 
1896
 
 
1897
  return delete_all_rows();
701
1898
}
702
1899
 
703
1900
 
704
1901
/**
705
1902
  Reset auto increment: public interface.
706
1903
 
707
 
  @sa Cursor::reset_auto_increment()
 
1904
  @sa handler::reset_auto_increment()
708
1905
*/
709
1906
 
710
1907
int
711
 
Cursor::ha_reset_auto_increment(uint64_t value)
 
1908
handler::ha_reset_auto_increment(uint64_t value)
712
1909
{
713
 
  setTransactionReadWrite();
 
1910
  mark_trx_read_write();
714
1911
 
715
1912
  return reset_auto_increment(value);
716
1913
}
717
1914
 
718
1915
 
719
1916
/**
 
1917
  Optimize table: public interface.
 
1918
 
 
1919
  @sa handler::optimize()
 
1920
*/
 
1921
 
 
1922
int
 
1923
handler::ha_optimize(Session* session, HA_CHECK_OPT* check_opt)
 
1924
{
 
1925
  mark_trx_read_write();
 
1926
 
 
1927
  return optimize(session, check_opt);
 
1928
}
 
1929
 
 
1930
 
 
1931
/**
720
1932
  Analyze table: public interface.
721
1933
 
722
 
  @sa Cursor::analyze()
 
1934
  @sa handler::analyze()
723
1935
*/
724
1936
 
725
1937
int
726
 
Cursor::ha_analyze(Session* session, HA_CHECK_OPT*)
 
1938
handler::ha_analyze(Session* session, HA_CHECK_OPT* check_opt)
727
1939
{
728
 
  setTransactionReadWrite();
 
1940
  mark_trx_read_write();
729
1941
 
730
 
  return analyze(session);
 
1942
  return analyze(session, check_opt);
731
1943
}
732
1944
 
733
1945
/**
734
1946
  Disable indexes: public interface.
735
1947
 
736
 
  @sa Cursor::disable_indexes()
 
1948
  @sa handler::disable_indexes()
737
1949
*/
738
1950
 
739
1951
int
740
 
Cursor::ha_disable_indexes(uint32_t mode)
 
1952
handler::ha_disable_indexes(uint32_t mode)
741
1953
{
742
 
  setTransactionReadWrite();
 
1954
  mark_trx_read_write();
743
1955
 
744
1956
  return disable_indexes(mode);
745
1957
}
748
1960
/**
749
1961
  Enable indexes: public interface.
750
1962
 
751
 
  @sa Cursor::enable_indexes()
 
1963
  @sa handler::enable_indexes()
752
1964
*/
753
1965
 
754
1966
int
755
 
Cursor::ha_enable_indexes(uint32_t mode)
 
1967
handler::ha_enable_indexes(uint32_t mode)
756
1968
{
757
 
  setTransactionReadWrite();
 
1969
  mark_trx_read_write();
758
1970
 
759
1971
  return enable_indexes(mode);
760
1972
}
763
1975
/**
764
1976
  Discard or import tablespace: public interface.
765
1977
 
766
 
  @sa Cursor::discard_or_import_tablespace()
 
1978
  @sa handler::discard_or_import_tablespace()
767
1979
*/
768
1980
 
769
1981
int
770
 
Cursor::ha_discard_or_import_tablespace(bool discard)
 
1982
handler::ha_discard_or_import_tablespace(bool discard)
771
1983
{
772
 
  setTransactionReadWrite();
 
1984
  mark_trx_read_write();
773
1985
 
774
1986
  return discard_or_import_tablespace(discard);
775
1987
}
776
1988
 
 
1989
 
 
1990
/**
 
1991
  Prepare for alter: public interface.
 
1992
 
 
1993
  Called to prepare an *online* ALTER.
 
1994
 
 
1995
  @sa handler::prepare_for_alter()
 
1996
*/
 
1997
 
 
1998
void
 
1999
handler::ha_prepare_for_alter()
 
2000
{
 
2001
  mark_trx_read_write();
 
2002
 
 
2003
  prepare_for_alter();
 
2004
}
 
2005
 
777
2006
/**
778
2007
  Drop table in the engine: public interface.
779
2008
 
780
 
  @sa Cursor::drop_table()
 
2009
  @sa handler::drop_table()
781
2010
*/
782
2011
 
783
2012
void
784
 
Cursor::closeMarkForDelete(const char *name)
 
2013
handler::ha_drop_table(const char *name)
785
2014
{
786
 
  setTransactionReadWrite();
 
2015
  mark_trx_read_write();
787
2016
 
788
2017
  return drop_table(name);
789
2018
}
790
2019
 
791
 
int Cursor::index_next_same(unsigned char *buf, const unsigned char *key, uint32_t keylen)
 
2020
/**
 
2021
  Tell the storage engine that it is allowed to "disable transaction" in the
 
2022
  handler. It is a hint that ACID is not required - it is used in NDB for
 
2023
  ALTER Table, for example, when data are copied to temporary table.
 
2024
  A storage engine may treat this hint any way it likes. NDB for example
 
2025
  starts to commit every now and then automatically.
 
2026
  This hint can be safely ignored.
 
2027
*/
 
2028
int ha_enable_transaction(Session *session, bool on)
 
2029
{
 
2030
  int error= 0;
 
2031
 
 
2032
  if ((session->transaction.on= on))
 
2033
  {
 
2034
    /*
 
2035
      Now all storage engines should have transaction handling enabled.
 
2036
      But some may have it enabled all the time - "disabling" transactions
 
2037
      is an optimization hint that storage engine is free to ignore.
 
2038
      So, let's commit an open transaction (if any) now.
 
2039
    */
 
2040
    if (!(error= ha_commit_trans(session, 0)))
 
2041
      if (! session->endTransaction(COMMIT))
 
2042
        error= 1;
 
2043
 
 
2044
  }
 
2045
  return error;
 
2046
}
 
2047
 
 
2048
int handler::index_next_same(unsigned char *buf, const unsigned char *key, uint32_t keylen)
792
2049
{
793
2050
  int error;
794
2051
  if (!(error=index_next(buf)))
795
2052
  {
796
 
    ptrdiff_t ptrdiff= buf - table->record[0];
 
2053
    my_ptrdiff_t ptrdiff= buf - table->record[0];
797
2054
    unsigned char *save_record_0= NULL;
798
2055
    KEY *key_info= NULL;
799
2056
    KEY_PART_INFO *key_part;
840
2097
 
841
2098
 
842
2099
/****************************************************************************
843
 
** Some general functions that isn't in the Cursor class
 
2100
** Some general functions that isn't in the handler class
844
2101
****************************************************************************/
845
2102
 
 
2103
 
 
2104
void st_ha_check_opt::init()
 
2105
{
 
2106
  flags= 0; 
 
2107
  use_frm= false;
 
2108
}
 
2109
 
 
2110
 
 
2111
/*****************************************************************************
 
2112
  Key cache handling.
 
2113
 
 
2114
  This code is only relevant for ISAM/MyISAM tables
 
2115
 
 
2116
  key_cache->cache may be 0 only in the case where a key cache is not
 
2117
  initialized or when we where not able to init the key cache in a previous
 
2118
  call to ha_init_key_cache() (probably out of memory)
 
2119
*****************************************************************************/
 
2120
 
 
2121
/**
 
2122
  Init a key cache if it has not been initied before.
 
2123
*/
 
2124
int ha_init_key_cache(const char *,
 
2125
                      KEY_CACHE *key_cache)
 
2126
{
 
2127
  if (!key_cache->key_cache_inited)
 
2128
  {
 
2129
    pthread_mutex_lock(&LOCK_global_system_variables);
 
2130
    uint32_t tmp_buff_size= (uint32_t) key_cache->param_buff_size;
 
2131
    uint32_t tmp_block_size= (uint32_t) key_cache->param_block_size;
 
2132
    uint32_t division_limit= key_cache->param_division_limit;
 
2133
    uint32_t age_threshold=  key_cache->param_age_threshold;
 
2134
    pthread_mutex_unlock(&LOCK_global_system_variables);
 
2135
    return(!init_key_cache(key_cache,
 
2136
                                tmp_block_size,
 
2137
                                tmp_buff_size,
 
2138
                                division_limit, age_threshold));
 
2139
  }
 
2140
  return 0;
 
2141
}
 
2142
 
 
2143
 
 
2144
/**
 
2145
  Resize key cache.
 
2146
*/
 
2147
int ha_resize_key_cache(KEY_CACHE *key_cache)
 
2148
{
 
2149
  if (key_cache->key_cache_inited)
 
2150
  {
 
2151
    pthread_mutex_lock(&LOCK_global_system_variables);
 
2152
    long tmp_buff_size= (long) key_cache->param_buff_size;
 
2153
    long tmp_block_size= (long) key_cache->param_block_size;
 
2154
    uint32_t division_limit= key_cache->param_division_limit;
 
2155
    uint32_t age_threshold=  key_cache->param_age_threshold;
 
2156
    pthread_mutex_unlock(&LOCK_global_system_variables);
 
2157
    return(!resize_key_cache(key_cache, tmp_block_size,
 
2158
                                  tmp_buff_size,
 
2159
                                  division_limit, age_threshold));
 
2160
  }
 
2161
  return 0;
 
2162
}
 
2163
 
 
2164
 
 
2165
/**
 
2166
  Change parameters for key cache (like size)
 
2167
*/
 
2168
int ha_change_key_cache_param(KEY_CACHE *key_cache)
 
2169
{
 
2170
  if (key_cache->key_cache_inited)
 
2171
  {
 
2172
    pthread_mutex_lock(&LOCK_global_system_variables);
 
2173
    uint32_t division_limit= key_cache->param_division_limit;
 
2174
    uint32_t age_threshold=  key_cache->param_age_threshold;
 
2175
    pthread_mutex_unlock(&LOCK_global_system_variables);
 
2176
    change_key_cache_param(key_cache, division_limit, age_threshold);
 
2177
  }
 
2178
  return 0;
 
2179
}
 
2180
 
 
2181
/**
 
2182
  Free memory allocated by a key cache.
 
2183
*/
 
2184
int ha_end_key_cache(KEY_CACHE *key_cache)
 
2185
{
 
2186
  end_key_cache(key_cache, 1);          // Can never fail
 
2187
  return 0;
 
2188
}
 
2189
 
 
2190
/**
 
2191
  Move all tables from one key cache to another one.
 
2192
*/
 
2193
int ha_change_key_cache(KEY_CACHE *old_key_cache,
 
2194
                        KEY_CACHE *new_key_cache)
 
2195
{
 
2196
  mi_change_key_cache(old_key_cache, new_key_cache);
 
2197
  return 0;
 
2198
}
 
2199
 
 
2200
 
846
2201
/**
847
2202
  Calculate cost of 'index only' scan for given index and number of records
848
2203
 
852
2207
  @note
853
2208
    It is assumed that we will read trough the whole key range and that all
854
2209
    key blocks are half full (normally things are much better). It is also
855
 
    assumed that each time we read the next key from the index, the Cursor
 
2210
    assumed that each time we read the next key from the index, the handler
856
2211
    performs a random seek, thus the cost is proportional to the number of
857
2212
    blocks read.
858
2213
 
859
2214
  @todo
860
 
    Consider joining this function and Cursor::read_time() into one
861
 
    Cursor::read_time(keynr, records, ranges, bool index_only) function.
 
2215
    Consider joining this function and handler::read_time() into one
 
2216
    handler::read_time(keynr, records, ranges, bool index_only) function.
862
2217
 
863
2218
  @return
864
2219
    Estimated cost of 'index only' scan
865
2220
*/
866
2221
 
867
 
double Cursor::index_only_read_time(uint32_t keynr, double key_records)
 
2222
double handler::index_only_read_time(uint32_t keynr, double key_records)
868
2223
{
869
2224
  uint32_t keys_per_block= (stats.block_size/2/
870
2225
                        (table->key_info[keynr].key_length + ref_length) + 1);
909
2264
*/
910
2265
 
911
2266
ha_rows
912
 
Cursor::multi_range_read_info_const(uint32_t keyno, RANGE_SEQ_IF *seq,
 
2267
handler::multi_range_read_info_const(uint32_t keyno, RANGE_SEQ_IF *seq,
913
2268
                                     void *seq_init_param,
914
2269
                                     uint32_t ,
915
 
                                     uint32_t *bufsz, uint32_t *flags, optimizer::CostVector *cost)
 
2270
                                     uint32_t *bufsz, uint32_t *flags, COST_VECT *cost)
916
2271
{
917
2272
  KEY_MULTI_RANGE range;
918
2273
  range_seq_t seq_it;
955
2310
    /* The following calculation is the same as in multi_range_read_info(): */
956
2311
    *flags |= HA_MRR_USE_DEFAULT_IMPL;
957
2312
    cost->zero();
958
 
    cost->setAvgIOCost(1); /* assume random seeks */
 
2313
    cost->avg_io_cost= 1; /* assume random seeks */
959
2314
    if ((*flags & HA_MRR_INDEX_ONLY) && total_rows > 2)
960
 
      cost->setIOCount(index_only_read_time(keyno, (uint32_t)total_rows));
 
2315
      cost->io_count= index_only_read_time(keyno, (uint32_t)total_rows);
961
2316
    else
962
 
      cost->setIOCount(read_time(keyno, n_ranges, total_rows));
963
 
    cost->setCpuCost((double) total_rows / TIME_FOR_COMPARE + 0.01);
 
2317
      cost->io_count= read_time(keyno, n_ranges, total_rows);
 
2318
    cost->cpu_cost= (double) total_rows / TIME_FOR_COMPARE + 0.01;
964
2319
  }
965
2320
  return total_rows;
966
2321
}
1000
2355
    other Error or can't perform the requested scan
1001
2356
*/
1002
2357
 
1003
 
int Cursor::multi_range_read_info(uint32_t keyno, uint32_t n_ranges, uint32_t n_rows,
1004
 
                                   uint32_t *bufsz, uint32_t *flags, optimizer::CostVector *cost)
 
2358
int handler::multi_range_read_info(uint32_t keyno, uint32_t n_ranges, uint32_t n_rows,
 
2359
                                   uint32_t *bufsz, uint32_t *flags, COST_VECT *cost)
1005
2360
{
1006
2361
  *bufsz= 0; /* Default implementation doesn't need a buffer */
1007
2362
 
1008
2363
  *flags |= HA_MRR_USE_DEFAULT_IMPL;
1009
2364
 
1010
2365
  cost->zero();
1011
 
  cost->setAvgIOCost(1); /* assume random seeks */
 
2366
  cost->avg_io_cost= 1; /* assume random seeks */
1012
2367
 
1013
2368
  /* Produce the same cost as non-MRR code does */
1014
2369
  if (*flags & HA_MRR_INDEX_ONLY)
1015
 
    cost->setIOCount(index_only_read_time(keyno, n_rows));
 
2370
    cost->io_count= index_only_read_time(keyno, n_rows);
1016
2371
  else
1017
 
    cost->setIOCount(read_time(keyno, n_ranges, n_rows));
 
2372
    cost->io_count= read_time(keyno, n_ranges, n_rows);
1018
2373
  return 0;
1019
2374
}
1020
2375
 
1045
2400
    also hold:
1046
2401
    The caller will guarantee that if "seq->init == mrr_ranges_array_init"
1047
2402
    then seq_init_param is an array of n_ranges KEY_MULTI_RANGE structures.
1048
 
    This property will only be used by NDB Cursor until WL#2623 is done.
 
2403
    This property will only be used by NDB handler until WL#2623 is done.
1049
2404
 
1050
2405
    Buffer memory management is done according to the following scenario:
1051
2406
    The caller allocates the buffer and provides it to the callee by filling
1061
2416
*/
1062
2417
 
1063
2418
int
1064
 
Cursor::multi_range_read_init(RANGE_SEQ_IF *seq_funcs, void *seq_init_param,
 
2419
handler::multi_range_read_init(RANGE_SEQ_IF *seq_funcs, void *seq_init_param,
1065
2420
                               uint32_t n_ranges, uint32_t mode,
1066
2421
                               HANDLER_BUFFER *)
1067
2422
{
1086
2441
  @retval other  Error code
1087
2442
*/
1088
2443
 
1089
 
int Cursor::multi_range_read_next(char **range_info)
 
2444
int handler::multi_range_read_next(char **range_info)
1090
2445
{
1091
2446
  int result= 0;
1092
2447
  int range_res= 0;
1140
2495
}
1141
2496
 
1142
2497
 
 
2498
/**
 
2499
  Get cost of reading nrows table records in a "disk sweep"
 
2500
 
 
2501
  A disk sweep read is a sequence of handler->rnd_pos(rowid) calls that made
 
2502
  for an ordered sequence of rowids.
 
2503
 
 
2504
  We assume hard disk IO. The read is performed as follows:
 
2505
 
 
2506
   1. The disk head is moved to the needed cylinder
 
2507
   2. The controller waits for the plate to rotate
 
2508
   3. The data is transferred
 
2509
 
 
2510
  Time to do #3 is insignificant compared to #2+#1.
 
2511
 
 
2512
  Time to move the disk head is proportional to head travel distance.
 
2513
 
 
2514
  Time to wait for the plate to rotate depends on whether the disk head
 
2515
  was moved or not.
 
2516
 
 
2517
  If disk head wasn't moved, the wait time is proportional to distance
 
2518
  between the previous block and the block we're reading.
 
2519
 
 
2520
  If the head was moved, we don't know how much we'll need to wait for the
 
2521
  plate to rotate. We assume the wait time to be a variate with a mean of
 
2522
  0.5 of full rotation time.
 
2523
 
 
2524
  Our cost units are "random disk seeks". The cost of random disk seek is
 
2525
  actually not a constant, it depends one range of cylinders we're going
 
2526
  to access. We make it constant by introducing a fuzzy concept of "typical
 
2527
  datafile length" (it's fuzzy as it's hard to tell whether it should
 
2528
  include index file, temp.tables etc). Then random seek cost is:
 
2529
 
 
2530
    1 = half_rotation_cost + move_cost * 1/3 * typical_data_file_length
 
2531
 
 
2532
  We define half_rotation_cost as DISK_SEEK_BASE_COST=0.9.
 
2533
 
 
2534
  @param table             Table to be accessed
 
2535
  @param nrows             Number of rows to retrieve
 
2536
  @param interrupted       true <=> Assume that the disk sweep will be
 
2537
                           interrupted by other disk IO. false - otherwise.
 
2538
  @param cost         OUT  The cost.
 
2539
*/
 
2540
 
 
2541
void get_sweep_read_cost(Table *table, ha_rows nrows, bool interrupted,
 
2542
                         COST_VECT *cost)
 
2543
{
 
2544
  cost->zero();
 
2545
  if (table->file->primary_key_is_clustered())
 
2546
  {
 
2547
    cost->io_count= table->file->read_time(table->s->primary_key,
 
2548
                                           (uint32_t) nrows, nrows);
 
2549
  }
 
2550
  else
 
2551
  {
 
2552
    double n_blocks=
 
2553
      ceil(uint64_t2double(table->file->stats.data_file_length) / IO_SIZE);
 
2554
    double busy_blocks=
 
2555
      n_blocks * (1.0 - pow(1.0 - 1.0/n_blocks, rows2double(nrows)));
 
2556
    if (busy_blocks < 1.0)
 
2557
      busy_blocks= 1.0;
 
2558
 
 
2559
    cost->io_count= busy_blocks;
 
2560
 
 
2561
    if (!interrupted)
 
2562
    {
 
2563
      /* Assume reading is done in one 'sweep' */
 
2564
      cost->avg_io_cost= (DISK_SEEK_BASE_COST +
 
2565
                          DISK_SEEK_PROP_COST*n_blocks/busy_blocks);
 
2566
    }
 
2567
  }
 
2568
}
 
2569
 
 
2570
 
1143
2571
/* **************************************************************************
1144
2572
 * DS-MRR implementation ends
1145
2573
 ***************************************************************************/
1162
2590
  @retval
1163
2591
    \#                  Error code
1164
2592
*/
1165
 
int Cursor::read_range_first(const key_range *start_key,
1166
 
                             const key_range *end_key,
1167
 
                             bool eq_range_arg,
1168
 
                             bool )
 
2593
int handler::read_range_first(const key_range *start_key,
 
2594
                              const key_range *end_key,
 
2595
                              bool eq_range_arg,
 
2596
                              bool )
1169
2597
{
1170
2598
  int result;
1171
2599
 
1209
2637
  @retval
1210
2638
    \#                  Error code
1211
2639
*/
1212
 
int Cursor::read_range_next()
 
2640
int handler::read_range_next()
1213
2641
{
1214
2642
  int result;
1215
2643
 
1242
2670
    - -1  : Key is less than range
1243
2671
    - 1   : Key is larger than range
1244
2672
*/
1245
 
int Cursor::compare_key(key_range *range)
 
2673
int handler::compare_key(key_range *range)
1246
2674
{
1247
2675
  int cmp;
1248
2676
  if (!range || in_range_check_pushed_down)
1259
2687
  This is used by index condition pushdown implementation.
1260
2688
*/
1261
2689
 
1262
 
int Cursor::compare_key2(key_range *range)
 
2690
int handler::compare_key2(key_range *range)
1263
2691
{
1264
2692
  int cmp;
1265
2693
  if (!range)
1270
2698
  return cmp;
1271
2699
}
1272
2700
 
1273
 
int Cursor::index_read_idx_map(unsigned char * buf, uint32_t index,
 
2701
int handler::index_read_idx_map(unsigned char * buf, uint32_t index,
1274
2702
                                const unsigned char * key,
1275
2703
                                key_part_map keypart_map,
1276
2704
                                enum ha_rkey_function find_flag)
1285
2713
  return error ?  error : error1;
1286
2714
}
1287
2715
 
 
2716
 
 
2717
static bool stat_print(Session *session, const char *type, uint32_t type_len,
 
2718
                       const char *file, uint32_t file_len,
 
2719
                       const char *status, uint32_t status_len)
 
2720
{
 
2721
  Protocol *protocol= session->protocol;
 
2722
  protocol->prepareForResend();
 
2723
  protocol->store(type, type_len);
 
2724
  protocol->store(file, file_len);
 
2725
  protocol->store(status, status_len);
 
2726
  if (protocol->write())
 
2727
    return true;
 
2728
  return false;
 
2729
}
 
2730
 
 
2731
bool ha_show_status(Session *session, StorageEngine *engine, enum ha_stat_type stat)
 
2732
{
 
2733
  List<Item> field_list;
 
2734
  Protocol *protocol= session->protocol;
 
2735
  bool result;
 
2736
 
 
2737
  field_list.push_back(new Item_empty_string("Type",10));
 
2738
  field_list.push_back(new Item_empty_string("Name",FN_REFLEN));
 
2739
  field_list.push_back(new Item_empty_string("Status",10));
 
2740
 
 
2741
  if (protocol->sendFields(&field_list,
 
2742
                           Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
 
2743
    return true;
 
2744
 
 
2745
  result= engine->show_status(session, stat_print, stat) ? 1 : 0;
 
2746
 
 
2747
  if (!result)
 
2748
    session->my_eof();
 
2749
  return result;
 
2750
}
 
2751
 
 
2752
 
1288
2753
/**
1289
2754
  Check if the conditions for row-based binlogging is correct for the table.
1290
2755
 
1291
2756
  A row in the given table should be replicated if:
 
2757
  - Row-based replication is enabled in the current thread
 
2758
  - The binlog is enabled
1292
2759
  - It is not a temporary table
 
2760
  - The binary log is open
 
2761
  - The database the table resides in shall be binlogged (binlog_*_db rules)
 
2762
  - table is not mysql.event
1293
2763
*/
1294
2764
 
1295
2765
static bool log_row_for_replication(Table* table,
1296
 
                                    const unsigned char *before_record,
1297
 
                                    const unsigned char *after_record)
 
2766
                           const unsigned char *before_record,
 
2767
                           const unsigned char *after_record)
1298
2768
{
1299
 
  TransactionServices &transaction_services= TransactionServices::singleton();
1300
 
  ReplicationServices &replication_services= ReplicationServices::singleton();
1301
2769
  Session *const session= table->in_use;
1302
2770
 
1303
 
  if (table->s->tmp_table || not replication_services.isActive())
1304
 
    return false;
1305
 
 
1306
 
  bool result= false;
1307
 
 
1308
2771
  switch (session->lex->sql_command)
1309
2772
  {
1310
 
  case SQLCOM_CREATE_TABLE:
1311
 
    /*
1312
 
     * We are in a CREATE TABLE ... SELECT statement
1313
 
     * and the kernel has already created the table
1314
 
     * and put a CreateTableStatement in the active
1315
 
     * Transaction message.  Here, we add a new InsertRecord
1316
 
     * to a new Transaction message (because the above
1317
 
     * CREATE TABLE will commit the transaction containing
1318
 
     * it).
1319
 
     */
1320
 
    result= transaction_services.insertRecord(session, table);
1321
 
    break;
1322
2773
  case SQLCOM_REPLACE:
 
2774
  case SQLCOM_INSERT:
1323
2775
  case SQLCOM_REPLACE_SELECT:
1324
 
    /*
1325
 
     * This is a total hack because of the code that is
1326
 
     * in write_record() in sql_insert.cc. During
1327
 
     * a REPLACE statement, a call to ha_write_row() is
1328
 
     * called.  If it fails, then a call to ha_delete_row()
1329
 
     * is called, followed by a repeat of the original
1330
 
     * call to ha_write_row().  So, log_row_for_replication
1331
 
     * could be called either once or twice for a REPLACE
1332
 
     * statement.  The below looks at the values of before_record
1333
 
     * and after_record to determine which call to this
1334
 
     * function is for the delete or the insert, since NULL
1335
 
     * is passed for after_record for the delete and NULL is
1336
 
     * passed for before_record for the insert...
1337
 
     *
1338
 
     * In addition, there is an optimization that allows an
1339
 
     * engine to convert the above delete + insert into an
1340
 
     * update, so we must also check for this case below...
1341
 
     */
1342
 
    if (after_record == NULL)
1343
 
    {
1344
 
      transaction_services.deleteRecord(session, table);
1345
 
      /* 
1346
 
       * We set the "current" statement message to NULL.  This triggers
1347
 
       * the replication services component to generate a new statement
1348
 
       * message for the inserted record which will come next.
1349
 
       */
1350
 
      transaction_services.finalizeStatementMessage(*session->getStatementMessage(), session);
1351
 
    }
1352
 
    else
1353
 
    {
1354
 
      if (before_record == NULL)
1355
 
        result= transaction_services.insertRecord(session, table);
1356
 
      else
1357
 
        transaction_services.updateRecord(session, table, before_record, after_record);
1358
 
    }
1359
 
    break;
1360
 
  case SQLCOM_INSERT:
1361
2776
  case SQLCOM_INSERT_SELECT:
1362
 
    /*
1363
 
     * The else block below represents an 
1364
 
     * INSERT ... ON DUPLICATE KEY UPDATE that
1365
 
     * has hit a key conflict and actually done
1366
 
     * an update.
1367
 
     */
1368
 
    if (before_record == NULL)
1369
 
      result= transaction_services.insertRecord(session, table);
1370
 
    else
1371
 
      transaction_services.updateRecord(session, table, before_record, after_record);
 
2777
  case SQLCOM_CREATE_TABLE:
 
2778
    transaction_services.insertRecord(session, table);
1372
2779
    break;
1373
2780
 
1374
2781
  case SQLCOM_UPDATE:
 
2782
  case SQLCOM_UPDATE_MULTI:
1375
2783
    transaction_services.updateRecord(session, table, before_record, after_record);
1376
2784
    break;
1377
2785
 
1378
2786
  case SQLCOM_DELETE:
 
2787
  case SQLCOM_DELETE_MULTI:
1379
2788
    transaction_services.deleteRecord(session, table);
1380
2789
    break;
 
2790
 
 
2791
    /*
 
2792
      For everything else we ignore the event (since it just involves a temp table)
 
2793
    */
1381
2794
  default:
1382
2795
    break;
1383
2796
  }
1384
2797
 
1385
 
  return result;
 
2798
  return false; //error;
1386
2799
}
1387
2800
 
1388
 
int Cursor::ha_external_lock(Session *session, int lock_type)
 
2801
int handler::ha_external_lock(Session *session, int lock_type)
1389
2802
{
1390
2803
  /*
1391
2804
    Whether this is lock or unlock, this should be true, and is to verify that
1394
2807
  */
1395
2808
  assert(next_insert_id == 0);
1396
2809
 
1397
 
  if (DRIZZLE_CURSOR_RDLOCK_START_ENABLED() ||
1398
 
      DRIZZLE_CURSOR_WRLOCK_START_ENABLED() ||
1399
 
      DRIZZLE_CURSOR_UNLOCK_START_ENABLED())
1400
 
  {
1401
 
    if (lock_type == F_RDLCK)
1402
 
    {
1403
 
      DRIZZLE_CURSOR_RDLOCK_START(table_share->getSchemaName(),
1404
 
                                  table_share->getTableName());
1405
 
    }
1406
 
    else if (lock_type == F_WRLCK)
1407
 
    {
1408
 
      DRIZZLE_CURSOR_WRLOCK_START(table_share->getSchemaName(),
1409
 
                                  table_share->getTableName());
1410
 
    }
1411
 
    else if (lock_type == F_UNLCK)
1412
 
    {
1413
 
      DRIZZLE_CURSOR_UNLOCK_START(table_share->getSchemaName(),
1414
 
                                  table_share->getTableName());
1415
 
    }
1416
 
  }
1417
 
 
1418
2810
  /*
1419
2811
    We cache the table flags if the locking succeeded. Otherwise, we
1420
2812
    keep them as they were when they were fetched in ha_open().
1421
2813
  */
 
2814
  DRIZZLE_EXTERNAL_LOCK(lock_type);
1422
2815
 
1423
2816
  int error= external_lock(session, lock_type);
1424
 
 
1425
 
  if (DRIZZLE_CURSOR_RDLOCK_DONE_ENABLED() ||
1426
 
      DRIZZLE_CURSOR_WRLOCK_DONE_ENABLED() ||
1427
 
      DRIZZLE_CURSOR_UNLOCK_DONE_ENABLED())
1428
 
  {
1429
 
    if (lock_type == F_RDLCK)
1430
 
    {
1431
 
      DRIZZLE_CURSOR_RDLOCK_DONE(error);
1432
 
    }
1433
 
    else if (lock_type == F_WRLCK)
1434
 
    {
1435
 
      DRIZZLE_CURSOR_WRLOCK_DONE(error);
1436
 
    }
1437
 
    else if (lock_type == F_UNLCK)
1438
 
    {
1439
 
      DRIZZLE_CURSOR_UNLOCK_DONE(error);
1440
 
    }
1441
 
  }
1442
 
 
 
2817
  if (error == 0)
 
2818
    cached_table_flags= table_flags();
1443
2819
  return error;
1444
2820
}
1445
2821
 
1446
2822
 
1447
2823
/**
1448
 
  Check Cursor usage and reset state of file to after 'open'
 
2824
  Check handler usage and reset state of file to after 'open'
1449
2825
*/
1450
 
int Cursor::ha_reset()
 
2826
int handler::ha_reset()
1451
2827
{
1452
2828
  /* Check that we have called all proper deallocation functions */
1453
 
  assert((unsigned char*) table->def_read_set.getBitmap() +
 
2829
  assert((unsigned char*) table->def_read_set.bitmap +
1454
2830
              table->s->column_bitmap_size ==
1455
 
              (unsigned char*) table->def_write_set.getBitmap());
1456
 
  assert(table->s->all_set.isSetAll());
 
2831
              (unsigned char*) table->def_write_set.bitmap);
 
2832
  assert(bitmap_is_set_all(&table->s->all_set));
1457
2833
  assert(table->key_read == 0);
1458
2834
  /* ensure that ha_index_end / ha_rnd_end has been called */
1459
2835
  assert(inited == NONE);
1460
2836
  /* Free cache used by filesort */
1461
 
  table->free_io_cache();
 
2837
  free_io_cache(table);
1462
2838
  /* reset the bitmaps to point to defaults */
1463
2839
  table->default_column_bitmaps();
1464
2840
  return(reset());
1465
2841
}
1466
2842
 
1467
2843
 
1468
 
int Cursor::ha_write_row(unsigned char *buf)
 
2844
int handler::ha_write_row(unsigned char *buf)
1469
2845
{
1470
2846
  int error;
 
2847
  DRIZZLE_INSERT_ROW_START();
1471
2848
 
1472
 
  /*
1473
 
   * If we have a timestamp column, update it to the current time
1474
 
   *
 
2849
  /* 
 
2850
   * If we have a timestamp column, update it to the current time 
 
2851
   * 
1475
2852
   * @TODO Technically, the below two lines can be take even further out of the
1476
 
   * Cursor interface and into the fill_record() method.
 
2853
   * handler interface and into the fill_record() method.
1477
2854
   */
1478
2855
  if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT)
1479
2856
    table->timestamp_field->set_time();
1480
2857
 
1481
 
  DRIZZLE_INSERT_ROW_START(table_share->getSchemaName(), table_share->getTableName());
1482
 
  setTransactionReadWrite();
1483
 
  error= write_row(buf);
1484
 
  DRIZZLE_INSERT_ROW_DONE(error);
 
2858
  mark_trx_read_write();
1485
2859
 
1486
 
  if (unlikely(error))
1487
 
  {
 
2860
  if (unlikely(error= write_row(buf)))
1488
2861
    return error;
1489
 
  }
1490
 
 
1491
 
  if (unlikely(log_row_for_replication(table, NULL, buf)))
1492
 
    return HA_ERR_RBR_LOGGING_FAILED;
1493
 
 
 
2862
 
 
2863
  if (unlikely(log_row_for_replication(table, 0, buf)))
 
2864
    return HA_ERR_RBR_LOGGING_FAILED; /* purecov: inspected */
 
2865
 
 
2866
  DRIZZLE_INSERT_ROW_END();
1494
2867
  return 0;
1495
2868
}
1496
2869
 
1497
2870
 
1498
 
int Cursor::ha_update_row(const unsigned char *old_data, unsigned char *new_data)
 
2871
int handler::ha_update_row(const unsigned char *old_data, unsigned char *new_data)
1499
2872
{
1500
2873
  int error;
1501
2874
 
1505
2878
   */
1506
2879
  assert(new_data == table->record[0]);
1507
2880
 
1508
 
  DRIZZLE_UPDATE_ROW_START(table_share->getSchemaName(), table_share->getTableName());
1509
 
  setTransactionReadWrite();
1510
 
  error= update_row(old_data, new_data);
1511
 
  DRIZZLE_UPDATE_ROW_DONE(error);
 
2881
  mark_trx_read_write();
1512
2882
 
1513
 
  if (unlikely(error))
1514
 
  {
 
2883
  if (unlikely(error= update_row(old_data, new_data)))
1515
2884
    return error;
1516
 
  }
1517
2885
 
1518
2886
  if (unlikely(log_row_for_replication(table, old_data, new_data)))
1519
2887
    return HA_ERR_RBR_LOGGING_FAILED;
1521
2889
  return 0;
1522
2890
}
1523
2891
 
1524
 
int Cursor::ha_delete_row(const unsigned char *buf)
 
2892
int handler::ha_delete_row(const unsigned char *buf)
1525
2893
{
1526
2894
  int error;
1527
2895
 
1528
 
  DRIZZLE_DELETE_ROW_START(table_share->getSchemaName(), table_share->getTableName());
1529
 
  setTransactionReadWrite();
1530
 
  error= delete_row(buf);
1531
 
  DRIZZLE_DELETE_ROW_DONE(error);
 
2896
  mark_trx_read_write();
1532
2897
 
1533
 
  if (unlikely(error))
 
2898
  if (unlikely(error= delete_row(buf)))
1534
2899
    return error;
1535
2900
 
1536
 
  if (unlikely(log_row_for_replication(table, buf, NULL)))
 
2901
  if (unlikely(log_row_for_replication(table, buf, 0)))
1537
2902
    return HA_ERR_RBR_LOGGING_FAILED;
1538
2903
 
1539
2904
  return 0;
1540
2905
}
1541
 
 
1542
 
} /* namespace drizzled */