handler.h 21.3 KB
Newer Older
1
/* Copyright (C) 2000,2004 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
2

bk@work.mysql.com's avatar
bk@work.mysql.com committed
3 4 5 6
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.
7

bk@work.mysql.com's avatar
bk@work.mysql.com committed
8 9 10 11
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
12

bk@work.mysql.com's avatar
bk@work.mysql.com committed
13 14 15 16 17 18 19 20 21 22 23
   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */


/* Definitions for parameters to do with handler-routines */

#ifdef __GNUC__
#pragma interface			/* gcc class implementation */
#endif

24
#include <ft_global.h>
25
#include <keycache.h>
26

bk@work.mysql.com's avatar
bk@work.mysql.com committed
27 28 29 30
#ifndef NO_HASH
#define NO_HASH				/* Not yet implemented */
#endif

31 32
#if defined(HAVE_BERKELEY_DB) || defined(HAVE_INNOBASE_DB) || \
    defined(HAVE_NDBCLUSTER_DB)
33 34 35
#define USING_TRANSACTIONS
#endif

bk@work.mysql.com's avatar
bk@work.mysql.com committed
36 37
// the following is for checking tables

38 39 40 41 42 43
#define HA_ADMIN_ALREADY_DONE	  1
#define HA_ADMIN_OK               0
#define HA_ADMIN_NOT_IMPLEMENTED -1
#define HA_ADMIN_FAILED		 -2
#define HA_ADMIN_CORRUPT         -3
#define HA_ADMIN_INTERNAL_ERROR  -4
44
#define HA_ADMIN_INVALID         -5
vva@eagle.mysql.r18.ru's avatar
vva@eagle.mysql.r18.ru committed
45
#define HA_ADMIN_REJECT          -6
46
#define HA_ADMIN_TRY_ALTER       -7
bk@work.mysql.com's avatar
bk@work.mysql.com committed
47

48
/* Bits in table_flags() to show what database can do */
49 50 51 52 53
#define HA_READ_RND_SAME       (1 << 0) /* can switch index during the scan
                                           with ::rnd_same() - not used yet.
                                           see mi_rsame/heap_rsame/myrg_rsame */
#define HA_TABLE_SCAN_ON_INDEX (1 << 2) /* No separate data/index file */
#define HA_REC_NOT_IN_SEQ      (1 << 3) /* ha_info don't return recnumber;
serg@serg.mylan's avatar
serg@serg.mylan committed
54
                                           It returns a position to ha_r_rnd */
55
#define HA_CAN_GEOMETRY        (1 << 4)
56
#define HA_FAST_KEY_READ       (1 << 5) /* no need for a record cache in filesort */
57 58
#define HA_NULL_IN_KEY         (1 << 7) /* One can have keys with NULL */
#define HA_DUPP_POS            (1 << 8) /* ha_position() gives dup row */
serg@serg.mylan's avatar
serg@serg.mylan committed
59
#define HA_NO_BLOBS            (1 << 9) /* Doesn't support blobs */
60 61 62
#define HA_CAN_INDEX_BLOBS     (1 << 10)
#define HA_AUTO_PART_KEY       (1 << 11) /* auto-increment in multi-part key */
#define HA_REQUIRE_PRIMARY_KEY (1 << 12) /* .. and can't create a hidden one */
serg@serg.mylan's avatar
serg@serg.mylan committed
63
#define HA_NOT_EXACT_COUNT     (1 << 13)
64 65 66
#define HA_CAN_INSERT_DELAYED  (1 << 14) /* only handlers with table-level locks
                                            need no special code to support
                                            INSERT DELAYED */
serg@serg.mylan's avatar
serg@serg.mylan committed
67 68 69 70 71 72 73
#define HA_PRIMARY_KEY_IN_READ_INDEX (1 << 15)
#define HA_NOT_DELETE_WITH_CACHE (1 << 18)
#define HA_NO_PREFIX_CHAR_KEYS (1 << 20)
#define HA_CAN_FULLTEXT        (1 << 21)
#define HA_CAN_SQL_HANDLER     (1 << 22)
#define HA_NO_AUTO_INCREMENT   (1 << 23)
#define HA_HAS_CHECKSUM        (1 << 24)
74
/* Table data are stored in separate files (for lower_case_table_names) */
monty@mysql.com's avatar
monty@mysql.com committed
75 76
#define HA_FILE_BASED	       (1 << 26)

77

78
/* bits in index_flags(index_number) for what you can do with index */
79 80 81 82
#define HA_READ_NEXT            1       /* TODO really use this flag */
#define HA_READ_PREV            2       /* supports ::index_prev */
#define HA_READ_ORDER           4       /* index_next/prev follow sort order */
#define HA_READ_RANGE           8       /* can find all records in a range */
83
#define HA_ONLY_WHOLE_INDEX	16	/* Can't use part key searches */
84
#define HA_KEYREAD_ONLY         64	/* Support HA_EXTRA_KEYREAD */
85

86 87 88 89 90 91 92
/* operations for disable/enable indexes */
#define HA_KEY_SWITCH_NONUNIQ      0
#define HA_KEY_SWITCH_ALL          1
#define HA_KEY_SWITCH_NONUNIQ_SAVE 2
#define HA_KEY_SWITCH_ALL_SAVE     3


93
/*
94 95 96 97
  Bits in index_ddl_flags(KEY *wanted_index)
  for what ddl you can do with index
  If none is set, the wanted type of index is not supported
  by the handler at all. See WorkLog 1563.
98 99 100 101 102
*/
#define HA_DDL_SUPPORT   1 /* Supported by handler */
#define HA_DDL_WITH_LOCK 2 /* Can create/drop with locked table */
#define HA_DDL_ONLINE    4 /* Can create/drop without lock */

103 104 105 106
/*
  Parameters for open() (in register form->filestat)
  HA_GET_INFO does an implicit HA_ABORT_IF_LOCKED
*/
bk@work.mysql.com's avatar
bk@work.mysql.com committed
107 108 109 110 111 112

#define HA_OPEN_KEYFILE		1
#define HA_OPEN_RNDFILE		2
#define HA_GET_INDEX		4
#define HA_GET_INFO		8	/* do a ha_info() after open */
#define HA_READ_ONLY		16	/* File opened as readonly */
113 114
/* Try readonly if can't open with read and write */
#define HA_TRY_READ_ONLY	32
bk@work.mysql.com's avatar
bk@work.mysql.com committed
115 116 117 118 119
#define HA_WAIT_IF_LOCKED	64	/* Wait if locked on open */
#define HA_ABORT_IF_LOCKED	128	/* skip if locked on open.*/
#define HA_BLOCK_LOCK		256	/* unlock when reading some records */
#define HA_OPEN_TEMPORARY	512

120
	/* Errors on write which is recoverable  (Key exist) */
monty@hundin.mysql.fi's avatar
monty@hundin.mysql.fi committed
121
#define HA_WRITE_SKIP 121		/* Duplicate key on write */
bk@work.mysql.com's avatar
bk@work.mysql.com committed
122 123 124 125 126 127 128 129 130 131 132 133 134
#define HA_READ_CHECK 123		/* Update with is recoverable */
#define HA_CANT_DO_THAT 131		/* Databasehandler can't do it */

	/* Some key definitions */
#define HA_KEY_NULL_LENGTH	1
#define HA_KEY_BLOB_LENGTH	2

#define HA_LEX_CREATE_TMP_TABLE	1
#define HA_LEX_CREATE_IF_NOT_EXISTS 2
#define HA_OPTION_NO_CHECKSUM	(1L << 17)
#define HA_OPTION_NO_DELAY_KEY_WRITE (1L << 18)
#define HA_MAX_REC_LENGTH	65535

135 136
/* Table caching type */
#define HA_CACHE_TBL_NONTRANSACT 0
137 138 139 140
#define HA_CACHE_TBL_NOCACHE     1
#define HA_CACHE_TBL_ASKTRANSACT 2
#define HA_CACHE_TBL_TRANSACT    4

141

142 143 144 145 146 147 148 149
enum db_type 
{ 
  DB_TYPE_UNKNOWN=0,DB_TYPE_DIAB_ISAM=1,
  DB_TYPE_HASH,DB_TYPE_MISAM,DB_TYPE_PISAM,
  DB_TYPE_RMS_ISAM, DB_TYPE_HEAP, DB_TYPE_ISAM,
  DB_TYPE_MRG_ISAM, DB_TYPE_MYISAM, DB_TYPE_MRG_MYISAM,
  DB_TYPE_BERKELEY_DB, DB_TYPE_INNODB, 
  DB_TYPE_GEMINI, DB_TYPE_NDBCLUSTER,
150
  DB_TYPE_EXAMPLE_DB, DB_TYPE_ARCHIVE_DB,
151 152 153
	       
  DB_TYPE_DEFAULT // Must be last
};
bk@work.mysql.com's avatar
bk@work.mysql.com committed
154

155 156 157 158 159 160 161
struct show_table_type_st {
  const char *type;
  SHOW_COMP_OPTION *value;
  const char *comment;
  enum db_type db_type;
};

162 163
enum row_type { ROW_TYPE_NOT_USED=-1, ROW_TYPE_DEFAULT, ROW_TYPE_FIXED,
		ROW_TYPE_DYNAMIC, ROW_TYPE_COMPRESSED};
bk@work.mysql.com's avatar
bk@work.mysql.com committed
164 165 166 167

/* struct to hold information about the table that should be created */

/* Bits in used_fields */
168 169 170 171
#define HA_CREATE_USED_AUTO		1
#define HA_CREATE_USED_RAID		2
#define HA_CREATE_USED_UNION		4
#define HA_CREATE_USED_INSERT_METHOD	8
172 173 174 175
#define HA_CREATE_USED_MIN_ROWS		16
#define HA_CREATE_USED_MAX_ROWS		32
#define HA_CREATE_USED_AVG_ROW_LENGTH	64
#define HA_CREATE_USED_PACK_KEYS	128
176
#define HA_CREATE_USED_CHARSET		256
177
#define HA_CREATE_USED_DEFAULT_CHARSET	512
bk@work.mysql.com's avatar
bk@work.mysql.com committed
178

179 180 181
typedef struct st_thd_trans {
  void *bdb_tid;
  void *innobase_tid;
monty@hundin.mysql.fi's avatar
monty@hundin.mysql.fi committed
182
  bool innodb_active_trans;
183
  void *ndb_tid;
184 185
} THD_TRANS;

monty@tik.mysql.fi's avatar
monty@tik.mysql.fi committed
186 187 188
enum enum_tx_isolation { ISO_READ_UNCOMMITTED, ISO_READ_COMMITTED,
			 ISO_REPEATABLE_READ, ISO_SERIALIZABLE};

bk@work.mysql.com's avatar
bk@work.mysql.com committed
189 190
typedef struct st_ha_create_information
{
191
  CHARSET_INFO *table_charset, *default_table_charset;
192 193 194
  const char *comment,*password;
  const char *data_file_name, *index_file_name;
  const char *alias;
195 196 197 198
  ulonglong max_rows,min_rows;
  ulonglong auto_increment_value;
  ulong table_options;
  ulong avg_row_length;
bk@work.mysql.com's avatar
bk@work.mysql.com committed
199 200
  ulong raid_chunksize;
  ulong used_fields;
201
  SQL_LIST merge_list;
202 203
  enum db_type db_type;
  enum row_type row_type;
204
  uint options;				/* OR of HA_CREATE_ options */
205
  uint raid_type,raid_chunks;
206
  uint merge_insert_method;
207
  bool table_existed;			/* 1 in create if table existed */
bk@work.mysql.com's avatar
bk@work.mysql.com committed
208 209 210 211 212 213 214 215 216 217 218
} HA_CREATE_INFO;


/* The handler for a table type.  Will be included in the TABLE structure */

struct st_table;
typedef struct st_table TABLE;

typedef struct st_ha_check_opt
{
  ulong sort_buffer_size;
serg@serg.mysql.com's avatar
serg@serg.mysql.com committed
219 220
  uint flags;       /* isam layer flags (e.g. for myisamchk) */
  uint sql_flags;   /* sql layer flags - for something myisamchk cannot do */
221
  KEY_CACHE *key_cache;	/* new key cache when changing key cache */
222
  void init();
bk@work.mysql.com's avatar
bk@work.mysql.com committed
223 224
} HA_CHECK_OPT;

225

bk@work.mysql.com's avatar
bk@work.mysql.com committed
226 227 228 229 230
class handler :public Sql_alloc
{
 protected:
  struct st_table *table;		/* The table definition */

231 232 233 234 235 236 237 238 239 240 241 242
  virtual int index_init(uint idx) { active_index=idx; return 0; }
  virtual int index_end() { active_index=MAX_KEY; return 0; }
  /*
    rnd_init() can be called two times without rnd_end() in between
    (it only makes sense if scan=1).
    then the second call should prepare for the new table scan (e.g
    if rnd_init allocates the cursor, second call should position it
    to the start of the table, no need to deallocate and allocate it again
  */
  virtual int rnd_init(bool scan) =0;
  virtual int rnd_end() { return 0; }

bk@work.mysql.com's avatar
bk@work.mysql.com committed
243 244 245 246 247 248 249 250 251
public:
  byte *ref;				/* Pointer to current row */
  byte *dupp_ref;			/* Pointer to dupp row */
  ulonglong data_file_length;		/* Length off data file */
  ulonglong max_data_file_length;	/* Length off data file */
  ulonglong index_file_length;
  ulonglong max_index_file_length;
  ulonglong delete_length;		/* Free bytes */
  ulonglong auto_increment_value;
252 253
  ha_rows records;			/* Records in table */
  ha_rows deleted;			/* Deleted records */
bk@work.mysql.com's avatar
bk@work.mysql.com committed
254
  ulong raid_chunksize;
255
  ulong mean_rec_length;		/* physical reclength */
bk@work.mysql.com's avatar
bk@work.mysql.com committed
256 257 258
  time_t create_time;			/* When table was created */
  time_t check_time;
  time_t update_time;
259 260 261 262 263

  /* The following are for read_range() */
  key_range save_end_range, *end_range;
  KEY_PART_INFO *range_key_part;
  int key_compare_result_on_equal;
264
  bool eq_range;
265

266 267 268 269 270 271 272
  uint errkey;				/* Last dup key */
  uint sortkey, key_used_on_scan;
  uint active_index;
  /* Length of ref (1-8 or the clustered key length) */
  uint ref_length;
  uint block_size;			/* index block size */
  uint raid_type,raid_chunks;
273
  FT_INFO *ft_handler;
274
  enum {NONE=0, INDEX, RND} inited;
275
  bool  auto_increment_column_changed;
276
  bool implicit_emptied;                /* Can be !=0 only if HEAP */
bk@work.mysql.com's avatar
bk@work.mysql.com committed
277

278

279 280 281 282 283
  handler(TABLE *table_arg) :table(table_arg),
    ref(0), data_file_length(0), max_data_file_length(0), index_file_length(0),
    delete_length(0), auto_increment_value(0),
    records(0), deleted(0), mean_rec_length(0),
    create_time(0), check_time(0), update_time(0),
284
    key_used_on_scan(MAX_KEY), active_index(MAX_KEY),
285
    ref_length(sizeof(my_off_t)), block_size(0),
286
    raid_type(0), ft_handler(0), inited(NONE), implicit_emptied(0)
bk@work.mysql.com's avatar
bk@work.mysql.com committed
287
    {}
288
  virtual ~handler(void) { /* TODO: DBUG_ASSERT(inited == NONE); */ }
bk@work.mysql.com's avatar
bk@work.mysql.com committed
289 290 291
  int ha_open(const char *name, int mode, int test_if_locked);
  void update_timestamp(byte *record);
  void update_auto_increment();
292
  virtual void print_error(int error, myf errflag);
293
  virtual bool get_error_message(int error, String *buf);
bk@work.mysql.com's avatar
bk@work.mysql.com committed
294 295 296
  uint get_dup_key(int error);
  void change_table_ptr(TABLE *table_arg) { table=table_arg; }
  virtual double scan_time()
297
    { return ulonglong2double(data_file_length) / IO_SIZE + 2; }
monty@narttu.mysql.fi's avatar
monty@narttu.mysql.fi committed
298 299
  virtual double read_time(uint index, uint ranges, ha_rows rows)
 { return rows2double(ranges+rows); }
serg@serg.mylan's avatar
serg@serg.mylan committed
300
  virtual const key_map *keys_to_use_for_scanning() { return &key_map_empty; }
bk@work.mysql.com's avatar
bk@work.mysql.com committed
301
  virtual bool has_transactions(){ return 0;}
302
  virtual uint extra_rec_buf_length() { return 0; }
303
  virtual ha_rows estimate_number_of_rows() { return records+EXTRA_RECORDS; }
bk@work.mysql.com's avatar
bk@work.mysql.com committed
304

305 306 307 308 309 310 311 312 313 314 315 316 317 318
  virtual const char *index_type(uint key_number) { DBUG_ASSERT(0); return "";}

  int ha_index_init(uint idx)
  {
    DBUG_ASSERT(inited==NONE);
    inited=INDEX;
    return index_init(idx);
  }
  int ha_index_end()
  {
    DBUG_ASSERT(inited==INDEX);
    inited=NONE;
    return index_end();
  }
319
  int ha_rnd_init(bool scan)
320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335
  {
    DBUG_ASSERT(inited==NONE || (inited==RND && scan));
    inited=RND;
    return rnd_init(scan);
  }
  int ha_rnd_end()
  {
    DBUG_ASSERT(inited==RND);
    inited=NONE;
    return rnd_end();
  }
  /* this is neseccary in many places, e.g. in HANDLER command */
  int ha_index_or_rnd_end()
  {
    return inited == INDEX ? ha_index_end() : inited == RND ? ha_rnd_end() : 0;
  }
bk@work.mysql.com's avatar
bk@work.mysql.com committed
336
  uint get_index(void) const { return active_index; }
337
  virtual int open(const char *name, int mode, uint test_if_locked)=0;
bk@work.mysql.com's avatar
bk@work.mysql.com committed
338
  virtual int close(void)=0;
339 340 341 342 343
  virtual int write_row(byte * buf) { return  HA_ERR_WRONG_COMMAND; }
  virtual int update_row(const byte * old_data, byte * new_data)
   { return  HA_ERR_WRONG_COMMAND; }
  virtual int delete_row(const byte * buf)
   { return  HA_ERR_WRONG_COMMAND; }
bk@work.mysql.com's avatar
bk@work.mysql.com committed
344
  virtual int index_read(byte * buf, const byte * key,
345 346
			 uint key_len, enum ha_rkey_function find_flag)
   { return  HA_ERR_WRONG_COMMAND; }
bk@work.mysql.com's avatar
bk@work.mysql.com committed
347
  virtual int index_read_idx(byte * buf, uint index, const byte * key,
348 349 350 351 352 353 354 355 356
			     uint key_len, enum ha_rkey_function find_flag);
  virtual int index_next(byte * buf)
   { return  HA_ERR_WRONG_COMMAND; }
  virtual int index_prev(byte * buf)
   { return  HA_ERR_WRONG_COMMAND; }
  virtual int index_first(byte * buf)
   { return  HA_ERR_WRONG_COMMAND; }
  virtual int index_last(byte * buf)
   { return  HA_ERR_WRONG_COMMAND; }
bk@work.mysql.com's avatar
bk@work.mysql.com committed
357
  virtual int index_next_same(byte *buf, const byte *key, uint keylen);
358
  virtual int index_read_last(byte * buf, const byte * key, uint key_len)
359
   { return (my_errno=HA_ERR_WRONG_COMMAND); }
360
  virtual int read_range_first(const key_range *start_key,
361 362 363
                               const key_range *end_key,
                               bool eq_range, bool sorted);
  virtual int read_range_next();
364
  int compare_key(key_range *range);
365
  virtual int ft_init() { return HA_ERR_WRONG_COMMAND; }
366 367
  virtual FT_INFO *ft_init_ext(uint flags,uint inx,const byte *key,
                               uint keylen)
368
    { return NULL; }
369
  virtual int ft_read(byte *buf) { return HA_ERR_WRONG_COMMAND; }
bk@work.mysql.com's avatar
bk@work.mysql.com committed
370 371
  virtual int rnd_next(byte *buf)=0;
  virtual int rnd_pos(byte * buf, byte *pos)=0;
372
  virtual int read_first_row(byte *buf, uint primary_key);
373 374 375 376 377 378 379 380
  /*
    The following function is only needed for tables that may be temporary
    tables during joins
  */
  virtual int restart_rnd_next(byte *buf, byte *pos)
    { return HA_ERR_WRONG_COMMAND; }
  virtual int rnd_same(byte *buf, uint inx)
    { return HA_ERR_WRONG_COMMAND; }
381 382
  virtual ha_rows records_in_range(uint inx, key_range *min_key,
                                   key_range *max_key)
bk@work.mysql.com's avatar
bk@work.mysql.com committed
383 384 385
    { return (ha_rows) 10; }
  virtual void position(const byte *record)=0;
  virtual void info(uint)=0;
386 387
  virtual int extra(enum ha_extra_function operation)
  { return 0; }
388
  virtual int extra_opt(enum ha_extra_function operation, ulong cache_size)
389
  { return extra(operation); }
390
  virtual int reset() { return extra(HA_EXTRA_RESET); }
bk@work.mysql.com's avatar
bk@work.mysql.com committed
391
  virtual int external_lock(THD *thd, int lock_type)=0;
monty@hundin.mysql.fi's avatar
monty@hundin.mysql.fi committed
392
  virtual void unlock_row() {}
393
  virtual int start_stmt(THD *thd) {return 0;}
394 395 396 397 398 399 400 401
  /*
    This is called to delete all rows in a table
    If the handler don't support this, then this function will
    return HA_ERR_WRONG_COMMAND and MySQL will delete the rows one
    by one.
  */
  virtual int delete_all_rows()
  { return (my_errno=HA_ERR_WRONG_COMMAND); }
bk@work.mysql.com's avatar
bk@work.mysql.com committed
402 403
  virtual longlong get_auto_increment();
  virtual void update_create_info(HA_CREATE_INFO *create_info) {}
404 405 406 407 408 409

  /* admin commands - called from mysql_admin_table */
  virtual int check(THD* thd, HA_CHECK_OPT* check_opt)
  { return HA_ADMIN_NOT_IMPLEMENTED; }
  virtual int backup(THD* thd, HA_CHECK_OPT* check_opt)
  { return HA_ADMIN_NOT_IMPLEMENTED; }
410 411 412 413
  /*
    restore assumes .frm file must exist, and that generate_table() has been
    called; It will just copy the data file and run repair.
  */
414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429
  virtual int restore(THD* thd, HA_CHECK_OPT* check_opt)
  { return HA_ADMIN_NOT_IMPLEMENTED; }
  virtual int repair(THD* thd, HA_CHECK_OPT* check_opt)
  { return HA_ADMIN_NOT_IMPLEMENTED; }
  virtual int optimize(THD* thd, HA_CHECK_OPT* check_opt)
  { return HA_ADMIN_NOT_IMPLEMENTED; }
  virtual int analyze(THD* thd, HA_CHECK_OPT* check_opt)
  { return HA_ADMIN_NOT_IMPLEMENTED; }
  virtual int assign_to_keycache(THD* thd, HA_CHECK_OPT* check_opt)
  { return HA_ADMIN_NOT_IMPLEMENTED; }
  virtual int preload_keys(THD* thd, HA_CHECK_OPT* check_opt)
  { return HA_ADMIN_NOT_IMPLEMENTED; }
  /* end of the list of admin commands */

  virtual bool check_and_repair(THD *thd) { return HA_ERR_WRONG_COMMAND; }
  virtual int dump(THD* thd, int fd = -1) { return HA_ERR_WRONG_COMMAND; }
430 431 432
  virtual int disable_indexes(uint mode) { return HA_ERR_WRONG_COMMAND; }
  virtual int enable_indexes(uint mode) { return HA_ERR_WRONG_COMMAND; }
  virtual int indexes_are_disabled(void) {return 0;}
433 434
  virtual void start_bulk_insert(ha_rows rows) {}
  virtual int end_bulk_insert() {return 0; }
435 436 437
  virtual int discard_or_import_tablespace(my_bool discard)
  {return HA_ERR_WRONG_COMMAND;}
  virtual int net_read_dump(NET* net) { return HA_ERR_WRONG_COMMAND; }
438 439 440
  virtual char *update_table_comment(const char * comment)
  { return (char*) comment;}
  virtual void append_create_info(String *packet) {}
441 442
  virtual char* get_foreign_key_create_info()
  { return(NULL);}  /* gets foreign key create string from InnoDB */
monty@mysql.com's avatar
monty@mysql.com committed
443 444
  /* used in REPLACE; is > 0 if table is referred by a FOREIGN KEY */
  virtual uint referenced_by_foreign_key() { return 0;}
445
  virtual void init_table_handle_for_HANDLER()
serg@serg.mylan's avatar
serg@serg.mylan committed
446 447
  { return; }       /* prepare InnoDB for HANDLER */
  virtual void free_foreign_key_create_info(char* str) {}
bk@work.mysql.com's avatar
bk@work.mysql.com committed
448 449 450
  /* The following can be called without an open handler */
  virtual const char *table_type() const =0;
  virtual const char **bas_ext() const =0;
451
  virtual ulong table_flags(void) const =0;
452
  virtual ulong index_flags(uint idx, uint part=~0) const =0;
453
  virtual ulong index_ddl_flags(KEY *wanted_index) const
454
  { return (HA_DDL_SUPPORT); }
455
  virtual int add_index(TABLE *table_arg, KEY *key_info, uint num_of_keys)
456
  { return (HA_ERR_WRONG_COMMAND); }
457
  virtual int drop_index(TABLE *table_arg, uint *key_num, uint num_of_keys)
458 459 460 461 462 463 464 465 466 467
  { return (HA_ERR_WRONG_COMMAND); }

  uint max_record_length() const
  { return min(HA_MAX_REC_LENGTH, max_supported_record_length()); }
  uint max_keys() const
  { return min(MAX_KEY, max_supported_keys()); }
  uint max_key_parts() const
  { return min(MAX_REF_PARTS, max_supported_key_parts()); }
  uint max_key_length() const
  { return min(MAX_KEY_LENGTH, max_supported_key_length()); }
468
  uint max_key_part_length() const
469 470 471 472 473 474
  { return min(MAX_KEY_LENGTH, max_supported_key_part_length()); }

  virtual uint max_supported_record_length() const { return HA_MAX_REC_LENGTH; }
  virtual uint max_supported_keys() const { return 0; }
  virtual uint max_supported_key_parts() const { return MAX_REF_PARTS; }
  virtual uint max_supported_key_length() const { return MAX_KEY_LENGTH; }
475
  virtual uint max_supported_key_part_length() const { return 255; }
bk@work.mysql.com's avatar
bk@work.mysql.com committed
476
  virtual uint min_record_length(uint options) const { return 1; }
477

bk@work.mysql.com's avatar
bk@work.mysql.com committed
478
  virtual bool low_byte_first() const { return 1; }
serg@serg.mylan's avatar
serg@serg.mylan committed
479
  virtual uint checksum() const { return 0; }
480 481
  virtual bool is_crashed() const  { return 0; }
  virtual bool auto_repair() const { return 0; }
bk@work.mysql.com's avatar
bk@work.mysql.com committed
482

483 484 485 486
  /*
    default rename_table() and delete_table() rename/delete files with a
    given name and extensions from bas_ext()
  */
bk@work.mysql.com's avatar
bk@work.mysql.com committed
487 488
  virtual int rename_table(const char *from, const char *to);
  virtual int delete_table(const char *name);
489
  
bk@work.mysql.com's avatar
bk@work.mysql.com committed
490
  virtual int create(const char *name, TABLE *form, HA_CREATE_INFO *info)=0;
491 492

  /* lock_count() can be more than one if the table is a MERGE */
bk@work.mysql.com's avatar
bk@work.mysql.com committed
493 494 495 496
  virtual uint lock_count(void) const { return 1; }
  virtual THR_LOCK_DATA **store_lock(THD *thd,
				     THR_LOCK_DATA **to,
				     enum thr_lock_type lock_type)=0;
497 498 499

  /* Type of table for caching query */
  virtual uint8 table_cache_type() { return HA_CACHE_TBL_NONTRANSACT; }
serg@serg.mylan's avatar
serg@serg.mylan committed
500 501
  /*
    Is query with this table cachable (have sense only for ASKTRANSACT
502 503
    tables)
  */
bk@work.mysql.com's avatar
bk@work.mysql.com committed
504 505 506 507
};

	/* Some extern variables used with handlers */

508
extern struct show_table_type_st sys_table_types[];
bk@work.mysql.com's avatar
bk@work.mysql.com committed
509
extern const char *ha_row_type[];
510
extern TYPELIB tx_isolation_typelib;
bk@work.mysql.com's avatar
bk@work.mysql.com committed
511

512 513 514 515 516 517
	/* Wrapper functions */
#define ha_commit_stmt(thd) (ha_commit_trans((thd), &((thd)->transaction.stmt)))
#define ha_rollback_stmt(thd) (ha_rollback_trans((thd), &((thd)->transaction.stmt)))
#define ha_commit(thd) (ha_commit_trans((thd), &((thd)->transaction.all)))
#define ha_rollback(thd) (ha_rollback_trans((thd), &((thd)->transaction.all)))

518 519
#define ha_supports_generate(T) (T != DB_TYPE_INNODB)

520 521
bool ha_caching_allowed(THD* thd, char* table_key,
                        uint key_length, uint8 cache_type);
522
enum db_type ha_resolve_by_name(const char *name, uint namelen);
523
const char *ha_get_storage_engine(enum db_type db_type);
bk@work.mysql.com's avatar
bk@work.mysql.com committed
524 525 526 527 528
handler *get_new_handler(TABLE *table, enum db_type db_type);
my_off_t ha_get_ptr(byte *ptr, uint pack_length);
void ha_store_ptr(byte *buff, uint pack_length, my_off_t pos);
int ha_init(void);
int ha_panic(enum ha_panic_function flag);
529
void ha_close_connection(THD* thd);
bk@work.mysql.com's avatar
bk@work.mysql.com committed
530 531 532 533
enum db_type ha_checktype(enum db_type database_type);
int ha_create_table(const char *name, HA_CREATE_INFO *create_info,
		    bool update_create_info);
int ha_delete_table(enum db_type db_type, const char *path);
534
void ha_drop_database(char* path);
535 536 537 538
int ha_init_key_cache(const char *name, KEY_CACHE *key_cache);
int ha_resize_key_cache(KEY_CACHE *key_cache);
int ha_change_key_cache_param(KEY_CACHE *key_cache);
int ha_end_key_cache(KEY_CACHE *key_cache);
serg@serg.mylan's avatar
serg@serg.mylan committed
539
int ha_start_stmt(THD *thd);
540 541
int ha_report_binlog_offset_and_commit(THD *thd, char *log_file_name,
				       my_off_t end_offset);
heikki@hundin.mysql.fi's avatar
heikki@hundin.mysql.fi committed
542
int ha_commit_complete(THD *thd);
543
int ha_release_temporary_latches(THD *thd);
544 545
int ha_commit_trans(THD *thd, THD_TRANS *trans);
int ha_rollback_trans(THD *thd, THD_TRANS *trans);
heikki@hundin.mysql.fi's avatar
heikki@hundin.mysql.fi committed
546 547
int ha_rollback_to_savepoint(THD *thd, char *savepoint_name);
int ha_savepoint(THD *thd, char *savepoint_name);
bk@work.mysql.com's avatar
bk@work.mysql.com committed
548
int ha_autocommit_or_rollback(THD *thd, int error);
monty@tik.mysql.fi's avatar
monty@tik.mysql.fi committed
549
void ha_set_spin_retries(uint retries);
bk@work.mysql.com's avatar
bk@work.mysql.com committed
550
bool ha_flush_logs(void);
551
int ha_recovery_logging(THD *thd, bool on);
552 553
int ha_change_key_cache(KEY_CACHE *old_key_cache,
			KEY_CACHE *new_key_cache);
554 555
int ha_discover(const char* dbname, const char* name,
		const void** frmblob, uint* frmlen);