~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to sql/handler.h

  • Committer: brian
  • Date: 2008-06-25 05:29:13 UTC
  • Revision ID: brian@localhost.localdomain-20080625052913-6upwo0jsrl4lnapl
clean slate

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (C) 2000-2006 MySQL AB
 
2
 
 
3
   This program is free software; you can redistribute it and/or modify
 
4
   it under the terms of the GNU General Public License as published by
 
5
   the Free Software Foundation; version 2 of the License.
 
6
 
 
7
   This program is distributed in the hope that it will be useful,
 
8
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
9
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
10
   GNU General Public License for more details.
 
11
 
 
12
   You should have received a copy of the GNU General Public License
 
13
   along with this program; if not, write to the Free Software
 
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
 
15
 
 
16
 
 
17
/* Definitions for parameters to do with handler-routines */
 
18
 
 
19
#ifdef USE_PRAGMA_INTERFACE
 
20
#pragma interface                       /* gcc class implementation */
 
21
#endif
 
22
 
 
23
#include <my_handler.h>
 
24
#include <ft_global.h>
 
25
#include <keycache.h>
 
26
 
 
27
#ifndef NO_HASH
 
28
#define NO_HASH                         /* Not yet implemented */
 
29
#endif
 
30
 
 
31
// the following is for checking tables
 
32
 
 
33
#define HA_ADMIN_ALREADY_DONE     1
 
34
#define HA_ADMIN_OK               0
 
35
#define HA_ADMIN_NOT_IMPLEMENTED -1
 
36
#define HA_ADMIN_FAILED          -2
 
37
#define HA_ADMIN_CORRUPT         -3
 
38
#define HA_ADMIN_INTERNAL_ERROR  -4
 
39
#define HA_ADMIN_INVALID         -5
 
40
#define HA_ADMIN_REJECT          -6
 
41
#define HA_ADMIN_TRY_ALTER       -7
 
42
#define HA_ADMIN_WRONG_CHECKSUM  -8
 
43
#define HA_ADMIN_NOT_BASE_TABLE  -9
 
44
#define HA_ADMIN_NEEDS_UPGRADE  -10
 
45
#define HA_ADMIN_NEEDS_ALTER    -11
 
46
#define HA_ADMIN_NEEDS_CHECK    -12
 
47
 
 
48
/* Bits to show what an alter table will do */
 
49
#include <sql_bitmap.h>
 
50
 
 
51
#define HA_MAX_ALTER_FLAGS 39
 
52
typedef Bitmap<HA_MAX_ALTER_FLAGS> HA_ALTER_FLAGS;
 
53
 
 
54
#define HA_ADD_INDEX                  (0)
 
55
#define HA_DROP_INDEX                 (1)
 
56
#define HA_ALTER_INDEX                (2)
 
57
#define HA_RENAME_INDEX               (3)
 
58
#define HA_ADD_UNIQUE_INDEX           (4)
 
59
#define HA_DROP_UNIQUE_INDEX          (5)
 
60
#define HA_ALTER_UNIQUE_INDEX         (6)
 
61
#define HA_RENAME_UNIQUE_INDEX        (7)
 
62
#define HA_ADD_PK_INDEX               (8)
 
63
#define HA_DROP_PK_INDEX              (9)
 
64
#define HA_ALTER_PK_INDEX             (10)
 
65
#define HA_ADD_COLUMN                 (11)
 
66
#define HA_DROP_COLUMN                (12)
 
67
#define HA_CHANGE_COLUMN              (13)
 
68
#define HA_ALTER_COLUMN_NAME          (14)
 
69
#define HA_ALTER_COLUMN_TYPE          (15)
 
70
#define HA_ALTER_COLUMN_ORDER         (16)
 
71
#define HA_ALTER_COLUMN_NULLABLE      (17)
 
72
#define HA_COLUMN_DEFAULT_VALUE       (18)
 
73
#define HA_COLUMN_STORAGE             (19)
 
74
#define HA_COLUMN_FORMAT              (20)
 
75
#define HA_ADD_FOREIGN_KEY            (21)
 
76
#define HA_DROP_FOREIGN_KEY           (22)
 
77
#define HA_ALTER_FOREIGN_KEY          (23)
 
78
#define HA_ADD_CONSTRAINT             (24)
 
79
#define HA_CHANGE_CHARACTER_SET       (30)
 
80
#define HA_SET_DEFAULT_CHARACTER_SET  (31)
 
81
#define HA_CHANGE_AUTOINCREMENT_VALUE (32)
 
82
#define HA_ALTER_STORAGE              (33)
 
83
#define HA_ALTER_TABLESPACE           (34)
 
84
#define HA_ALTER_ROW_FORMAT           (35)
 
85
#define HA_RENAME_TABLE               (36)
 
86
#define HA_ALTER_STORAGE_ENGINE       (37)
 
87
#define HA_RECREATE                   (38)
 
88
/* Remember to increase HA_MAX_ALTER_FLAGS when adding more flags! */
 
89
 
 
90
/* Return values for check_if_supported_alter */
 
91
 
 
92
#define HA_ALTER_ERROR               -1
 
93
#define HA_ALTER_SUPPORTED_WAIT_LOCK  0
 
94
#define HA_ALTER_SUPPORTED_NO_LOCK    1
 
95
#define HA_ALTER_NOT_SUPPORTED        2
 
96
 
 
97
/* Bits in table_flags() to show what database can do */
 
98
 
 
99
#define HA_NO_TRANSACTIONS     (1 << 0) /* Doesn't support transactions */
 
100
#define HA_PARTIAL_COLUMN_READ (1 << 1) /* read may not return all columns */
 
101
#define HA_TABLE_SCAN_ON_INDEX (1 << 2) /* No separate data/index file */
 
102
/*
 
103
  The following should be set if the following is not true when scanning
 
104
  a table with rnd_next()
 
105
  - We will see all rows (including deleted ones)
 
106
  - Row positions are 'table->s->db_record_offset' apart
 
107
  If this flag is not set, filesort will do a postion() call for each matched
 
108
  row to be able to find the row later.
 
109
*/
 
110
#define HA_REC_NOT_IN_SEQ      (1 << 3)
 
111
/* This is now a dead option, just left for compatibility */
 
112
#define HA_CAN_GEOMETRY        (1 << 4)
 
113
/*
 
114
  Reading keys in random order is as fast as reading keys in sort order
 
115
  (Used in records.cc to decide if we should use a record cache and by
 
116
  filesort to decide if we should sort key + data or key + pointer-to-row
 
117
*/
 
118
#define HA_FAST_KEY_READ       (1 << 5)
 
119
/*
 
120
  Set the following flag if we on delete should force all key to be read
 
121
  and on update read all keys that changes
 
122
*/
 
123
#define HA_REQUIRES_KEY_COLUMNS_FOR_DELETE (1 << 6)
 
124
#define HA_NULL_IN_KEY         (1 << 7) /* One can have keys with NULL */
 
125
#define HA_DUPLICATE_POS       (1 << 8)    /* ha_position() gives dup row */
 
126
#define HA_NO_BLOBS            (1 << 9) /* Doesn't support blobs */
 
127
#define HA_CAN_INDEX_BLOBS     (1 << 10)
 
128
#define HA_AUTO_PART_KEY       (1 << 11) /* auto-increment in multi-part key */
 
129
#define HA_REQUIRE_PRIMARY_KEY (1 << 12) /* .. and can't create a hidden one */
 
130
#define HA_STATS_RECORDS_IS_EXACT (1 << 13) /* stats.records is exact */
 
131
/*
 
132
  INSERT_DELAYED only works with handlers that uses MySQL internal table
 
133
  level locks
 
134
*/
 
135
#define HA_CAN_INSERT_DELAYED  (1 << 14)
 
136
/*
 
137
  If we get the primary key columns for free when we do an index read
 
138
  It also implies that we have to retrive the primary key when using
 
139
  position() and rnd_pos().
 
140
*/
 
141
#define HA_PRIMARY_KEY_IN_READ_INDEX (1 << 15)
 
142
/*
 
143
  If HA_PRIMARY_KEY_REQUIRED_FOR_POSITION is set, it means that to position()
 
144
  uses a primary key. Without primary key, we can't call position().
 
145
*/ 
 
146
#define HA_PRIMARY_KEY_REQUIRED_FOR_POSITION (1 << 16) 
 
147
#define HA_CAN_RTREEKEYS       (1 << 17)
 
148
#define HA_NOT_DELETE_WITH_CACHE (1 << 18)
 
149
/*
 
150
  The following is we need to a primary key to delete (and update) a row.
 
151
  If there is no primary key, all columns needs to be read on update and delete
 
152
*/
 
153
#define HA_PRIMARY_KEY_REQUIRED_FOR_DELETE (1 << 19)
 
154
#define HA_NO_PREFIX_CHAR_KEYS (1 << 20)
 
155
#define HA_CAN_FULLTEXT        (1 << 21)
 
156
#define HA_CAN_SQL_HANDLER     (1 << 22)
 
157
#define HA_NO_AUTO_INCREMENT   (1 << 23)
 
158
#define HA_HAS_CHECKSUM        (1 << 24)
 
159
/* Table data are stored in separate files (for lower_case_table_names) */
 
160
#define HA_FILE_BASED          (1 << 26)
 
161
#define HA_NO_VARCHAR          (1 << 27)
 
162
#define HA_CAN_BIT_FIELD       (1 << 28) /* supports bit fields */
 
163
#define HA_NEED_READ_RANGE_BUFFER (1 << 29) /* for read_multi_range */
 
164
#define HA_ANY_INDEX_MAY_BE_UNIQUE (1 << 30)
 
165
#define HA_NO_COPY_ON_ALTER    (LL(1) << 31)
 
166
#define HA_HAS_RECORDS         (LL(1) << 32) /* records() gives exact count*/
 
167
/* Has it's own method of binlog logging */
 
168
#define HA_HAS_OWN_BINLOGGING  (LL(1) << 33)
 
169
#define HA_MRR_CANT_SORT       (LL(1) << 34)
 
170
 
 
171
/*
 
172
  Engine is capable of row-format and statement-format logging,
 
173
  respectively
 
174
*/
 
175
#define HA_BINLOG_ROW_CAPABLE  (LL(1) << 35)
 
176
#define HA_BINLOG_STMT_CAPABLE (LL(1) << 36)
 
177
 
 
178
#define HA_ONLINE_ALTER        (LL(1) << 37)
 
179
 
 
180
/*
 
181
  Set of all binlog flags. Currently only contain the capabilities
 
182
  flags.
 
183
 */
 
184
#define HA_BINLOG_FLAGS (HA_BINLOG_ROW_CAPABLE | HA_BINLOG_STMT_CAPABLE)
 
185
 
 
186
/* bits in index_flags(index_number) for what you can do with index */
 
187
#define HA_READ_NEXT            1       /* TODO really use this flag */
 
188
#define HA_READ_PREV            2       /* supports ::index_prev */
 
189
#define HA_READ_ORDER           4       /* index_next/prev follow sort order */
 
190
#define HA_READ_RANGE           8       /* can find all records in a range */
 
191
#define HA_ONLY_WHOLE_INDEX     16      /* Can't use part key searches */
 
192
#define HA_KEYREAD_ONLY         64      /* Support HA_EXTRA_KEYREAD */
 
193
/*
 
194
  Index scan will not return records in rowid order. Not guaranteed to be
 
195
  set for unordered (e.g. HASH) indexes.
 
196
*/
 
197
#define HA_KEY_SCAN_NOT_ROR     128 
 
198
#define HA_DO_INDEX_COND_PUSHDOWN  256 /* Supports Index Condition Pushdown */
 
199
 
 
200
 
 
201
 
 
202
/*
 
203
  HA_PARTITION_FUNCTION_SUPPORTED indicates that the function is
 
204
  supported at all.
 
205
  HA_FAST_CHANGE_PARTITION means that optimised variants of the changes
 
206
  exists but they are not necessarily done online.
 
207
 
 
208
  HA_ONLINE_DOUBLE_WRITE means that the handler supports writing to both
 
209
  the new partition and to the old partitions when updating through the
 
210
  old partitioning schema while performing a change of the partitioning.
 
211
  This means that we can support updating of the table while performing
 
212
  the copy phase of the change. For no lock at all also a double write
 
213
  from new to old must exist and this is not required when this flag is
 
214
  set.
 
215
  This is actually removed even before it was introduced the first time.
 
216
  The new idea is that handlers will handle the lock level already in
 
217
  store_lock for ALTER TABLE partitions.
 
218
 
 
219
  HA_PARTITION_ONE_PHASE is a flag that can be set by handlers that take
 
220
  care of changing the partitions online and in one phase. Thus all phases
 
221
  needed to handle the change are implemented inside the storage engine.
 
222
  The storage engine must also support auto-discovery since the frm file
 
223
  is changed as part of the change and this change must be controlled by
 
224
  the storage engine. A typical engine to support this is NDB (through
 
225
  WL #2498).
 
226
*/
 
227
#define HA_PARTITION_FUNCTION_SUPPORTED         (1L << 1)
 
228
#define HA_FAST_CHANGE_PARTITION                (1L << 2)
 
229
#define HA_PARTITION_ONE_PHASE                  (1L << 3)
 
230
 
 
231
/* operations for disable/enable indexes */
 
232
#define HA_KEY_SWITCH_NONUNIQ      0
 
233
#define HA_KEY_SWITCH_ALL          1
 
234
#define HA_KEY_SWITCH_NONUNIQ_SAVE 2
 
235
#define HA_KEY_SWITCH_ALL_SAVE     3
 
236
 
 
237
/*
 
238
  Note: the following includes binlog and closing 0.
 
239
  so: innodb + bdb + ndb + binlog + myisam + myisammrg + archive +
 
240
      example + csv + heap + blackhole + federated + 0
 
241
  (yes, the sum is deliberately inaccurate)
 
242
  TODO remove the limit, use dynarrays
 
243
*/
 
244
#define MAX_HA 15
 
245
 
 
246
/*
 
247
  Parameters for open() (in register form->filestat)
 
248
  HA_GET_INFO does an implicit HA_ABORT_IF_LOCKED
 
249
*/
 
250
 
 
251
#define HA_OPEN_KEYFILE         1
 
252
#define HA_OPEN_RNDFILE         2
 
253
#define HA_GET_INDEX            4
 
254
#define HA_GET_INFO             8       /* do a ha_info() after open */
 
255
#define HA_READ_ONLY            16      /* File opened as readonly */
 
256
/* Try readonly if can't open with read and write */
 
257
#define HA_TRY_READ_ONLY        32
 
258
#define HA_WAIT_IF_LOCKED       64      /* Wait if locked on open */
 
259
#define HA_ABORT_IF_LOCKED      128     /* skip if locked on open.*/
 
260
#define HA_BLOCK_LOCK           256     /* unlock when reading some records */
 
261
#define HA_OPEN_TEMPORARY       512
 
262
 
 
263
/* For transactional LOCK TABLE. handler::lock_table() */
 
264
#define HA_LOCK_IN_SHARE_MODE      F_RDLCK
 
265
#define HA_LOCK_IN_EXCLUSIVE_MODE  F_WRLCK
 
266
 
 
267
/* Some key definitions */
 
268
#define HA_KEY_NULL_LENGTH      1
 
269
#define HA_KEY_BLOB_LENGTH      2
 
270
 
 
271
#define HA_LEX_CREATE_TMP_TABLE 1
 
272
#define HA_LEX_CREATE_IF_NOT_EXISTS 2
 
273
#define HA_LEX_CREATE_TABLE_LIKE 4
 
274
#define HA_OPTION_NO_CHECKSUM   (1L << 17)
 
275
#define HA_OPTION_NO_DELAY_KEY_WRITE (1L << 18)
 
276
#define HA_MAX_REC_LENGTH       65535
 
277
 
 
278
/* Table caching type */
 
279
#define HA_CACHE_TBL_NONTRANSACT 0
 
280
#define HA_CACHE_TBL_NOCACHE     1
 
281
#define HA_CACHE_TBL_ASKTRANSACT 2
 
282
#define HA_CACHE_TBL_TRANSACT    4
 
283
 
 
284
/* Options of START TRANSACTION statement (and later of SET TRANSACTION stmt) */
 
285
#define MYSQL_START_TRANS_OPT_WITH_CONS_SNAPSHOT 1
 
286
 
 
287
/* Flags for method is_fatal_error */
 
288
#define HA_CHECK_DUP_KEY 1
 
289
#define HA_CHECK_DUP_UNIQUE 2
 
290
#define HA_CHECK_DUP (HA_CHECK_DUP_KEY + HA_CHECK_DUP_UNIQUE)
 
291
 
 
292
enum legacy_db_type
 
293
{
 
294
  DB_TYPE_UNKNOWN=0,DB_TYPE_DIAB_ISAM=1,
 
295
  DB_TYPE_HASH,DB_TYPE_MISAM,DB_TYPE_PISAM,
 
296
  DB_TYPE_RMS_ISAM, DB_TYPE_HEAP, DB_TYPE_ISAM,
 
297
  DB_TYPE_MRG_ISAM, DB_TYPE_MYISAM, DB_TYPE_MRG_MYISAM,
 
298
  DB_TYPE_BERKELEY_DB, DB_TYPE_INNODB,
 
299
  DB_TYPE_GEMINI, DB_TYPE_NDBCLUSTER,
 
300
  DB_TYPE_EXAMPLE_DB, DB_TYPE_ARCHIVE_DB, DB_TYPE_CSV_DB,
 
301
  DB_TYPE_FEDERATED_DB,
 
302
  DB_TYPE_BLACKHOLE_DB,
 
303
  DB_TYPE_PARTITION_DB,
 
304
  DB_TYPE_BINLOG,
 
305
  DB_TYPE_SOLID,
 
306
  DB_TYPE_PBXT,
 
307
  DB_TYPE_TABLE_FUNCTION,
 
308
  DB_TYPE_MEMCACHE,
 
309
  DB_TYPE_FALCON,
 
310
  DB_TYPE_MARIA,
 
311
  DB_TYPE_FIRST_DYNAMIC=42,
 
312
  DB_TYPE_DEFAULT=127 // Must be last
 
313
};
 
314
 
 
315
enum row_type { ROW_TYPE_NOT_USED=-1, ROW_TYPE_DEFAULT, ROW_TYPE_FIXED,
 
316
                ROW_TYPE_DYNAMIC, ROW_TYPE_COMPRESSED,
 
317
                ROW_TYPE_REDUNDANT, ROW_TYPE_COMPACT, ROW_TYPE_PAGE };
 
318
 
 
319
enum column_format_type { COLUMN_FORMAT_TYPE_NOT_USED= -1,
 
320
                          COLUMN_FORMAT_TYPE_DEFAULT=   0,
 
321
                          COLUMN_FORMAT_TYPE_FIXED=     1,
 
322
                          COLUMN_FORMAT_TYPE_DYNAMIC=   2 };
 
323
 
 
324
enum enum_binlog_func {
 
325
  BFN_RESET_LOGS=        1,
 
326
  BFN_RESET_SLAVE=       2,
 
327
  BFN_BINLOG_WAIT=       3,
 
328
  BFN_BINLOG_END=        4,
 
329
  BFN_BINLOG_PURGE_FILE= 5
 
330
};
 
331
 
 
332
enum enum_binlog_command {
 
333
  LOGCOM_CREATE_TABLE,
 
334
  LOGCOM_ALTER_TABLE,
 
335
  LOGCOM_RENAME_TABLE,
 
336
  LOGCOM_DROP_TABLE,
 
337
  LOGCOM_CREATE_DB,
 
338
  LOGCOM_ALTER_DB,
 
339
  LOGCOM_DROP_DB
 
340
};
 
341
 
 
342
/* struct to hold information about the table that should be created */
 
343
 
 
344
/* Bits in used_fields */
 
345
#define HA_CREATE_USED_AUTO             (1L << 0)
 
346
#define HA_CREATE_USED_RAID             (1L << 1) //RAID is no longer availble
 
347
#define HA_CREATE_USED_UNION            (1L << 2)
 
348
#define HA_CREATE_USED_INSERT_METHOD    (1L << 3)
 
349
#define HA_CREATE_USED_MIN_ROWS         (1L << 4)
 
350
#define HA_CREATE_USED_MAX_ROWS         (1L << 5)
 
351
#define HA_CREATE_USED_AVG_ROW_LENGTH   (1L << 6)
 
352
#define HA_CREATE_USED_PACK_KEYS        (1L << 7)
 
353
#define HA_CREATE_USED_CHARSET          (1L << 8)
 
354
#define HA_CREATE_USED_DEFAULT_CHARSET  (1L << 9)
 
355
#define HA_CREATE_USED_DATADIR          (1L << 10)
 
356
#define HA_CREATE_USED_INDEXDIR         (1L << 11)
 
357
#define HA_CREATE_USED_ENGINE           (1L << 12)
 
358
#define HA_CREATE_USED_CHECKSUM         (1L << 13)
 
359
#define HA_CREATE_USED_DELAY_KEY_WRITE  (1L << 14)
 
360
#define HA_CREATE_USED_ROW_FORMAT       (1L << 15)
 
361
#define HA_CREATE_USED_COMMENT          (1L << 16)
 
362
#define HA_CREATE_USED_PASSWORD         (1L << 17)
 
363
#define HA_CREATE_USED_CONNECTION       (1L << 18)
 
364
#define HA_CREATE_USED_KEY_BLOCK_SIZE   (1L << 19)
 
365
#define HA_CREATE_USED_TRANSACTIONAL    (1L << 20)
 
366
#define HA_CREATE_USED_PAGE_CHECKSUM    (1L << 21)
 
367
 
 
368
typedef uint64_t my_xid; // this line is the same as in log_event.h
 
369
#define MYSQL_XID_PREFIX "MySQLXid"
 
370
#define MYSQL_XID_PREFIX_LEN 8 // must be a multiple of 8
 
371
#define MYSQL_XID_OFFSET (MYSQL_XID_PREFIX_LEN+sizeof(server_id))
 
372
#define MYSQL_XID_GTRID_LEN (MYSQL_XID_OFFSET+sizeof(my_xid))
 
373
 
 
374
#define XIDDATASIZE MYSQL_XIDDATASIZE
 
375
#define MAXGTRIDSIZE 64
 
376
#define MAXBQUALSIZE 64
 
377
 
 
378
#define COMPATIBLE_DATA_YES 0
 
379
#define COMPATIBLE_DATA_NO  1
 
380
 
 
381
/**
 
382
  struct xid_t is binary compatible with the XID structure as
 
383
  in the X/Open CAE Specification, Distributed Transaction Processing:
 
384
  The XA Specification, X/Open Company Ltd., 1991.
 
385
  http://www.opengroup.org/bookstore/catalog/c193.htm
 
386
 
 
387
  @see MYSQL_XID in mysql/plugin.h
 
388
*/
 
389
struct xid_t {
 
390
  long formatID;
 
391
  long gtrid_length;
 
392
  long bqual_length;
 
393
  char data[XIDDATASIZE];  // not \0-terminated !
 
394
 
 
395
  xid_t() {}                                /* Remove gcc warning */  
 
396
  bool eq(struct xid_t *xid)
 
397
  { return eq(xid->gtrid_length, xid->bqual_length, xid->data); }
 
398
  bool eq(long g, long b, const char *d)
 
399
  { return g == gtrid_length && b == bqual_length && !memcmp(d, data, g+b); }
 
400
  void set(struct xid_t *xid)
 
401
  { memcpy(this, xid, xid->length()); }
 
402
  void set(long f, const char *g, long gl, const char *b, long bl)
 
403
  {
 
404
    formatID= f;
 
405
    memcpy(data, g, gtrid_length= gl);
 
406
    memcpy(data+gl, b, bqual_length= bl);
 
407
  }
 
408
  void set(uint64_t xid)
 
409
  {
 
410
    my_xid tmp;
 
411
    formatID= 1;
 
412
    set(MYSQL_XID_PREFIX_LEN, 0, MYSQL_XID_PREFIX);
 
413
    memcpy(data+MYSQL_XID_PREFIX_LEN, &server_id, sizeof(server_id));
 
414
    tmp= xid;
 
415
    memcpy(data+MYSQL_XID_OFFSET, &tmp, sizeof(tmp));
 
416
    gtrid_length=MYSQL_XID_GTRID_LEN;
 
417
  }
 
418
  void set(long g, long b, const char *d)
 
419
  {
 
420
    formatID= 1;
 
421
    gtrid_length= g;
 
422
    bqual_length= b;
 
423
    memcpy(data, d, g+b);
 
424
  }
 
425
  bool is_null() { return formatID == -1; }
 
426
  void null() { formatID= -1; }
 
427
  my_xid quick_get_my_xid()
 
428
  {
 
429
    my_xid tmp;
 
430
    memcpy(&tmp, data+MYSQL_XID_OFFSET, sizeof(tmp));
 
431
    return tmp;
 
432
  }
 
433
  my_xid get_my_xid()
 
434
  {
 
435
    return gtrid_length == MYSQL_XID_GTRID_LEN && bqual_length == 0 &&
 
436
           !memcmp(data+MYSQL_XID_PREFIX_LEN, &server_id, sizeof(server_id)) &&
 
437
           !memcmp(data, MYSQL_XID_PREFIX, MYSQL_XID_PREFIX_LEN) ?
 
438
           quick_get_my_xid() : 0;
 
439
  }
 
440
  uint length()
 
441
  {
 
442
    return sizeof(formatID)+sizeof(gtrid_length)+sizeof(bqual_length)+
 
443
           gtrid_length+bqual_length;
 
444
  }
 
445
  uchar *key()
 
446
  {
 
447
    return (uchar *)&gtrid_length;
 
448
  }
 
449
  uint key_length()
 
450
  {
 
451
    return sizeof(gtrid_length)+sizeof(bqual_length)+gtrid_length+bqual_length;
 
452
  }
 
453
};
 
454
typedef struct xid_t XID;
 
455
 
 
456
/* for recover() handlerton call */
 
457
#define MIN_XID_LIST_SIZE  128
 
458
#define MAX_XID_LIST_SIZE  (1024*128)
 
459
 
 
460
/*
 
461
  These structures are used to pass information from a set of SQL commands
 
462
  on add/drop/change tablespace definitions to the proper hton.
 
463
*/
 
464
#define UNDEF_NODEGROUP 65535
 
465
enum ts_command_type
 
466
{
 
467
  TS_CMD_NOT_DEFINED = -1,
 
468
  CREATE_TABLESPACE = 0,
 
469
  ALTER_TABLESPACE = 1,
 
470
  CREATE_LOGFILE_GROUP = 2,
 
471
  ALTER_LOGFILE_GROUP = 3,
 
472
  DROP_TABLESPACE = 4,
 
473
  DROP_LOGFILE_GROUP = 5,
 
474
  CHANGE_FILE_TABLESPACE = 6,
 
475
  ALTER_ACCESS_MODE_TABLESPACE = 7
 
476
};
 
477
 
 
478
enum ts_alter_tablespace_type
 
479
{
 
480
  TS_ALTER_TABLESPACE_TYPE_NOT_DEFINED = -1,
 
481
  ALTER_TABLESPACE_ADD_FILE = 1,
 
482
  ALTER_TABLESPACE_DROP_FILE = 2
 
483
};
 
484
 
 
485
enum tablespace_access_mode
 
486
{
 
487
  TS_NOT_DEFINED= -1,
 
488
  TS_READ_ONLY = 0,
 
489
  TS_READ_WRITE = 1,
 
490
  TS_NOT_ACCESSIBLE = 2
 
491
};
 
492
 
 
493
struct handlerton;
 
494
class st_alter_tablespace : public Sql_alloc
 
495
{
 
496
  public:
 
497
  const char *tablespace_name;
 
498
  const char *logfile_group_name;
 
499
  enum ts_command_type ts_cmd_type;
 
500
  enum ts_alter_tablespace_type ts_alter_tablespace_type;
 
501
  const char *data_file_name;
 
502
  const char *undo_file_name;
 
503
  const char *redo_file_name;
 
504
  uint64_t extent_size;
 
505
  uint64_t undo_buffer_size;
 
506
  uint64_t redo_buffer_size;
 
507
  uint64_t initial_size;
 
508
  uint64_t autoextend_size;
 
509
  uint64_t max_size;
 
510
  uint nodegroup_id;
 
511
  handlerton *storage_engine;
 
512
  bool wait_until_completed;
 
513
  const char *ts_comment;
 
514
  enum tablespace_access_mode ts_access_mode;
 
515
  st_alter_tablespace()
 
516
  {
 
517
    tablespace_name= NULL;
 
518
    logfile_group_name= "DEFAULT_LG"; //Default log file group
 
519
    ts_cmd_type= TS_CMD_NOT_DEFINED;
 
520
    data_file_name= NULL;
 
521
    undo_file_name= NULL;
 
522
    redo_file_name= NULL;
 
523
    extent_size= 1024*1024;        //Default 1 MByte
 
524
    undo_buffer_size= 8*1024*1024; //Default 8 MByte
 
525
    redo_buffer_size= 8*1024*1024; //Default 8 MByte
 
526
    initial_size= 128*1024*1024;   //Default 128 MByte
 
527
    autoextend_size= 0;            //No autoextension as default
 
528
    max_size= 0;                   //Max size == initial size => no extension
 
529
    storage_engine= NULL;
 
530
    nodegroup_id= UNDEF_NODEGROUP;
 
531
    wait_until_completed= TRUE;
 
532
    ts_comment= NULL;
 
533
    ts_access_mode= TS_NOT_DEFINED;
 
534
  }
 
535
};
 
536
 
 
537
/* The handler for a table type.  Will be included in the TABLE structure */
 
538
 
 
539
struct st_table;
 
540
typedef struct st_table TABLE;
 
541
typedef struct st_table_share TABLE_SHARE;
 
542
struct st_foreign_key_info;
 
543
typedef struct st_foreign_key_info FOREIGN_KEY_INFO;
 
544
typedef bool (stat_print_fn)(THD *thd, const char *type, uint type_len,
 
545
                             const char *file, uint file_len,
 
546
                             const char *status, uint status_len);
 
547
enum ha_stat_type { HA_ENGINE_STATUS, HA_ENGINE_LOGS, HA_ENGINE_MUTEX };
 
548
extern st_plugin_int *hton2plugin[MAX_HA];
 
549
 
 
550
/*
 
551
  handlerton is a singleton structure - one instance per storage engine -
 
552
  to provide access to storage engine functionality that works on the
 
553
  "global" level (unlike handler class that works on a per-table basis)
 
554
 
 
555
  usually handlerton instance is defined statically in ha_xxx.cc as
 
556
 
 
557
  static handlerton { ... } xxx_hton;
 
558
 
 
559
  savepoint_*, prepare, recover, and *_by_xid pointers can be 0.
 
560
*/
 
561
struct handlerton
 
562
{
 
563
  /*
 
564
    Historical marker for if the engine is available of not
 
565
  */
 
566
  SHOW_COMP_OPTION state;
 
567
 
 
568
  /*
 
569
    Historical number used for frm file to determine the correct storage engine.
 
570
    This is going away and new engines will just use "name" for this.
 
571
  */
 
572
  enum legacy_db_type db_type;
 
573
  /*
 
574
    each storage engine has it's own memory area (actually a pointer)
 
575
    in the thd, for storing per-connection information.
 
576
    It is accessed as
 
577
 
 
578
      thd->ha_data[xxx_hton.slot]
 
579
 
 
580
   slot number is initialized by MySQL after xxx_init() is called.
 
581
   */
 
582
   uint slot;
 
583
   /*
 
584
     to store per-savepoint data storage engine is provided with an area
 
585
     of a requested size (0 is ok here).
 
586
     savepoint_offset must be initialized statically to the size of
 
587
     the needed memory to store per-savepoint information.
 
588
     After xxx_init it is changed to be an offset to savepoint storage
 
589
     area and need not be used by storage engine.
 
590
     see binlog_hton and binlog_savepoint_set/rollback for an example.
 
591
   */
 
592
   uint savepoint_offset;
 
593
   /*
 
594
     handlerton methods:
 
595
 
 
596
     close_connection is only called if
 
597
     thd->ha_data[xxx_hton.slot] is non-zero, so even if you don't need
 
598
     this storage area - set it to something, so that MySQL would know
 
599
     this storage engine was accessed in this connection
 
600
   */
 
601
   int  (*close_connection)(handlerton *hton, THD *thd);
 
602
   /*
 
603
     sv points to an uninitialized storage area of requested size
 
604
     (see savepoint_offset description)
 
605
   */
 
606
   int  (*savepoint_set)(handlerton *hton, THD *thd, void *sv);
 
607
   /*
 
608
     sv points to a storage area, that was earlier passed
 
609
     to the savepoint_set call
 
610
   */
 
611
   int  (*savepoint_rollback)(handlerton *hton, THD *thd, void *sv);
 
612
   int  (*savepoint_release)(handlerton *hton, THD *thd, void *sv);
 
613
   /*
 
614
     'all' is true if it's a real commit, that makes persistent changes
 
615
     'all' is false if it's not in fact a commit but an end of the
 
616
     statement that is part of the transaction.
 
617
     NOTE 'all' is also false in auto-commit mode where 'end of statement'
 
618
     and 'real commit' mean the same event.
 
619
   */
 
620
   int  (*commit)(handlerton *hton, THD *thd, bool all);
 
621
   int  (*rollback)(handlerton *hton, THD *thd, bool all);
 
622
   int  (*prepare)(handlerton *hton, THD *thd, bool all);
 
623
   int  (*recover)(handlerton *hton, XID *xid_list, uint len);
 
624
   int  (*commit_by_xid)(handlerton *hton, XID *xid);
 
625
   int  (*rollback_by_xid)(handlerton *hton, XID *xid);
 
626
   void *(*create_cursor_read_view)(handlerton *hton, THD *thd);
 
627
   void (*set_cursor_read_view)(handlerton *hton, THD *thd, void *read_view);
 
628
   void (*close_cursor_read_view)(handlerton *hton, THD *thd, void *read_view);
 
629
   handler *(*create)(handlerton *hton, TABLE_SHARE *table, MEM_ROOT *mem_root);
 
630
   void (*drop_database)(handlerton *hton, char* path);
 
631
   int (*panic)(handlerton *hton, enum ha_panic_function flag);
 
632
   int (*start_consistent_snapshot)(handlerton *hton, THD *thd);
 
633
   bool (*flush_logs)(handlerton *hton);
 
634
   bool (*show_status)(handlerton *hton, THD *thd, stat_print_fn *print, enum ha_stat_type stat);
 
635
   int (*alter_tablespace)(handlerton *hton, THD *thd, st_alter_tablespace *ts_info);
 
636
   int (*fill_files_table)(handlerton *hton, THD *thd,
 
637
                           TABLE_LIST *tables,
 
638
                           class Item *cond);
 
639
   uint32 flags;                                /* global handler flags */
 
640
   int (*release_temporary_latches)(handlerton *hton, THD *thd);
 
641
 
 
642
   int (*discover)(handlerton *hton, THD* thd, const char *db, 
 
643
                   const char *name,
 
644
                   uchar **frmblob, 
 
645
                   size_t *frmlen);
 
646
   int (*table_exists_in_engine)(handlerton *hton, THD* thd, const char *db,
 
647
                                 const char *name);
 
648
   uint32 license; /* Flag for Engine License */
 
649
   void *data; /* Location for engines to keep personal structures */
 
650
};
 
651
 
 
652
 
 
653
/* Possible flags of a handlerton (there can be 32 of them) */
 
654
#define HTON_NO_FLAGS                 0
 
655
#define HTON_CLOSE_CURSORS_AT_COMMIT (1 << 0)
 
656
#define HTON_ALTER_NOT_SUPPORTED     (1 << 1) //Engine does not support alter
 
657
#define HTON_CAN_RECREATE            (1 << 2) //Delete all is used fro truncate
 
658
#define HTON_HIDDEN                  (1 << 3) //Engine does not appear in lists
 
659
#define HTON_FLUSH_AFTER_RENAME      (1 << 4)
 
660
#define HTON_NOT_USER_SELECTABLE     (1 << 5)
 
661
#define HTON_TEMPORARY_NOT_SUPPORTED (1 << 6) //Having temporary tables not supported
 
662
#define HTON_SUPPORT_LOG_TABLES      (1 << 7) //Engine supports log tables
 
663
#define HTON_NO_PARTITION            (1 << 8) //You can not partition these tables
 
664
 
 
665
class Ha_trx_info;
 
666
 
 
667
struct THD_TRANS
 
668
{
 
669
  /* true is not all entries in the ht[] support 2pc */
 
670
  bool        no_2pc;
 
671
  /* storage engines that registered in this transaction */
 
672
  Ha_trx_info *ha_list;
 
673
  /* 
 
674
    The purpose of this flag is to keep track of non-transactional
 
675
    tables that were modified in scope of:
 
676
    - transaction, when the variable is a member of
 
677
    THD::transaction.all
 
678
    - top-level statement or sub-statement, when the variable is a
 
679
    member of THD::transaction.stmt
 
680
    This member has the following life cycle:
 
681
    * stmt.modified_non_trans_table is used to keep track of
 
682
    modified non-transactional tables of top-level statements. At
 
683
    the end of the previous statement and at the beginning of the session,
 
684
    it is reset to FALSE.  If such functions
 
685
    as mysql_insert, mysql_update, mysql_delete etc modify a
 
686
    non-transactional table, they set this flag to TRUE.  At the
 
687
    end of the statement, the value of stmt.modified_non_trans_table 
 
688
    is merged with all.modified_non_trans_table and gets reset.
 
689
    * all.modified_non_trans_table is reset at the end of transaction
 
690
    
 
691
    * Since we do not have a dedicated context for execution of a
 
692
    sub-statement, to keep track of non-transactional changes in a
 
693
    sub-statement, we re-use stmt.modified_non_trans_table. 
 
694
    At entrance into a sub-statement, a copy of the value of
 
695
    stmt.modified_non_trans_table (containing the changes of the
 
696
    outer statement) is saved on stack. Then 
 
697
    stmt.modified_non_trans_table is reset to FALSE and the
 
698
    substatement is executed. Then the new value is merged with the
 
699
    saved value.
 
700
  */
 
701
  bool modified_non_trans_table;
 
702
 
 
703
  void reset() { no_2pc= FALSE; modified_non_trans_table= FALSE; }
 
704
};
 
705
 
 
706
 
 
707
/**
 
708
  Either statement transaction or normal transaction - related
 
709
  thread-specific storage engine data.
 
710
 
 
711
  If a storage engine participates in a statement/transaction,
 
712
  an instance of this class is present in
 
713
  thd->transaction.{stmt|all}.ha_list. The addition to
 
714
  {stmt|all}.ha_list is made by trans_register_ha().
 
715
 
 
716
  When it's time to commit or rollback, each element of ha_list
 
717
  is used to access storage engine's prepare()/commit()/rollback()
 
718
  methods, and also to evaluate if a full two phase commit is
 
719
  necessary.
 
720
 
 
721
  @sa General description of transaction handling in handler.cc.
 
722
*/
 
723
 
 
724
class Ha_trx_info
 
725
{
 
726
public:
 
727
  /** Register this storage engine in the given transaction context. */
 
728
  void register_ha(THD_TRANS *trans, handlerton *ht_arg)
 
729
  {
 
730
    DBUG_ASSERT(m_flags == 0);
 
731
    DBUG_ASSERT(m_ht == NULL);
 
732
    DBUG_ASSERT(m_next == NULL);
 
733
 
 
734
    m_ht= ht_arg;
 
735
    m_flags= (int) TRX_READ_ONLY; /* Assume read-only at start. */
 
736
 
 
737
    m_next= trans->ha_list;
 
738
    trans->ha_list= this;
 
739
  }
 
740
 
 
741
  /** Clear, prepare for reuse. */
 
742
  void reset()
 
743
  {
 
744
    m_next= NULL;
 
745
    m_ht= NULL;
 
746
    m_flags= 0;
 
747
  }
 
748
 
 
749
  Ha_trx_info() { reset(); }
 
750
 
 
751
  void set_trx_read_write()
 
752
  {
 
753
    DBUG_ASSERT(is_started());
 
754
    m_flags|= (int) TRX_READ_WRITE;
 
755
  }
 
756
  bool is_trx_read_write() const
 
757
  {
 
758
    DBUG_ASSERT(is_started());
 
759
    return m_flags & (int) TRX_READ_WRITE;
 
760
  }
 
761
  bool is_started() const { return m_ht != NULL; }
 
762
  /** Mark this transaction read-write if the argument is read-write. */
 
763
  void coalesce_trx_with(const Ha_trx_info *stmt_trx)
 
764
  {
 
765
    /*
 
766
      Must be called only after the transaction has been started.
 
767
      Can be called many times, e.g. when we have many
 
768
      read-write statements in a transaction.
 
769
    */
 
770
    DBUG_ASSERT(is_started());
 
771
    if (stmt_trx->is_trx_read_write())
 
772
      set_trx_read_write();
 
773
  }
 
774
  Ha_trx_info *next() const
 
775
  {
 
776
    DBUG_ASSERT(is_started());
 
777
    return m_next;
 
778
  }
 
779
  handlerton *ht() const
 
780
  {
 
781
    DBUG_ASSERT(is_started());
 
782
    return m_ht;
 
783
  }
 
784
private:
 
785
  enum { TRX_READ_ONLY= 0, TRX_READ_WRITE= 1 };
 
786
  /** Auxiliary, used for ha_list management */
 
787
  Ha_trx_info *m_next;
 
788
  /**
 
789
    Although a given Ha_trx_info instance is currently always used
 
790
    for the same storage engine, 'ht' is not-NULL only when the
 
791
    corresponding storage is a part of a transaction.
 
792
  */
 
793
  handlerton *m_ht;
 
794
  /**
 
795
    Transaction flags related to this engine.
 
796
    Not-null only if this instance is a part of transaction.
 
797
    May assume a combination of enum values above.
 
798
  */
 
799
  uchar       m_flags;
 
800
};
 
801
 
 
802
 
 
803
enum enum_tx_isolation { ISO_READ_UNCOMMITTED, ISO_READ_COMMITTED,
 
804
                         ISO_REPEATABLE_READ, ISO_SERIALIZABLE};
 
805
 
 
806
 
 
807
enum ndb_distribution { ND_KEYHASH= 0, ND_LINHASH= 1 };
 
808
 
 
809
 
 
810
typedef struct {
 
811
  uint64_t data_file_length;
 
812
  uint64_t max_data_file_length;
 
813
  uint64_t index_file_length;
 
814
  uint64_t delete_length;
 
815
  ha_rows records;
 
816
  ulong mean_rec_length;
 
817
  time_t create_time;
 
818
  time_t check_time;
 
819
  time_t update_time;
 
820
  uint64_t check_sum;
 
821
} PARTITION_INFO;
 
822
 
 
823
#define UNDEF_NODEGROUP 65535
 
824
class Item;
 
825
struct st_table_log_memory_entry;
 
826
 
 
827
#define NOT_A_PARTITION_ID ((uint32)-1)
 
828
 
 
829
enum ha_choice { HA_CHOICE_UNDEF, HA_CHOICE_NO, HA_CHOICE_YES };
 
830
 
 
831
typedef struct st_ha_create_information
 
832
{
 
833
  CHARSET_INFO *table_charset, *default_table_charset;
 
834
  LEX_STRING connect_string;
 
835
  const char *password, *tablespace;
 
836
  LEX_STRING comment;
 
837
  const char *data_file_name, *index_file_name;
 
838
  const char *alias;
 
839
  uint64_t max_rows,min_rows;
 
840
  uint64_t auto_increment_value;
 
841
  ulong table_options;
 
842
  ulong avg_row_length;
 
843
  ulong used_fields;
 
844
  ulong key_block_size;
 
845
  SQL_LIST merge_list;
 
846
  handlerton *db_type;
 
847
  enum row_type row_type;
 
848
  uint null_bits;                       /* NULL bits at start of record */
 
849
  uint options;                         /* OR of HA_CREATE_ options */
 
850
  uint merge_insert_method;
 
851
  uint extra_size;                      /* length of extra data segment */
 
852
  /* 0 not used, 1 if not transactional, 2 if transactional */
 
853
  enum ha_choice transactional;
 
854
  bool table_existed;                   /* 1 in create if table existed */
 
855
  bool frm_only;                        /* 1 if no ha_create_table() */
 
856
  bool varchar;                         /* 1 if table has a VARCHAR */
 
857
  enum ha_storage_media default_storage_media;  /* DEFAULT, DISK or MEMORY */
 
858
  enum ha_choice page_checksum;         /* If we have page_checksums */
 
859
} HA_CREATE_INFO;
 
860
 
 
861
typedef struct st_ha_alter_information
 
862
{
 
863
  KEY  *key_info_buffer;
 
864
  uint key_count;
 
865
  uint index_drop_count;
 
866
  uint *index_drop_buffer;
 
867
  uint index_add_count;
 
868
  uint *index_add_buffer;
 
869
  void *data;
 
870
} HA_ALTER_INFO;
 
871
 
 
872
 
 
873
typedef struct st_key_create_information
 
874
{
 
875
  enum ha_key_alg algorithm;
 
876
  ulong block_size;
 
877
  LEX_STRING parser_name;
 
878
  LEX_STRING comment;
 
879
} KEY_CREATE_INFO;
 
880
 
 
881
 
 
882
/*
 
883
  Class for maintaining hooks used inside operations on tables such
 
884
  as: create table functions, delete table functions, and alter table
 
885
  functions.
 
886
 
 
887
  Class is using the Template Method pattern to separate the public
 
888
  usage interface from the private inheritance interface.  This
 
889
  imposes no overhead, since the public non-virtual function is small
 
890
  enough to be inlined.
 
891
 
 
892
  The hooks are usually used for functions that does several things,
 
893
  e.g., create_table_from_items(), which both create a table and lock
 
894
  it.
 
895
 */
 
896
class TABLEOP_HOOKS
 
897
{
 
898
public:
 
899
  TABLEOP_HOOKS() {}
 
900
  virtual ~TABLEOP_HOOKS() {}
 
901
 
 
902
  inline void prelock(TABLE **tables, uint count)
 
903
  {
 
904
    do_prelock(tables, count);
 
905
  }
 
906
 
 
907
  inline int postlock(TABLE **tables, uint count)
 
908
  {
 
909
    return do_postlock(tables, count);
 
910
  }
 
911
private:
 
912
  /* Function primitive that is called prior to locking tables */
 
913
  virtual void do_prelock(TABLE **tables, uint count)
 
914
  {
 
915
    /* Default is to do nothing */
 
916
  }
 
917
 
 
918
  /**
 
919
     Primitive called after tables are locked.
 
920
 
 
921
     If an error is returned, the tables will be unlocked and error
 
922
     handling start.
 
923
 
 
924
     @return Error code or zero.
 
925
   */
 
926
  virtual int do_postlock(TABLE **tables, uint count)
 
927
  {
 
928
    return 0;                           /* Default is to do nothing */
 
929
  }
 
930
};
 
931
 
 
932
typedef struct st_savepoint SAVEPOINT;
 
933
extern ulong savepoint_alloc_size;
 
934
extern KEY_CREATE_INFO default_key_create_info;
 
935
 
 
936
/* Forward declaration for condition pushdown to storage engine */
 
937
typedef class Item COND;
 
938
 
 
939
typedef struct st_ha_check_opt
 
940
{
 
941
  st_ha_check_opt() {}                        /* Remove gcc warning */
 
942
  ulong sort_buffer_size;
 
943
  uint flags;       /* isam layer flags (e.g. for myisamchk) */
 
944
  uint sql_flags;   /* sql layer flags - for something myisamchk cannot do */
 
945
  KEY_CACHE *key_cache; /* new key cache when changing key cache */
 
946
  void init();
 
947
} HA_CHECK_OPT;
 
948
 
 
949
 
 
950
 
 
951
/*
 
952
  This is a buffer area that the handler can use to store rows.
 
953
  'end_of_used_area' should be kept updated after calls to
 
954
  read-functions so that other parts of the code can use the
 
955
  remaining area (until next read calls is issued).
 
956
*/
 
957
 
 
958
typedef struct st_handler_buffer
 
959
{
 
960
  uchar *buffer;         /* Buffer one can start using */
 
961
  uchar *buffer_end;     /* End of buffer */
 
962
  uchar *end_of_used_area;     /* End of area that was used by handler */
 
963
} HANDLER_BUFFER;
 
964
 
 
965
typedef struct system_status_var SSV;
 
966
 
 
967
 
 
968
typedef void *range_seq_t;
 
969
 
 
970
typedef struct st_range_seq_if
 
971
{
 
972
  /*
 
973
    Initialize the traversal of range sequence
 
974
    
 
975
    SYNOPSIS
 
976
      init()
 
977
        init_params  The seq_init_param parameter 
 
978
        n_ranges     The number of ranges obtained 
 
979
        flags        A combination of HA_MRR_SINGLE_POINT, HA_MRR_FIXED_KEY
 
980
 
 
981
    RETURN
 
982
      An opaque value to be used as RANGE_SEQ_IF::next() parameter
 
983
  */
 
984
  range_seq_t (*init)(void *init_params, uint n_ranges, uint flags);
 
985
 
 
986
 
 
987
  /*
 
988
    Get the next range in the range sequence
 
989
 
 
990
    SYNOPSIS
 
991
      next()
 
992
        seq    The value returned by RANGE_SEQ_IF::init()
 
993
        range  OUT Information about the next range
 
994
    
 
995
    RETURN
 
996
      0 - Ok, the range structure filled with info about the next range
 
997
      1 - No more ranges
 
998
  */
 
999
  uint (*next) (range_seq_t seq, KEY_MULTI_RANGE *range);
 
1000
} RANGE_SEQ_IF;
 
1001
 
 
1002
uint16 &mrr_persistent_flag_storage(range_seq_t seq, uint idx);
 
1003
char* &mrr_get_ptr_by_idx(range_seq_t seq, uint idx);
 
1004
 
 
1005
class COST_VECT
 
1006
 
1007
public:
 
1008
  double io_count;     /* number of I/O                 */
 
1009
  double avg_io_cost;  /* cost of an average I/O oper.  */
 
1010
  double cpu_cost;     /* cost of operations in CPU     */
 
1011
  double mem_cost;     /* cost of used memory           */ 
 
1012
  double import_cost;  /* cost of remote operations     */
 
1013
  
 
1014
  enum { IO_COEFF=1 };
 
1015
  enum { CPU_COEFF=1 };
 
1016
  enum { MEM_COEFF=1 };
 
1017
  enum { IMPORT_COEFF=1 };
 
1018
 
 
1019
  COST_VECT() {}                              // keep gcc happy
 
1020
 
 
1021
  double total_cost() 
 
1022
  {
 
1023
    return IO_COEFF*io_count*avg_io_cost + CPU_COEFF * cpu_cost +
 
1024
           MEM_COEFF*mem_cost + IMPORT_COEFF*import_cost;
 
1025
  }
 
1026
 
 
1027
  void zero()
 
1028
  {
 
1029
    avg_io_cost= 1.0;
 
1030
    io_count= cpu_cost= mem_cost= import_cost= 0.0;
 
1031
  }
 
1032
 
 
1033
  void multiply(double m)
 
1034
  {
 
1035
    io_count *= m;
 
1036
    cpu_cost *= m;
 
1037
    import_cost *= m;
 
1038
    /* Don't multiply mem_cost */
 
1039
  }
 
1040
 
 
1041
  void add(const COST_VECT* cost)
 
1042
  {
 
1043
    double io_count_sum= io_count + cost->io_count;
 
1044
    add_io(cost->io_count, cost->avg_io_cost);
 
1045
    io_count= io_count_sum;
 
1046
    cpu_cost += cost->cpu_cost;
 
1047
  }
 
1048
  void add_io(double add_io_cnt, double add_avg_cost)
 
1049
  {
 
1050
    double io_count_sum= io_count + add_io_cnt;
 
1051
    avg_io_cost= (io_count * avg_io_cost + 
 
1052
                  add_io_cnt * add_avg_cost) / io_count_sum;
 
1053
    io_count= io_count_sum;
 
1054
  }
 
1055
};
 
1056
 
 
1057
void get_sweep_read_cost(TABLE *table, ha_rows nrows, bool interrupted, 
 
1058
                         COST_VECT *cost);
 
1059
 
 
1060
/*
 
1061
  The below two are not used (and not handled) in this milestone of this WL
 
1062
  entry because there seems to be no use for them at this stage of
 
1063
  implementation.
 
1064
*/
 
1065
#define HA_MRR_SINGLE_POINT 1
 
1066
#define HA_MRR_FIXED_KEY  2
 
1067
 
 
1068
/* 
 
1069
  Indicates that RANGE_SEQ_IF::next(&range) doesn't need to fill in the
 
1070
  'range' parameter.
 
1071
*/
 
1072
#define HA_MRR_NO_ASSOCIATION 4
 
1073
 
 
1074
/* 
 
1075
  The MRR user will provide ranges in key order, and MRR implementation
 
1076
  must return rows in key order.
 
1077
*/
 
1078
#define HA_MRR_SORTED 8
 
1079
 
 
1080
/* MRR implementation doesn't have to retrieve full records */
 
1081
#define HA_MRR_INDEX_ONLY 16
 
1082
 
 
1083
/* 
 
1084
  The passed memory buffer is of maximum possible size, the caller can't
 
1085
  assume larger buffer.
 
1086
*/
 
1087
#define HA_MRR_LIMITS 32
 
1088
 
 
1089
 
 
1090
/*
 
1091
  Flag set <=> default MRR implementation is used
 
1092
  (The choice is made by **_info[_const]() function which may set this
 
1093
   flag. SQL layer remembers the flag value and then passes it to
 
1094
   multi_read_range_init().
 
1095
*/
 
1096
#define HA_MRR_USE_DEFAULT_IMPL 64
 
1097
 
 
1098
/*
 
1099
  Used only as parameter to multi_range_read_info():
 
1100
  Flag set <=> the caller guarantees that the bounds of the scanned ranges
 
1101
  will not have NULL values.
 
1102
*/
 
1103
#define HA_MRR_NO_NULL_ENDPOINTS 128
 
1104
 
 
1105
 
 
1106
class ha_statistics
 
1107
{
 
1108
public:
 
1109
  uint64_t data_file_length;            /* Length off data file */
 
1110
  uint64_t max_data_file_length;        /* Length off data file */
 
1111
  uint64_t index_file_length;
 
1112
  uint64_t max_index_file_length;
 
1113
  uint64_t delete_length;               /* Free bytes */
 
1114
  uint64_t auto_increment_value;
 
1115
  /*
 
1116
    The number of records in the table. 
 
1117
      0    - means the table has exactly 0 rows
 
1118
    other  - if (table_flags() & HA_STATS_RECORDS_IS_EXACT)
 
1119
               the value is the exact number of records in the table
 
1120
             else
 
1121
               it is an estimate
 
1122
  */
 
1123
  ha_rows records;
 
1124
  ha_rows deleted;                      /* Deleted records */
 
1125
  ulong mean_rec_length;                /* physical reclength */
 
1126
  time_t create_time;                   /* When table was created */
 
1127
  time_t check_time;
 
1128
  time_t update_time;
 
1129
  uint block_size;                      /* index block size */
 
1130
 
 
1131
  ha_statistics():
 
1132
    data_file_length(0), max_data_file_length(0),
 
1133
    index_file_length(0), delete_length(0), auto_increment_value(0),
 
1134
    records(0), deleted(0), mean_rec_length(0), create_time(0),
 
1135
    check_time(0), update_time(0), block_size(0)
 
1136
  {}
 
1137
};
 
1138
 
 
1139
uint calculate_key_len(TABLE *, uint, const uchar *, key_part_map);
 
1140
/*
 
1141
  bitmap with first N+1 bits set
 
1142
  (keypart_map for a key prefix of [0..N] keyparts)
 
1143
*/
 
1144
#define make_keypart_map(N) (((key_part_map)2 << (N)) - 1)
 
1145
/*
 
1146
  bitmap with first N bits set
 
1147
  (keypart_map for a key prefix of [0..N-1] keyparts)
 
1148
*/
 
1149
#define make_prev_keypart_map(N) (((key_part_map)1 << (N)) - 1)
 
1150
 
 
1151
/**
 
1152
  The handler class is the interface for dynamically loadable
 
1153
  storage engines. Do not add ifdefs and take care when adding or
 
1154
  changing virtual functions to avoid vtable confusion
 
1155
 
 
1156
  Functions in this class accept and return table columns data. Two data
 
1157
  representation formats are used:
 
1158
  1. TableRecordFormat - Used to pass [partial] table records to/from
 
1159
     storage engine
 
1160
 
 
1161
  2. KeyTupleFormat - used to pass index search tuples (aka "keys") to
 
1162
     storage engine. See opt_range.cc for description of this format.
 
1163
 
 
1164
  TableRecordFormat
 
1165
  =================
 
1166
  [Warning: this description is work in progress and may be incomplete]
 
1167
  The table record is stored in a fixed-size buffer:
 
1168
   
 
1169
    record: null_bytes, column1_data, column2_data, ...
 
1170
  
 
1171
  The offsets of the parts of the buffer are also fixed: every column has 
 
1172
  an offset to its column{i}_data, and if it is nullable it also has its own
 
1173
  bit in null_bytes. 
 
1174
 
 
1175
  The record buffer only includes data about columns that are marked in the
 
1176
  relevant column set (table->read_set and/or table->write_set, depending on
 
1177
  the situation). 
 
1178
  <not-sure>It could be that it is required that null bits of non-present
 
1179
  columns are set to 1</not-sure>
 
1180
 
 
1181
  VARIOUS EXCEPTIONS AND SPECIAL CASES
 
1182
 
 
1183
  f the table has no nullable columns, then null_bytes is still 
 
1184
  present, its length is one byte <not-sure> which must be set to 0xFF 
 
1185
  at all times. </not-sure>
 
1186
  
 
1187
  If the table has columns of type BIT, then certain bits from those columns
 
1188
  may be stored in null_bytes as well. Grep around for Field_bit for
 
1189
  details.
 
1190
 
 
1191
  For blob columns (see Field_blob), the record buffer stores length of the 
 
1192
  data, following by memory pointer to the blob data. The pointer is owned 
 
1193
  by the storage engine and is valid until the next operation.
 
1194
 
 
1195
  If a blob column has NULL value, then its length and blob data pointer
 
1196
  must be set to 0.
 
1197
*/
 
1198
 
 
1199
class handler :public Sql_alloc
 
1200
{
 
1201
public:
 
1202
  typedef uint64_t Table_flags;
 
1203
protected:
 
1204
  struct st_table_share *table_share;   /* The table definition */
 
1205
  struct st_table *table;               /* The current open table */
 
1206
  Table_flags cached_table_flags;       /* Set on init() and open() */
 
1207
 
 
1208
  ha_rows estimation_rows_to_insert;
 
1209
public:
 
1210
  handlerton *ht;                 /* storage engine of this handler */
 
1211
  uchar *ref;                           /* Pointer to current row */
 
1212
  uchar *dup_ref;                       /* Pointer to duplicate row */
 
1213
 
 
1214
  ha_statistics stats;
 
1215
  /** MultiRangeRead-related members: */
 
1216
  range_seq_t mrr_iter;    /* Interator to traverse the range sequence */
 
1217
  RANGE_SEQ_IF mrr_funcs;  /* Range sequence traversal functions */
 
1218
  HANDLER_BUFFER *multi_range_buffer; /* MRR buffer info */
 
1219
  uint ranges_in_seq; /* Total number of ranges in the traversed sequence */
 
1220
  /* TRUE <=> source MRR ranges and the output are ordered */
 
1221
  bool mrr_is_output_sorted;
 
1222
 
 
1223
  /** TRUE <=> we're currently traversing a range in mrr_cur_range. */
 
1224
  bool mrr_have_range;
 
1225
  /** Current range (the one we're now returning rows from) */
 
1226
  KEY_MULTI_RANGE mrr_cur_range;
 
1227
 
 
1228
  /** The following are for read_range() */
 
1229
  key_range save_end_range, *end_range;
 
1230
  KEY_PART_INFO *range_key_part;
 
1231
  int key_compare_result_on_equal;
 
1232
  bool eq_range;
 
1233
  /* 
 
1234
    TRUE <=> the engine guarantees that returned records are within the range
 
1235
    being scanned.
 
1236
  */
 
1237
  bool in_range_check_pushed_down;
 
1238
 
 
1239
  uint errkey;                          /* Last dup key */
 
1240
  uint key_used_on_scan;
 
1241
  uint active_index;
 
1242
  /** Length of ref (1-8 or the clustered key length) */
 
1243
  uint ref_length;
 
1244
  FT_INFO *ft_handler;
 
1245
  enum {NONE=0, INDEX, RND} inited;
 
1246
  bool locked;
 
1247
  bool implicit_emptied;                /* Can be !=0 only if HEAP */
 
1248
  const Item *pushed_cond;
 
1249
 
 
1250
  Item *pushed_idx_cond;
 
1251
  uint pushed_idx_cond_keyno;  /* The index which the above condition is for */
 
1252
 
 
1253
  /**
 
1254
    next_insert_id is the next value which should be inserted into the
 
1255
    auto_increment column: in a inserting-multi-row statement (like INSERT
 
1256
    SELECT), for the first row where the autoinc value is not specified by the
 
1257
    statement, get_auto_increment() called and asked to generate a value,
 
1258
    next_insert_id is set to the next value, then for all other rows
 
1259
    next_insert_id is used (and increased each time) without calling
 
1260
    get_auto_increment().
 
1261
  */
 
1262
  uint64_t next_insert_id;
 
1263
  /**
 
1264
    insert id for the current row (*autogenerated*; if not
 
1265
    autogenerated, it's 0).
 
1266
    At first successful insertion, this variable is stored into
 
1267
    THD::first_successful_insert_id_in_cur_stmt.
 
1268
  */
 
1269
  uint64_t insert_id_for_cur_row;
 
1270
  /**
 
1271
    Interval returned by get_auto_increment() and being consumed by the
 
1272
    inserter.
 
1273
  */
 
1274
  Discrete_interval auto_inc_interval_for_cur_row;
 
1275
 
 
1276
  handler(handlerton *ht_arg, TABLE_SHARE *share_arg)
 
1277
    :table_share(share_arg), table(0),
 
1278
    estimation_rows_to_insert(0), ht(ht_arg),
 
1279
    ref(0), in_range_check_pushed_down(FALSE),
 
1280
    key_used_on_scan(MAX_KEY), active_index(MAX_KEY),
 
1281
    ref_length(sizeof(my_off_t)),
 
1282
    ft_handler(0), inited(NONE),
 
1283
    locked(FALSE), implicit_emptied(0),
 
1284
    pushed_cond(0), pushed_idx_cond(NULL), pushed_idx_cond_keyno(MAX_KEY),
 
1285
    next_insert_id(0), insert_id_for_cur_row(0)
 
1286
    {}
 
1287
  virtual ~handler(void)
 
1288
  {
 
1289
    DBUG_ASSERT(locked == FALSE);
 
1290
    /* TODO: DBUG_ASSERT(inited == NONE); */
 
1291
  }
 
1292
  virtual handler *clone(MEM_ROOT *mem_root);
 
1293
  /** This is called after create to allow us to set up cached variables */
 
1294
  void init()
 
1295
  {
 
1296
    cached_table_flags= table_flags();
 
1297
  }
 
1298
  /* ha_ methods: pubilc wrappers for private virtual API */
 
1299
 
 
1300
  int ha_open(TABLE *table, const char *name, int mode, int test_if_locked);
 
1301
  int ha_index_init(uint idx, bool sorted)
 
1302
  {
 
1303
    int result;
 
1304
    DBUG_ENTER("ha_index_init");
 
1305
    DBUG_ASSERT(inited==NONE);
 
1306
    if (!(result= index_init(idx, sorted)))
 
1307
      inited=INDEX;
 
1308
    end_range= NULL;
 
1309
    DBUG_RETURN(result);
 
1310
  }
 
1311
  int ha_index_end()
 
1312
  {
 
1313
    DBUG_ENTER("ha_index_end");
 
1314
    DBUG_ASSERT(inited==INDEX);
 
1315
    inited=NONE;
 
1316
    end_range= NULL;
 
1317
    DBUG_RETURN(index_end());
 
1318
  }
 
1319
  int ha_rnd_init(bool scan)
 
1320
  {
 
1321
    int result;
 
1322
    DBUG_ENTER("ha_rnd_init");
 
1323
    DBUG_ASSERT(inited==NONE || (inited==RND && scan));
 
1324
    inited= (result= rnd_init(scan)) ? NONE: RND;
 
1325
    DBUG_RETURN(result);
 
1326
  }
 
1327
  int ha_rnd_end()
 
1328
  {
 
1329
    DBUG_ENTER("ha_rnd_end");
 
1330
    DBUG_ASSERT(inited==RND);
 
1331
    inited=NONE;
 
1332
    DBUG_RETURN(rnd_end());
 
1333
  }
 
1334
  int ha_reset();
 
1335
  /* this is necessary in many places, e.g. in HANDLER command */
 
1336
  int ha_index_or_rnd_end()
 
1337
  {
 
1338
    return inited == INDEX ? ha_index_end() : inited == RND ? ha_rnd_end() : 0;
 
1339
  }
 
1340
  Table_flags ha_table_flags() const { return cached_table_flags; }
 
1341
  /**
 
1342
    These functions represent the public interface to *users* of the
 
1343
    handler class, hence they are *not* virtual. For the inheritance
 
1344
    interface, see the (private) functions write_row(), update_row(),
 
1345
    and delete_row() below.
 
1346
  */
 
1347
  int ha_external_lock(THD *thd, int lock_type);
 
1348
  int ha_write_row(uchar * buf);
 
1349
  int ha_update_row(const uchar * old_data, uchar * new_data);
 
1350
  int ha_delete_row(const uchar * buf);
 
1351
  void ha_release_auto_increment();
 
1352
 
 
1353
  int ha_check_for_upgrade(HA_CHECK_OPT *check_opt);
 
1354
  /** to be actually called to get 'check()' functionality*/
 
1355
  int ha_check(THD *thd, HA_CHECK_OPT *check_opt);
 
1356
  int ha_repair(THD* thd, HA_CHECK_OPT* check_opt);
 
1357
  void ha_start_bulk_insert(ha_rows rows)
 
1358
  {
 
1359
    estimation_rows_to_insert= rows;
 
1360
    start_bulk_insert(rows);
 
1361
  }
 
1362
  int ha_end_bulk_insert()
 
1363
  {
 
1364
    estimation_rows_to_insert= 0;
 
1365
    return end_bulk_insert();
 
1366
  }
 
1367
  int ha_bulk_update_row(const uchar *old_data, uchar *new_data,
 
1368
                         uint *dup_key_found);
 
1369
  int ha_delete_all_rows();
 
1370
  int ha_reset_auto_increment(uint64_t value);
 
1371
  int ha_optimize(THD* thd, HA_CHECK_OPT* check_opt);
 
1372
  int ha_analyze(THD* thd, HA_CHECK_OPT* check_opt);
 
1373
  bool ha_check_and_repair(THD *thd);
 
1374
  int ha_disable_indexes(uint mode);
 
1375
  int ha_enable_indexes(uint mode);
 
1376
  int ha_discard_or_import_tablespace(my_bool discard);
 
1377
  void ha_prepare_for_alter();
 
1378
  int ha_rename_table(const char *from, const char *to);
 
1379
  int ha_delete_table(const char *name);
 
1380
  void ha_drop_table(const char *name);
 
1381
 
 
1382
  int ha_create(const char *name, TABLE *form, HA_CREATE_INFO *info);
 
1383
 
 
1384
  int ha_create_handler_files(const char *name, const char *old_name,
 
1385
                              int action_flag, HA_CREATE_INFO *info);
 
1386
 
 
1387
  void adjust_next_insert_id_after_explicit_value(uint64_t nr);
 
1388
  int update_auto_increment();
 
1389
  void print_keydup_error(uint key_nr, const char *msg);
 
1390
  virtual void print_error(int error, myf errflag);
 
1391
  virtual bool get_error_message(int error, String *buf);
 
1392
  uint get_dup_key(int error);
 
1393
  virtual void change_table_ptr(TABLE *table_arg, TABLE_SHARE *share)
 
1394
  {
 
1395
    table= table_arg;
 
1396
    table_share= share;
 
1397
  }
 
1398
  /* Estimates calculation */
 
1399
  virtual double scan_time()
 
1400
  { return ulonglong2double(stats.data_file_length) / IO_SIZE + 2; }
 
1401
  virtual double read_time(uint index, uint ranges, ha_rows rows)
 
1402
  { return rows2double(ranges+rows); }
 
1403
 
 
1404
  virtual double index_only_read_time(uint keynr, double records);
 
1405
  
 
1406
  virtual ha_rows multi_range_read_info_const(uint keyno, RANGE_SEQ_IF *seq,
 
1407
                                              void *seq_init_param, 
 
1408
                                              uint n_ranges, uint *bufsz,
 
1409
                                              uint *flags, COST_VECT *cost);
 
1410
  virtual int multi_range_read_info(uint keyno, uint n_ranges, uint keys,
 
1411
                                    uint *bufsz, uint *flags, COST_VECT *cost);
 
1412
  virtual int multi_range_read_init(RANGE_SEQ_IF *seq, void *seq_init_param,
 
1413
                                    uint n_ranges, uint mode,
 
1414
                                    HANDLER_BUFFER *buf);
 
1415
  virtual int multi_range_read_next(char **range_info);
 
1416
 
 
1417
 
 
1418
  virtual const key_map *keys_to_use_for_scanning() { return &key_map_empty; }
 
1419
  bool has_transactions()
 
1420
  { return (ha_table_flags() & HA_NO_TRANSACTIONS) == 0; }
 
1421
  virtual uint extra_rec_buf_length() const { return 0; }
 
1422
 
 
1423
  /**
 
1424
    This method is used to analyse the error to see whether the error
 
1425
    is ignorable or not, certain handlers can have more error that are
 
1426
    ignorable than others. E.g. the partition handler can get inserts
 
1427
    into a range where there is no partition and this is an ignorable
 
1428
    error.
 
1429
    HA_ERR_FOUND_DUP_UNIQUE is a special case in MyISAM that means the
 
1430
    same thing as HA_ERR_FOUND_DUP_KEY but can in some cases lead to
 
1431
    a slightly different error message.
 
1432
  */
 
1433
  virtual bool is_fatal_error(int error, uint flags)
 
1434
  {
 
1435
    if (!error ||
 
1436
        ((flags & HA_CHECK_DUP_KEY) &&
 
1437
         (error == HA_ERR_FOUND_DUPP_KEY ||
 
1438
          error == HA_ERR_FOUND_DUPP_UNIQUE)))
 
1439
      return FALSE;
 
1440
    return TRUE;
 
1441
  }
 
1442
 
 
1443
  /**
 
1444
    Number of rows in table. It will only be called if
 
1445
    (table_flags() & (HA_HAS_RECORDS | HA_STATS_RECORDS_IS_EXACT)) != 0
 
1446
  */
 
1447
  virtual ha_rows records() { return stats.records; }
 
1448
  /**
 
1449
    Return upper bound of current number of records in the table
 
1450
    (max. of how many records one will retrieve when doing a full table scan)
 
1451
    If upper bound is not known, HA_POS_ERROR should be returned as a max
 
1452
    possible upper bound.
 
1453
  */
 
1454
  virtual ha_rows estimate_rows_upper_bound()
 
1455
  { return stats.records+EXTRA_RECORDS; }
 
1456
 
 
1457
  /**
 
1458
    Get the row type from the storage engine.  If this method returns
 
1459
    ROW_TYPE_NOT_USED, the information in HA_CREATE_INFO should be used.
 
1460
  */
 
1461
  virtual enum row_type get_row_type() const { return ROW_TYPE_NOT_USED; }
 
1462
 
 
1463
  virtual const char *index_type(uint key_number) { DBUG_ASSERT(0); return "";}
 
1464
 
 
1465
 
 
1466
  /**
 
1467
    Signal that the table->read_set and table->write_set table maps changed
 
1468
    The handler is allowed to set additional bits in the above map in this
 
1469
    call. Normally the handler should ignore all calls until we have done
 
1470
    a ha_rnd_init() or ha_index_init(), write_row(), update_row or delete_row()
 
1471
    as there may be several calls to this routine.
 
1472
  */
 
1473
  virtual void column_bitmaps_signal();
 
1474
  uint get_index(void) const { return active_index; }
 
1475
  virtual int close(void)=0;
 
1476
 
 
1477
  /**
 
1478
    @retval  0   Bulk update used by handler
 
1479
    @retval  1   Bulk update not used, normal operation used
 
1480
  */
 
1481
  virtual bool start_bulk_update() { return 1; }
 
1482
  /**
 
1483
    @retval  0   Bulk delete used by handler
 
1484
    @retval  1   Bulk delete not used, normal operation used
 
1485
  */
 
1486
  virtual bool start_bulk_delete() { return 1; }
 
1487
  /**
 
1488
    After this call all outstanding updates must be performed. The number
 
1489
    of duplicate key errors are reported in the duplicate key parameter.
 
1490
    It is allowed to continue to the batched update after this call, the
 
1491
    handler has to wait until end_bulk_update with changing state.
 
1492
 
 
1493
    @param    dup_key_found       Number of duplicate keys found
 
1494
 
 
1495
    @retval  0           Success
 
1496
    @retval  >0          Error code
 
1497
  */
 
1498
  virtual int exec_bulk_update(uint *dup_key_found)
 
1499
  {
 
1500
    DBUG_ASSERT(FALSE);
 
1501
    return HA_ERR_WRONG_COMMAND;
 
1502
  }
 
1503
  /**
 
1504
    Perform any needed clean-up, no outstanding updates are there at the
 
1505
    moment.
 
1506
  */
 
1507
  virtual void end_bulk_update() { return; }
 
1508
  /**
 
1509
    Execute all outstanding deletes and close down the bulk delete.
 
1510
 
 
1511
    @retval 0             Success
 
1512
    @retval >0            Error code
 
1513
  */
 
1514
  virtual int end_bulk_delete()
 
1515
  {
 
1516
    DBUG_ASSERT(FALSE);
 
1517
    return HA_ERR_WRONG_COMMAND;
 
1518
  }
 
1519
  /**
 
1520
     @brief
 
1521
     Positions an index cursor to the index specified in the handle. Fetches the
 
1522
     row if available. If the key value is null, begin at the first key of the
 
1523
     index.
 
1524
  */
 
1525
  virtual int index_read_map(uchar * buf, const uchar * key,
 
1526
                             key_part_map keypart_map,
 
1527
                             enum ha_rkey_function find_flag)
 
1528
  {
 
1529
    uint key_len= calculate_key_len(table, active_index, key, keypart_map);
 
1530
    return  index_read(buf, key, key_len, find_flag);
 
1531
  }
 
1532
  /**
 
1533
     @brief
 
1534
     Positions an index cursor to the index specified in the handle. Fetches the
 
1535
     row if available. If the key value is null, begin at the first key of the
 
1536
     index.
 
1537
  */
 
1538
  virtual int index_read_idx_map(uchar * buf, uint index, const uchar * key,
 
1539
                                 key_part_map keypart_map,
 
1540
                                 enum ha_rkey_function find_flag);
 
1541
  virtual int index_next(uchar * buf)
 
1542
   { return  HA_ERR_WRONG_COMMAND; }
 
1543
  virtual int index_prev(uchar * buf)
 
1544
   { return  HA_ERR_WRONG_COMMAND; }
 
1545
  virtual int index_first(uchar * buf)
 
1546
   { return  HA_ERR_WRONG_COMMAND; }
 
1547
  virtual int index_last(uchar * buf)
 
1548
   { return  HA_ERR_WRONG_COMMAND; }
 
1549
  virtual int index_next_same(uchar *buf, const uchar *key, uint keylen);
 
1550
  /**
 
1551
     @brief
 
1552
     The following functions works like index_read, but it find the last
 
1553
     row with the current key value or prefix.
 
1554
  */
 
1555
  virtual int index_read_last_map(uchar * buf, const uchar * key,
 
1556
                                  key_part_map keypart_map)
 
1557
  {
 
1558
    uint key_len= calculate_key_len(table, active_index, key, keypart_map);
 
1559
    return index_read_last(buf, key, key_len);
 
1560
  }
 
1561
  virtual int read_range_first(const key_range *start_key,
 
1562
                               const key_range *end_key,
 
1563
                               bool eq_range, bool sorted);
 
1564
  virtual int read_range_next();
 
1565
  int compare_key(key_range *range);
 
1566
  int compare_key2(key_range *range);
 
1567
  virtual int ft_init() { return HA_ERR_WRONG_COMMAND; }
 
1568
  void ft_end() { ft_handler=NULL; }
 
1569
  virtual FT_INFO *ft_init_ext(uint flags, uint inx,String *key)
 
1570
    { return NULL; }
 
1571
  virtual int ft_read(uchar *buf) { return HA_ERR_WRONG_COMMAND; }
 
1572
  virtual int rnd_next(uchar *buf)=0;
 
1573
  virtual int rnd_pos(uchar * buf, uchar *pos)=0;
 
1574
  /**
 
1575
    One has to use this method when to find
 
1576
    random position by record as the plain
 
1577
    position() call doesn't work for some
 
1578
    handlers for random position.
 
1579
  */
 
1580
  virtual int rnd_pos_by_record(uchar *record);
 
1581
  virtual int read_first_row(uchar *buf, uint primary_key);
 
1582
  /**
 
1583
    The following function is only needed for tables that may be temporary
 
1584
    tables during joins.
 
1585
  */
 
1586
  virtual int restart_rnd_next(uchar *buf, uchar *pos)
 
1587
    { return HA_ERR_WRONG_COMMAND; }
 
1588
  virtual int rnd_same(uchar *buf, uint inx)
 
1589
    { return HA_ERR_WRONG_COMMAND; }
 
1590
  virtual ha_rows records_in_range(uint inx, key_range *min_key, key_range *max_key)
 
1591
    { return (ha_rows) 10; }
 
1592
  virtual void position(const uchar *record)=0;
 
1593
  virtual int info(uint)=0; // see my_base.h for full description
 
1594
  virtual uint32 calculate_key_hash_value(Field **field_array)
 
1595
  { DBUG_ASSERT(0); return 0; }
 
1596
  virtual int extra(enum ha_extra_function operation)
 
1597
  { return 0; }
 
1598
  virtual int extra_opt(enum ha_extra_function operation, ulong cache_size)
 
1599
  { return extra(operation); }
 
1600
 
 
1601
  /**
 
1602
    In an UPDATE or DELETE, if the row under the cursor was locked by another
 
1603
    transaction, and the engine used an optimistic read of the last
 
1604
    committed row value under the cursor, then the engine returns 1 from this
 
1605
    function. MySQL must NOT try to update this optimistic value. If the
 
1606
    optimistic value does not match the WHERE condition, MySQL can decide to
 
1607
    skip over this row. Currently only works for InnoDB. This can be used to
 
1608
    avoid unnecessary lock waits.
 
1609
 
 
1610
    If this method returns nonzero, it will also signal the storage
 
1611
    engine that the next read will be a locking re-read of the row.
 
1612
  */
 
1613
  virtual bool was_semi_consistent_read() { return 0; }
 
1614
  /**
 
1615
    Tell the engine whether it should avoid unnecessary lock waits.
 
1616
    If yes, in an UPDATE or DELETE, if the row under the cursor was locked
 
1617
    by another transaction, the engine may try an optimistic read of
 
1618
    the last committed row value under the cursor.
 
1619
  */
 
1620
  virtual void try_semi_consistent_read(bool) {}
 
1621
  virtual void unlock_row() {}
 
1622
  virtual int start_stmt(THD *thd, thr_lock_type lock_type) {return 0;}
 
1623
  virtual void get_auto_increment(uint64_t offset, uint64_t increment,
 
1624
                                  uint64_t nb_desired_values,
 
1625
                                  uint64_t *first_value,
 
1626
                                  uint64_t *nb_reserved_values);
 
1627
  void set_next_insert_id(uint64_t id)
 
1628
  {
 
1629
    DBUG_PRINT("info",("auto_increment: next value %lu", (ulong)id));
 
1630
    next_insert_id= id;
 
1631
  }
 
1632
  void restore_auto_increment(uint64_t prev_insert_id)
 
1633
  {
 
1634
    /*
 
1635
      Insertion of a row failed, re-use the lastly generated auto_increment
 
1636
      id, for the next row. This is achieved by resetting next_insert_id to
 
1637
      what it was before the failed insertion (that old value is provided by
 
1638
      the caller). If that value was 0, it was the first row of the INSERT;
 
1639
      then if insert_id_for_cur_row contains 0 it means no id was generated
 
1640
      for this first row, so no id was generated since the INSERT started, so
 
1641
      we should set next_insert_id to 0; if insert_id_for_cur_row is not 0, it
 
1642
      is the generated id of the first and failed row, so we use it.
 
1643
    */
 
1644
    next_insert_id= (prev_insert_id > 0) ? prev_insert_id :
 
1645
      insert_id_for_cur_row;
 
1646
  }
 
1647
 
 
1648
  virtual void update_create_info(HA_CREATE_INFO *create_info) {}
 
1649
  int check_old_types();
 
1650
  virtual int assign_to_keycache(THD* thd, HA_CHECK_OPT* check_opt)
 
1651
  { return HA_ADMIN_NOT_IMPLEMENTED; }
 
1652
  virtual int preload_keys(THD* thd, HA_CHECK_OPT* check_opt)
 
1653
  { return HA_ADMIN_NOT_IMPLEMENTED; }
 
1654
  /* end of the list of admin commands */
 
1655
 
 
1656
  virtual int indexes_are_disabled(void) {return 0;}
 
1657
  virtual char *update_table_comment(const char * comment)
 
1658
  { return (char*) comment;}
 
1659
  virtual void append_create_info(String *packet) {}
 
1660
  /**
 
1661
      If index == MAX_KEY then a check for table is made and if index <
 
1662
      MAX_KEY then a check is made if the table has foreign keys and if
 
1663
      a foreign key uses this index (and thus the index cannot be dropped).
 
1664
 
 
1665
    @param  index            Index to check if foreign key uses it
 
1666
 
 
1667
    @retval   TRUE            Foreign key defined on table or index
 
1668
    @retval   FALSE           No foreign key defined
 
1669
  */
 
1670
  virtual bool is_fk_defined_on_table_or_index(uint index)
 
1671
  { return FALSE; }
 
1672
  virtual char* get_foreign_key_create_info()
 
1673
  { return(NULL);}  /* gets foreign key create string from InnoDB */
 
1674
  /* gets tablespace name from handler */
 
1675
  const char* get_tablespace_name();
 
1676
  /** used in ALTER TABLE; 1 if changing storage engine is allowed */
 
1677
  virtual bool can_switch_engines() { return 1; }
 
1678
  /** used in REPLACE; is > 0 if table is referred by a FOREIGN KEY */
 
1679
  virtual int get_foreign_key_list(THD *thd, List<FOREIGN_KEY_INFO> *f_key_list)
 
1680
  { return 0; }
 
1681
  virtual uint referenced_by_foreign_key() { return 0;}
 
1682
  virtual void init_table_handle_for_HANDLER()
 
1683
  { return; }       /* prepare InnoDB for HANDLER */
 
1684
  virtual void free_foreign_key_create_info(char* str) {}
 
1685
  /** The following can be called without an open handler */
 
1686
  virtual const char *table_type() const =0;
 
1687
  /**
 
1688
    If frm_error() is called then we will use this to find out what file
 
1689
    extentions exist for the storage engine. This is also used by the default
 
1690
    rename_table and delete_table method in handler.cc.
 
1691
 
 
1692
    For engines that have two file name extentions (separate meta/index file
 
1693
    and data file), the order of elements is relevant. First element of engine
 
1694
    file name extentions array should be meta/index file extention. Second
 
1695
    element - data file extention. This order is assumed by
 
1696
    prepare_for_repair() when REPAIR TABLE ... USE_FRM is issued.
 
1697
  */
 
1698
  virtual const char **bas_ext() const =0;
 
1699
 
 
1700
  virtual int get_default_no_partitions(HA_CREATE_INFO *info) { return 1;}
 
1701
  virtual bool get_no_parts(const char *name,
 
1702
                            uint *no_parts)
 
1703
  {
 
1704
    *no_parts= 0;
 
1705
    return 0;
 
1706
  }
 
1707
 
 
1708
  virtual ulong index_flags(uint idx, uint part, bool all_parts) const =0;
 
1709
 
 
1710
  virtual int add_index(TABLE *table_arg, KEY *key_info, uint num_of_keys)
 
1711
  { return (HA_ERR_WRONG_COMMAND); }
 
1712
  virtual int prepare_drop_index(TABLE *table_arg, uint *key_num,
 
1713
                                 uint num_of_keys)
 
1714
  { return (HA_ERR_WRONG_COMMAND); }
 
1715
  virtual int final_drop_index(TABLE *table_arg)
 
1716
  { return (HA_ERR_WRONG_COMMAND); }
 
1717
 
 
1718
  uint max_record_length() const
 
1719
  { return min(HA_MAX_REC_LENGTH, max_supported_record_length()); }
 
1720
  uint max_keys() const
 
1721
  { return min(MAX_KEY, max_supported_keys()); }
 
1722
  uint max_key_parts() const
 
1723
  { return min(MAX_REF_PARTS, max_supported_key_parts()); }
 
1724
  uint max_key_length() const
 
1725
  { return min(MAX_KEY_LENGTH, max_supported_key_length()); }
 
1726
  uint max_key_part_length() const
 
1727
  { return min(MAX_KEY_LENGTH, max_supported_key_part_length()); }
 
1728
 
 
1729
  virtual uint max_supported_record_length() const { return HA_MAX_REC_LENGTH; }
 
1730
  virtual uint max_supported_keys() const { return 0; }
 
1731
  virtual uint max_supported_key_parts() const { return MAX_REF_PARTS; }
 
1732
  virtual uint max_supported_key_length() const { return MAX_KEY_LENGTH; }
 
1733
  virtual uint max_supported_key_part_length() const { return 255; }
 
1734
  virtual uint min_record_length(uint options) const { return 1; }
 
1735
 
 
1736
  virtual bool low_byte_first() const { return 1; }
 
1737
  virtual uint checksum() const { return 0; }
 
1738
  virtual bool is_crashed() const  { return 0; }
 
1739
  virtual bool auto_repair() const { return 0; }
 
1740
 
 
1741
 
 
1742
#define CHF_CREATE_FLAG 0
 
1743
#define CHF_DELETE_FLAG 1
 
1744
#define CHF_RENAME_FLAG 2
 
1745
 
 
1746
 
 
1747
  /**
 
1748
    @note lock_count() can return > 1 if the table is MERGE or partitioned.
 
1749
  */
 
1750
  virtual uint lock_count(void) const { return 1; }
 
1751
  /**
 
1752
    Is not invoked for non-transactional temporary tables.
 
1753
 
 
1754
    @note store_lock() can return more than one lock if the table is MERGE
 
1755
    or partitioned.
 
1756
 
 
1757
    @note that one can NOT rely on table->in_use in store_lock().  It may
 
1758
    refer to a different thread if called from mysql_lock_abort_for_thread().
 
1759
 
 
1760
    @note If the table is MERGE, store_lock() can return less locks
 
1761
    than lock_count() claimed. This can happen when the MERGE children
 
1762
    are not attached when this is called from another thread.
 
1763
  */
 
1764
  virtual THR_LOCK_DATA **store_lock(THD *thd,
 
1765
                                     THR_LOCK_DATA **to,
 
1766
                                     enum thr_lock_type lock_type)=0;
 
1767
 
 
1768
  /** Type of table for caching query */
 
1769
  virtual uint8 table_cache_type() { return HA_CACHE_TBL_NONTRANSACT; }
 
1770
 
 
1771
 
 
1772
  /**
 
1773
    @brief Register a named table with a call back function to the query cache.
 
1774
 
 
1775
    @param thd The thread handle
 
1776
    @param table_key A pointer to the table name in the table cache
 
1777
    @param key_length The length of the table name
 
1778
    @param[out] engine_callback The pointer to the storage engine call back
 
1779
      function
 
1780
    @param[out] engine_data Storage engine specific data which could be
 
1781
      anything
 
1782
 
 
1783
    This method offers the storage engine, the possibility to store a reference
 
1784
    to a table name which is going to be used with query cache. 
 
1785
    The method is called each time a statement is written to the cache and can
 
1786
    be used to verify if a specific statement is cachable. It also offers
 
1787
    the possibility to register a generic (but static) call back function which
 
1788
    is called each time a statement is matched against the query cache.
 
1789
 
 
1790
    @note If engine_data supplied with this function is different from
 
1791
      engine_data supplied with the callback function, and the callback returns
 
1792
      FALSE, a table invalidation on the current table will occur.
 
1793
 
 
1794
    @return Upon success the engine_callback will point to the storage engine
 
1795
      call back function, if any, and engine_data will point to any storage
 
1796
      engine data used in the specific implementation.
 
1797
      @retval TRUE Success
 
1798
      @retval FALSE The specified table or current statement should not be
 
1799
        cached
 
1800
  */
 
1801
 
 
1802
  virtual my_bool register_query_cache_table(THD *thd, char *table_key,
 
1803
                                             uint key_length,
 
1804
                                             qc_engine_callback
 
1805
                                             *engine_callback,
 
1806
                                             uint64_t *engine_data)
 
1807
  {
 
1808
    *engine_callback= 0;
 
1809
    return TRUE;
 
1810
  }
 
1811
 
 
1812
 
 
1813
 /*
 
1814
   @retval TRUE   Primary key (if there is one) is clustered
 
1815
                  key covering all fields
 
1816
   @retval FALSE  otherwise
 
1817
 */
 
1818
 virtual bool primary_key_is_clustered() { return FALSE; }
 
1819
 virtual int cmp_ref(const uchar *ref1, const uchar *ref2)
 
1820
 {
 
1821
   return memcmp(ref1, ref2, ref_length);
 
1822
 }
 
1823
 
 
1824
 /*
 
1825
   Condition pushdown to storage engines
 
1826
 */
 
1827
 
 
1828
 /**
 
1829
   Push condition down to the table handler.
 
1830
 
 
1831
   @param  cond   Condition to be pushed. The condition tree must not be
 
1832
                  modified by the by the caller.
 
1833
 
 
1834
   @return
 
1835
     The 'remainder' condition that caller must use to filter out records.
 
1836
     NULL means the handler will not return rows that do not match the
 
1837
     passed condition.
 
1838
 
 
1839
   @note
 
1840
   The pushed conditions form a stack (from which one can remove the
 
1841
   last pushed condition using cond_pop).
 
1842
   The table handler filters out rows using (pushed_cond1 AND pushed_cond2 
 
1843
   AND ... AND pushed_condN)
 
1844
   or less restrictive condition, depending on handler's capabilities.
 
1845
 
 
1846
   handler->ha_reset() call empties the condition stack.
 
1847
   Calls to rnd_init/rnd_end, index_init/index_end etc do not affect the
 
1848
   condition stack.
 
1849
 */ 
 
1850
 virtual const COND *cond_push(const COND *cond) { return cond; }
 
1851
 
 
1852
 /**
 
1853
   Pop the top condition from the condition stack of the handler instance.
 
1854
 
 
1855
   Pops the top if condition stack, if stack is not empty.
 
1856
 */
 
1857
 virtual void cond_pop() { return; }
 
1858
 
 
1859
 virtual Item *idx_cond_push(uint keyno, Item* idx_cond) { return idx_cond; }
 
1860
 
 
1861
 /*
 
1862
    Part of old fast alter table, to be depricated
 
1863
  */
 
1864
 virtual bool check_if_incompatible_data(HA_CREATE_INFO *create_info,
 
1865
                                         uint table_changes)
 
1866
 { return COMPATIBLE_DATA_NO; }
 
1867
 
 
1868
 /* On-line ALTER TABLE interface */
 
1869
 
 
1870
 /**
 
1871
    Check if a storage engine supports a particular alter table on-line
 
1872
 
 
1873
    @param    altered_table     A temporary table show what table is to
 
1874
                                change to
 
1875
    @param    create_info       Information from the parsing phase about new
 
1876
                                table properties.
 
1877
    @param    alter_flags       Bitmask that shows what will be changed
 
1878
    @param    table_changes     Shows if table layout has changed (for
 
1879
                                backwards compatibility with
 
1880
                                check_if_incompatible_data
 
1881
 
 
1882
    @retval   HA_ALTER_ERROR                Unexpected error
 
1883
    @retval   HA_ALTER_SUPPORTED_WAIT_LOCK  Supported, but requires DDL lock
 
1884
    @retval   HA_ALTER_SUPPORTED_NO_LOCK    Supported
 
1885
    @retval   HA_ALTER_NOT_SUPPORTED        Not supported
 
1886
 
 
1887
    @note
 
1888
      The default implementation is implemented to support fast
 
1889
      alter table (storage engines that support some changes by
 
1890
      just changing the frm file) without any change in the handler
 
1891
      implementation.    
 
1892
 */
 
1893
 virtual int check_if_supported_alter(TABLE *altered_table,
 
1894
                                      HA_CREATE_INFO *create_info,
 
1895
                                      HA_ALTER_FLAGS *alter_flags,
 
1896
                                      uint table_changes)
 
1897
 {
 
1898
   DBUG_ENTER("check_if_supported_alter");
 
1899
   if (this->check_if_incompatible_data(create_info, table_changes)
 
1900
       == COMPATIBLE_DATA_NO)
 
1901
     DBUG_RETURN(HA_ALTER_NOT_SUPPORTED);
 
1902
   else
 
1903
     DBUG_RETURN(HA_ALTER_SUPPORTED_WAIT_LOCK);
 
1904
 }
 
1905
 /**
 
1906
   Tell storage engine to prepare for the on-line alter table (pre-alter)
 
1907
 
 
1908
   @param     thd               The thread handle
 
1909
   @param     altered_table     A temporary table show what table is to
 
1910
                                change to
 
1911
   @param     alter_info        Storage place for data used during phase1
 
1912
                                and phase2
 
1913
   @param     alter_flags       Bitmask that shows what will be changed
 
1914
 
 
1915
   @retval   0      OK
 
1916
   @retval   error  error code passed from storage engine
 
1917
 */
 
1918
 virtual int alter_table_phase1(THD *thd,
 
1919
                                TABLE *altered_table,
 
1920
                                HA_CREATE_INFO *create_info,
 
1921
                                HA_ALTER_INFO *alter_info,
 
1922
                                HA_ALTER_FLAGS *alter_flags)
 
1923
 {
 
1924
   return HA_ERR_UNSUPPORTED;
 
1925
 }
 
1926
 /**
 
1927
    Tell storage engine to perform the on-line alter table (alter)
 
1928
 
 
1929
    @param    thd               The thread handle
 
1930
    @param    altered_table     A temporary table show what table is to
 
1931
                                change to
 
1932
    @param    alter_info        Storage place for data used during phase1
 
1933
                                and phase2
 
1934
    @param    alter_flags       Bitmask that shows what will be changed
 
1935
 
 
1936
    @retval  0      OK
 
1937
    @retval  error  error code passed from storage engine
 
1938
 
 
1939
    @note
 
1940
      If check_if_supported_alter returns HA_ALTER_SUPPORTED_WAIT_LOCK
 
1941
      this call is to be wrapped with a DDL lock. This is currently NOT
 
1942
      supported.
 
1943
 */
 
1944
 virtual int alter_table_phase2(THD *thd,
 
1945
                                TABLE *altered_table,
 
1946
                                HA_CREATE_INFO *create_info,
 
1947
                                HA_ALTER_INFO *alter_info,
 
1948
                                HA_ALTER_FLAGS *alter_flags)
 
1949
 {
 
1950
   return HA_ERR_UNSUPPORTED;
 
1951
 }
 
1952
 /**
 
1953
    Tell storage engine that changed frm file is now on disk and table
 
1954
    has been re-opened (post-alter)
 
1955
 
 
1956
    @param    thd               The thread handle
 
1957
    @param    table             The altered table, re-opened
 
1958
 */
 
1959
 virtual int alter_table_phase3(THD *thd, TABLE *table)
 
1960
 {
 
1961
   return HA_ERR_UNSUPPORTED;
 
1962
 }
 
1963
 
 
1964
  /**
 
1965
    use_hidden_primary_key() is called in case of an update/delete when
 
1966
    (table_flags() and HA_PRIMARY_KEY_REQUIRED_FOR_DELETE) is defined
 
1967
    but we don't have a primary key
 
1968
  */
 
1969
  virtual void use_hidden_primary_key();
 
1970
 
 
1971
  /**
 
1972
    Lock table.
 
1973
 
 
1974
    @param    thd                     Thread handle
 
1975
    @param    lock_type               HA_LOCK_IN_SHARE_MODE     (F_RDLCK)
 
1976
                                      HA_LOCK_IN_EXCLUSIVE_MODE (F_WRLCK)
 
1977
    @param    lock_timeout            -1 default timeout
 
1978
                                      0  no wait
 
1979
                                      >0 wait timeout in milliseconds.
 
1980
 
 
1981
   @note
 
1982
      lock_timeout >0 is not used by MySQL currently. If the storage
 
1983
      engine does not support NOWAIT (lock_timeout == 0) it should
 
1984
      return an error. But if it does not support WAIT X (lock_timeout
 
1985
      >0) it should treat it as lock_timeout == -1 and wait a default
 
1986
      (or even hard-coded) timeout.
 
1987
 
 
1988
    @retval HA_ERR_WRONG_COMMAND      Storage engine does not support
 
1989
                                      lock_table()
 
1990
    @retval HA_ERR_UNSUPPORTED        Storage engine does not support NOWAIT
 
1991
    @retval HA_ERR_LOCK_WAIT_TIMEOUT  Lock request timed out or
 
1992
                                      lock conflict with NOWAIT option
 
1993
    @retval HA_ERR_LOCK_DEADLOCK      Deadlock detected
 
1994
  */
 
1995
  virtual int lock_table(THD *thd         __attribute__((unused)),
 
1996
                         int lock_type    __attribute__((unused)),
 
1997
                         int lock_timeout __attribute__((unused)))
 
1998
  {
 
1999
    return HA_ERR_WRONG_COMMAND;
 
2000
  }
 
2001
 
 
2002
protected:
 
2003
  /* Service methods for use by storage engines. */
 
2004
  void ha_statistic_increment(ulong SSV::*offset) const;
 
2005
  void **ha_data(THD *) const;
 
2006
  THD *ha_thd(void) const;
 
2007
 
 
2008
  /**
 
2009
    Default rename_table() and delete_table() rename/delete files with a
 
2010
    given name and extensions from bas_ext().
 
2011
 
 
2012
    These methods can be overridden, but their default implementation
 
2013
    provide useful functionality.
 
2014
  */
 
2015
  virtual int rename_table(const char *from, const char *to);
 
2016
  /**
 
2017
    Delete a table in the engine. Called for base as well as temporary
 
2018
    tables.
 
2019
  */
 
2020
  virtual int delete_table(const char *name);
 
2021
 
 
2022
private:
 
2023
  /* Private helpers */
 
2024
  inline void mark_trx_read_write();
 
2025
private:
 
2026
  /*
 
2027
    Low-level primitives for storage engines.  These should be
 
2028
    overridden by the storage engine class. To call these methods, use
 
2029
    the corresponding 'ha_*' method above.
 
2030
  */
 
2031
 
 
2032
  virtual int open(const char *name, int mode, uint test_if_locked)=0;
 
2033
  virtual int index_init(uint idx, bool sorted) { active_index= idx; return 0; }
 
2034
  virtual int index_end() { active_index= MAX_KEY; return 0; }
 
2035
  /**
 
2036
    rnd_init() can be called two times without rnd_end() in between
 
2037
    (it only makes sense if scan=1).
 
2038
    then the second call should prepare for the new table scan (e.g
 
2039
    if rnd_init allocates the cursor, second call should position it
 
2040
    to the start of the table, no need to deallocate and allocate it again
 
2041
  */
 
2042
  virtual int rnd_init(bool scan)= 0;
 
2043
  virtual int rnd_end() { return 0; }
 
2044
  virtual int write_row(uchar *buf __attribute__((unused)))
 
2045
  {
 
2046
    return HA_ERR_WRONG_COMMAND;
 
2047
  }
 
2048
 
 
2049
  virtual int update_row(const uchar *old_data __attribute__((unused)),
 
2050
                         uchar *new_data __attribute__((unused)))
 
2051
  {
 
2052
    return HA_ERR_WRONG_COMMAND;
 
2053
  }
 
2054
 
 
2055
  virtual int delete_row(const uchar *buf __attribute__((unused)))
 
2056
  {
 
2057
    return HA_ERR_WRONG_COMMAND;
 
2058
  }
 
2059
  /**
 
2060
    Reset state of file to after 'open'.
 
2061
    This function is called after every statement for all tables used
 
2062
    by that statement.
 
2063
  */
 
2064
  virtual int reset() { return 0; }
 
2065
  virtual Table_flags table_flags(void) const= 0;
 
2066
 
 
2067
  /**
 
2068
    Is not invoked for non-transactional temporary tables.
 
2069
 
 
2070
    Tells the storage engine that we intend to read or write data
 
2071
    from the table. This call is prefixed with a call to handler::store_lock()
 
2072
    and is invoked only for those handler instances that stored the lock.
 
2073
 
 
2074
    Calls to rnd_init/index_init are prefixed with this call. When table
 
2075
    IO is complete, we call external_lock(F_UNLCK).
 
2076
    A storage engine writer should expect that each call to
 
2077
    ::external_lock(F_[RD|WR]LOCK is followed by a call to
 
2078
    ::external_lock(F_UNLCK). If it is not, it is a bug in MySQL.
 
2079
 
 
2080
    The name and signature originate from the first implementation
 
2081
    in MyISAM, which would call fcntl to set/clear an advisory
 
2082
    lock on the data file in this method.
 
2083
 
 
2084
    @param   lock_type    F_RDLCK, F_WRLCK, F_UNLCK
 
2085
 
 
2086
    @return  non-0 in case of failure, 0 in case of success.
 
2087
    When lock_type is F_UNLCK, the return value is ignored.
 
2088
  */
 
2089
  virtual int external_lock(THD *thd __attribute__((unused)),
 
2090
                            int lock_type __attribute__((unused)))
 
2091
  {
 
2092
    return 0;
 
2093
  }
 
2094
  virtual void release_auto_increment() { return; };
 
2095
  /** admin commands - called from mysql_admin_table */
 
2096
  virtual int check_for_upgrade(HA_CHECK_OPT *check_opt)
 
2097
  { return 0; }
 
2098
  virtual int check(THD* thd, HA_CHECK_OPT* check_opt)
 
2099
  { return HA_ADMIN_NOT_IMPLEMENTED; }
 
2100
 
 
2101
  /**
 
2102
     In this method check_opt can be modified
 
2103
     to specify CHECK option to use to call check()
 
2104
     upon the table.
 
2105
  */
 
2106
  virtual int repair(THD* thd, HA_CHECK_OPT* check_opt)
 
2107
  { return HA_ADMIN_NOT_IMPLEMENTED; }
 
2108
  virtual void start_bulk_insert(ha_rows rows) {}
 
2109
  virtual int end_bulk_insert() { return 0; }
 
2110
  virtual int index_read(uchar * buf, const uchar * key, uint key_len,
 
2111
                         enum ha_rkey_function find_flag)
 
2112
   { return  HA_ERR_WRONG_COMMAND; }
 
2113
  virtual int index_read_last(uchar * buf, const uchar * key, uint key_len)
 
2114
   { return (my_errno= HA_ERR_WRONG_COMMAND); }
 
2115
  /**
 
2116
    This method is similar to update_row, however the handler doesn't need
 
2117
    to execute the updates at this point in time. The handler can be certain
 
2118
    that another call to bulk_update_row will occur OR a call to
 
2119
    exec_bulk_update before the set of updates in this query is concluded.
 
2120
 
 
2121
    @param    old_data       Old record
 
2122
    @param    new_data       New record
 
2123
    @param    dup_key_found  Number of duplicate keys found
 
2124
 
 
2125
    @retval  0   Bulk delete used by handler
 
2126
    @retval  1   Bulk delete not used, normal operation used
 
2127
  */
 
2128
  virtual int bulk_update_row(const uchar *old_data, uchar *new_data,
 
2129
                              uint *dup_key_found)
 
2130
  {
 
2131
    DBUG_ASSERT(FALSE);
 
2132
    return HA_ERR_WRONG_COMMAND;
 
2133
  }
 
2134
  /**
 
2135
    This is called to delete all rows in a table
 
2136
    If the handler don't support this, then this function will
 
2137
    return HA_ERR_WRONG_COMMAND and MySQL will delete the rows one
 
2138
    by one.
 
2139
  */
 
2140
  virtual int delete_all_rows()
 
2141
  { return (my_errno=HA_ERR_WRONG_COMMAND); }
 
2142
  /**
 
2143
    Reset the auto-increment counter to the given value, i.e. the next row
 
2144
    inserted will get the given value. This is called e.g. after TRUNCATE
 
2145
    is emulated by doing a 'DELETE FROM t'. HA_ERR_WRONG_COMMAND is
 
2146
    returned by storage engines that don't support this operation.
 
2147
  */
 
2148
  virtual int reset_auto_increment(uint64_t value)
 
2149
  { return HA_ERR_WRONG_COMMAND; }
 
2150
  virtual int optimize(THD* thd, HA_CHECK_OPT* check_opt)
 
2151
  { return HA_ADMIN_NOT_IMPLEMENTED; }
 
2152
  virtual int analyze(THD* thd, HA_CHECK_OPT* check_opt)
 
2153
  { return HA_ADMIN_NOT_IMPLEMENTED; }
 
2154
  virtual bool check_and_repair(THD *thd) { return TRUE; }
 
2155
  virtual int disable_indexes(uint mode) { return HA_ERR_WRONG_COMMAND; }
 
2156
  virtual int enable_indexes(uint mode) { return HA_ERR_WRONG_COMMAND; }
 
2157
  virtual int discard_or_import_tablespace(my_bool discard)
 
2158
  { return (my_errno=HA_ERR_WRONG_COMMAND); }
 
2159
  virtual void prepare_for_alter() { return; }
 
2160
  virtual void drop_table(const char *name);
 
2161
  virtual int create(const char *name, TABLE *form, HA_CREATE_INFO *info)=0;
 
2162
 
 
2163
  virtual int create_handler_files(const char *name, const char *old_name,
 
2164
                                   int action_flag, HA_CREATE_INFO *info)
 
2165
  { return FALSE; }
 
2166
};
 
2167
 
 
2168
 
 
2169
 
 
2170
/**
 
2171
  A Disk-Sweep MRR interface implementation
 
2172
 
 
2173
  This implementation makes range (and, in the future, 'ref') scans to read
 
2174
  table rows in disk sweeps. 
 
2175
  
 
2176
  Currently it is used by MyISAM and InnoDB. Potentially it can be used with
 
2177
  any table handler that has non-clustered indexes and on-disk rows.
 
2178
*/
 
2179
 
 
2180
class DsMrr_impl
 
2181
{
 
2182
public:
 
2183
  typedef void (handler::*range_check_toggle_func_t)(bool on);
 
2184
 
 
2185
  DsMrr_impl()
 
2186
    : h2(NULL) {};
 
2187
 
 
2188
  handler *h; /* The "owner" handler object. It is used for scanning the index */
 
2189
  TABLE *table; /* Always equal to h->table */
 
2190
private:
 
2191
  /*
 
2192
    Secondary handler object. It is used to retrieve full table rows by
 
2193
    calling rnd_pos().
 
2194
  */
 
2195
  handler *h2;
 
2196
 
 
2197
  /* Buffer to store rowids, or (rowid, range_id) pairs */
 
2198
  uchar *rowids_buf;
 
2199
  uchar *rowids_buf_cur;   /* Current position when reading/writing */
 
2200
  uchar *rowids_buf_last;  /* When reading: end of used buffer space */
 
2201
  uchar *rowids_buf_end;   /* End of the buffer */
 
2202
 
 
2203
  bool dsmrr_eof; /* TRUE <=> We have reached EOF when reading index tuples */
 
2204
 
 
2205
  /* TRUE <=> need range association, buffer holds {rowid, range_id} pairs */
 
2206
  bool is_mrr_assoc;
 
2207
 
 
2208
  bool use_default_impl; /* TRUE <=> shortcut all calls to default MRR impl */
 
2209
public:
 
2210
  void init(handler *h_arg, TABLE *table_arg)
 
2211
  {
 
2212
    h= h_arg; 
 
2213
    table= table_arg;
 
2214
  }
 
2215
  int dsmrr_init(handler *h, KEY *key, RANGE_SEQ_IF *seq_funcs, 
 
2216
                 void *seq_init_param, uint n_ranges, uint mode, 
 
2217
                 HANDLER_BUFFER *buf);
 
2218
  void dsmrr_close();
 
2219
  int dsmrr_fill_buffer(handler *h);
 
2220
  int dsmrr_next(handler *h, char **range_info);
 
2221
 
 
2222
  int dsmrr_info(uint keyno, uint n_ranges, uint keys, uint *bufsz,
 
2223
                 uint *flags, COST_VECT *cost);
 
2224
 
 
2225
  ha_rows dsmrr_info_const(uint keyno, RANGE_SEQ_IF *seq, 
 
2226
                            void *seq_init_param, uint n_ranges, uint *bufsz,
 
2227
                            uint *flags, COST_VECT *cost);
 
2228
private:
 
2229
  bool key_uses_partial_cols(uint keyno);
 
2230
  bool choose_mrr_impl(uint keyno, ha_rows rows, uint *flags, uint *bufsz, 
 
2231
                       COST_VECT *cost);
 
2232
  bool get_disk_sweep_mrr_cost(uint keynr, ha_rows rows, uint flags, 
 
2233
                               uint *buffer_size, COST_VECT *cost);
 
2234
};
 
2235
 
 
2236
extern const char *ha_row_type[];
 
2237
extern const char *tx_isolation_names[];
 
2238
extern const char *binlog_format_names[];
 
2239
extern TYPELIB tx_isolation_typelib;
 
2240
extern TYPELIB myisam_stats_method_typelib;
 
2241
extern ulong total_ha, total_ha_2pc;
 
2242
 
 
2243
       /* Wrapper functions */
 
2244
#define ha_commit(thd) (ha_commit_trans((thd), TRUE))
 
2245
#define ha_rollback(thd) (ha_rollback_trans((thd), TRUE))
 
2246
 
 
2247
/* lookups */
 
2248
handlerton *ha_default_handlerton(THD *thd);
 
2249
plugin_ref ha_resolve_by_name(THD *thd, const LEX_STRING *name);
 
2250
plugin_ref ha_lock_engine(THD *thd, handlerton *hton);
 
2251
handlerton *ha_resolve_by_legacy_type(THD *thd, enum legacy_db_type db_type);
 
2252
handler *get_new_handler(TABLE_SHARE *share, MEM_ROOT *alloc,
 
2253
                         handlerton *db_type);
 
2254
handlerton *ha_checktype(THD *thd, enum legacy_db_type database_type,
 
2255
                          bool no_substitute, bool report_error);
 
2256
 
 
2257
 
 
2258
static inline enum legacy_db_type ha_legacy_type(const handlerton *db_type)
 
2259
{
 
2260
  return (db_type == NULL) ? DB_TYPE_UNKNOWN : db_type->db_type;
 
2261
}
 
2262
 
 
2263
static inline const char *ha_resolve_storage_engine_name(const handlerton *db_type)
 
2264
{
 
2265
  return db_type == NULL ? "UNKNOWN" : hton2plugin[db_type->slot]->name.str;
 
2266
}
 
2267
 
 
2268
static inline bool ha_check_storage_engine_flag(const handlerton *db_type, uint32 flag)
 
2269
{
 
2270
  return db_type == NULL ? FALSE : test(db_type->flags & flag);
 
2271
}
 
2272
 
 
2273
static inline bool ha_storage_engine_is_enabled(const handlerton *db_type)
 
2274
{
 
2275
  return (db_type && db_type->create) ?
 
2276
         (db_type->state == SHOW_OPTION_YES) : FALSE;
 
2277
}
 
2278
 
 
2279
/* basic stuff */
 
2280
int ha_init_errors(void);
 
2281
int ha_init(void);
 
2282
int ha_end(void);
 
2283
int ha_initialize_handlerton(st_plugin_int *plugin);
 
2284
int ha_finalize_handlerton(st_plugin_int *plugin);
 
2285
 
 
2286
TYPELIB *ha_known_exts(void);
 
2287
int ha_panic(enum ha_panic_function flag);
 
2288
void ha_close_connection(THD* thd);
 
2289
bool ha_flush_logs(handlerton *db_type);
 
2290
void ha_drop_database(char* path);
 
2291
int ha_create_table(THD *thd, const char *path,
 
2292
                    const char *db, const char *table_name,
 
2293
                    HA_CREATE_INFO *create_info,
 
2294
                    bool update_create_info);
 
2295
int ha_delete_table(THD *thd, handlerton *db_type, const char *path,
 
2296
                    const char *db, const char *alias, bool generate_warning);
 
2297
 
 
2298
/* statistics and info */
 
2299
bool ha_show_status(THD *thd, handlerton *db_type, enum ha_stat_type stat);
 
2300
 
 
2301
/* discovery */
 
2302
int ha_create_table_from_engine(THD* thd, const char *db, const char *name);
 
2303
int ha_discover(THD* thd, const char* dbname, const char* name,
 
2304
                uchar** frmblob, size_t* frmlen);
 
2305
int ha_find_files(THD *thd,const char *db,const char *path,
 
2306
                  const char *wild, bool dir, List<LEX_STRING>* files);
 
2307
int ha_table_exists_in_engine(THD* thd, const char* db, const char* name);
 
2308
 
 
2309
/* key cache */
 
2310
extern "C" int ha_init_key_cache(const char *name, KEY_CACHE *key_cache);
 
2311
int ha_resize_key_cache(KEY_CACHE *key_cache);
 
2312
int ha_change_key_cache_param(KEY_CACHE *key_cache);
 
2313
int ha_change_key_cache(KEY_CACHE *old_key_cache, KEY_CACHE *new_key_cache);
 
2314
int ha_end_key_cache(KEY_CACHE *key_cache);
 
2315
 
 
2316
/* report to InnoDB that control passes to the client */
 
2317
int ha_release_temporary_latches(THD *thd);
 
2318
 
 
2319
/* transactions: interface to handlerton functions */
 
2320
int ha_start_consistent_snapshot(THD *thd);
 
2321
int ha_commit_or_rollback_by_xid(XID *xid, bool commit);
 
2322
int ha_commit_one_phase(THD *thd, bool all);
 
2323
int ha_rollback_trans(THD *thd, bool all);
 
2324
int ha_prepare(THD *thd);
 
2325
int ha_recover(HASH *commit_list);
 
2326
 
 
2327
/* transactions: these functions never call handlerton functions directly */
 
2328
int ha_commit_trans(THD *thd, bool all);
 
2329
int ha_autocommit_or_rollback(THD *thd, int error);
 
2330
int ha_enable_transaction(THD *thd, bool on);
 
2331
 
 
2332
/* savepoints */
 
2333
int ha_rollback_to_savepoint(THD *thd, SAVEPOINT *sv);
 
2334
int ha_savepoint(THD *thd, SAVEPOINT *sv);
 
2335
int ha_release_savepoint(THD *thd, SAVEPOINT *sv);
 
2336
 
 
2337
/* these are called by storage engines */
 
2338
void trans_register_ha(THD *thd, bool all, handlerton *ht);
 
2339
 
 
2340
/*
 
2341
  Storage engine has to assume the transaction will end up with 2pc if
 
2342
   - there is more than one 2pc-capable storage engine available
 
2343
   - in the current transaction 2pc was not disabled yet
 
2344
*/
 
2345
#define trans_need_2pc(thd, all)                   ((total_ha_2pc > 1) && \
 
2346
        !((all ? &thd->transaction.all : &thd->transaction.stmt)->no_2pc))
 
2347
 
 
2348
#ifdef HAVE_NDB_BINLOG
 
2349
int ha_reset_logs(THD *thd);
 
2350
int ha_binlog_index_purge_file(THD *thd, const char *file);
 
2351
void ha_reset_slave(THD *thd);
 
2352
void ha_binlog_log_query(THD *thd, handlerton *db_type,
 
2353
                         enum_binlog_command binlog_command,
 
2354
                         const char *query, uint query_length,
 
2355
                         const char *db, const char *table_name);
 
2356
void ha_binlog_wait(THD *thd);
 
2357
int ha_binlog_end(THD *thd);
 
2358
#else
 
2359
#define ha_reset_logs(a) do {} while (0)
 
2360
#define ha_binlog_index_purge_file(a,b) do {} while (0)
 
2361
#define ha_reset_slave(a) do {} while (0)
 
2362
#define ha_binlog_log_query(a,b,c,d,e,f,g) do {} while (0)
 
2363
#define ha_binlog_wait(a) do {} while (0)
 
2364
#define ha_binlog_end(a)  do {} while (0)
 
2365
#endif