~ubuntu-branches/ubuntu/trusty/drizzle/trusty

« back to all changes in this revision

Viewing changes to drizzled/cursor.h

  • Committer: Bazaar Package Importer
  • Author(s): Monty Taylor
  • Date: 2010-03-18 12:12:31 UTC
  • Revision ID: james.westby@ubuntu.com-20100318121231-k6g1xe6cshbwa0f8
Tags: upstream-2010.03.1347
ImportĀ upstreamĀ versionĀ 2010.03.1347

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
 
2
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
 
3
 *
 
4
 *  Copyright (C) 2008 Sun Microsystems
 
5
 *
 
6
 *  This program is free software; you can redistribute it and/or modify
 
7
 *  it under the terms of the GNU General Public License as published by
 
8
 *  the Free Software Foundation; version 2 of the License.
 
9
 *
 
10
 *  This program is distributed in the hope that it will be useful,
 
11
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
13
 *  GNU General Public License for more details.
 
14
 *
 
15
 *  You should have received a copy of the GNU General Public License
 
16
 *  along with this program; if not, write to the Free Software
 
17
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
18
 */
 
19
 
 
20
#ifndef DRIZZLED_CURSOR_H
 
21
#define DRIZZLED_CURSOR_H
 
22
 
 
23
#include <drizzled/xid.h>
 
24
#include <drizzled/discrete_interval.h>
 
25
#include <drizzled/table_identifier.h>
 
26
 
 
27
/* Definitions for parameters to do with Cursor-routines */
 
28
 
 
29
#include <drizzled/thr_lock.h>
 
30
#include <drizzled/sql_string.h>
 
31
#include <drizzled/sql_list.h>
 
32
#include <drizzled/plugin/storage_engine.h>
 
33
#include <drizzled/handler_structs.h>
 
34
#include <drizzled/ha_statistics.h>
 
35
#include <drizzled/atomics.h>
 
36
 
 
37
#include <drizzled/message/table.pb.h>
 
38
 
 
39
/* Bits to show what an alter table will do */
 
40
#include <drizzled/sql_bitmap.h>
 
41
 
 
42
#include <drizzled/cursor.h>
 
43
 
 
44
#include <bitset>
 
45
#include <algorithm>
 
46
 
 
47
namespace drizzled
 
48
{
 
49
 
 
50
#define HA_MAX_ALTER_FLAGS 40
 
51
 
 
52
 
 
53
typedef std::bitset<HA_MAX_ALTER_FLAGS> HA_ALTER_FLAGS;
 
54
 
 
55
extern uint64_t refresh_version;  /* Increments on each reload */
 
56
 
 
57
 
 
58
typedef bool (*qc_engine_callback)(Session *session, char *table_key,
 
59
                                      uint32_t key_length,
 
60
                                      uint64_t *engine_data);
 
61
 
 
62
 
 
63
/* The Cursor for a table type.  Will be included in the Table structure */
 
64
 
 
65
class Table;
 
66
class TableList;
 
67
class TableShare;
 
68
class Select_Lex_Unit;
 
69
struct st_foreign_key_info;
 
70
typedef struct st_foreign_key_info FOREIGN_KEY_INFO;
 
71
struct order_st;
 
72
 
 
73
class Item;
 
74
struct st_table_log_memory_entry;
 
75
 
 
76
class LEX;
 
77
class Select_Lex;
 
78
class AlterInfo;
 
79
class select_result;
 
80
class CreateField;
 
81
class sys_var_str;
 
82
class Item_ident;
 
83
typedef struct st_sort_field SORT_FIELD;
 
84
 
 
85
typedef List<Item> List_item;
 
86
extern KEY_CREATE_INFO default_key_create_info;
 
87
 
 
88
/* Forward declaration for condition pushdown to storage engine */
 
89
typedef class Item COND;
 
90
 
 
91
typedef struct system_status_var system_status_var;
 
92
 
 
93
class COST_VECT;
 
94
 
 
95
uint32_t calculate_key_len(Table *, uint, const unsigned char *, key_part_map);
 
96
/*
 
97
  bitmap with first N+1 bits set
 
98
  (keypart_map for a key prefix of [0..N] keyparts)
 
99
*/
 
100
template<class T>
 
101
inline key_part_map make_keypart_map(T a)
 
102
{
 
103
  return (((key_part_map)2 << a) - 1);
 
104
}
 
105
 
 
106
/*
 
107
  bitmap with first N bits set
 
108
  (keypart_map for a key prefix of [0..N-1] keyparts)
 
109
*/
 
110
template<class T>
 
111
inline key_part_map make_prev_keypart_map(T a)
 
112
{
 
113
  return (((key_part_map)1 << a) - 1);
 
114
}
 
115
 
 
116
/**
 
117
  The Cursor class is the interface for dynamically loadable
 
118
  storage engines. Do not add ifdefs and take care when adding or
 
119
  changing virtual functions to avoid vtable confusion
 
120
 
 
121
  Functions in this class accept and return table columns data. Two data
 
122
  representation formats are used:
 
123
  1. TableRecordFormat - Used to pass [partial] table records to/from
 
124
     storage engine
 
125
 
 
126
  2. KeyTupleFormat - used to pass index search tuples (aka "keys") to
 
127
     storage engine. See optimizer/range.cc for description of this format.
 
128
 
 
129
  TableRecordFormat
 
130
  =================
 
131
  [Warning: this description is work in progress and may be incomplete]
 
132
  The table record is stored in a fixed-size buffer:
 
133
 
 
134
    record: null_bytes, column1_data, column2_data, ...
 
135
 
 
136
  The offsets of the parts of the buffer are also fixed: every column has
 
137
  an offset to its column{i}_data, and if it is nullable it also has its own
 
138
  bit in null_bytes.
 
139
 
 
140
  The record buffer only includes data about columns that are marked in the
 
141
  relevant column set (table->read_set and/or table->write_set, depending on
 
142
  the situation).
 
143
  <not-sure>It could be that it is required that null bits of non-present
 
144
  columns are set to 1</not-sure>
 
145
 
 
146
  VARIOUS EXCEPTIONS AND SPECIAL CASES
 
147
 
 
148
  f the table has no nullable columns, then null_bytes is still
 
149
  present, its length is one byte <not-sure> which must be set to 0xFF
 
150
  at all times. </not-sure>
 
151
 
 
152
  If the table has columns of type BIT, then certain bits from those columns
 
153
  may be stored in null_bytes as well. Grep around for Field_bit for
 
154
  details.
 
155
 
 
156
  For blob columns (see Field_blob), the record buffer stores length of the
 
157
  data, following by memory pointer to the blob data. The pointer is owned
 
158
  by the storage engine and is valid until the next operation.
 
159
 
 
160
  If a blob column has NULL value, then its length and blob data pointer
 
161
  must be set to 0.
 
162
*/
 
163
 
 
164
class Cursor :public memory::SqlAlloc
 
165
{
 
166
protected:
 
167
  TableShare *table_share;   /* The table definition */
 
168
  Table *table;               /* The current open table */
 
169
 
 
170
  ha_rows estimation_rows_to_insert;
 
171
public:
 
172
  plugin::StorageEngine *engine;      /* storage engine of this Cursor */
 
173
  inline plugin::StorageEngine *getEngine() const       /* table_type for handler */
 
174
  {
 
175
    return engine;
 
176
  }
 
177
  unsigned char *ref;                           /* Pointer to current row */
 
178
  unsigned char *dup_ref;                       /* Pointer to duplicate row */
 
179
 
 
180
  ha_statistics stats;
 
181
  /** MultiRangeRead-related members: */
 
182
  range_seq_t mrr_iter;    /* Interator to traverse the range sequence */
 
183
  RANGE_SEQ_IF mrr_funcs;  /* Range sequence traversal functions */
 
184
  HANDLER_BUFFER *multi_range_buffer; /* MRR buffer info */
 
185
  uint32_t ranges_in_seq; /* Total number of ranges in the traversed sequence */
 
186
  /* true <=> source MRR ranges and the output are ordered */
 
187
  bool mrr_is_output_sorted;
 
188
 
 
189
  /** true <=> we're currently traversing a range in mrr_cur_range. */
 
190
  bool mrr_have_range;
 
191
 
 
192
  bool eq_range;
 
193
  /*
 
194
    true <=> the engine guarantees that returned records are within the range
 
195
    being scanned.
 
196
  */
 
197
  bool in_range_check_pushed_down;
 
198
 
 
199
  /** Current range (the one we're now returning rows from) */
 
200
  KEY_MULTI_RANGE mrr_cur_range;
 
201
 
 
202
  /** The following are for read_range() */
 
203
  key_range save_end_range, *end_range;
 
204
  KEY_PART_INFO *range_key_part;
 
205
  int key_compare_result_on_equal;
 
206
 
 
207
  uint32_t errkey;                              /* Last dup key */
 
208
  uint32_t key_used_on_scan;
 
209
  uint32_t active_index;
 
210
  /** Length of ref (1-8 or the clustered key length) */
 
211
  uint32_t ref_length;
 
212
  enum {NONE=0, INDEX, RND} inited;
 
213
  bool locked;
 
214
  bool implicit_emptied;                /* Can be !=0 only if HEAP */
 
215
 
 
216
  /**
 
217
    next_insert_id is the next value which should be inserted into the
 
218
    auto_increment column: in a inserting-multi-row statement (like INSERT
 
219
    SELECT), for the first row where the autoinc value is not specified by the
 
220
    statement, get_auto_increment() called and asked to generate a value,
 
221
    next_insert_id is set to the next value, then for all other rows
 
222
    next_insert_id is used (and increased each time) without calling
 
223
    get_auto_increment().
 
224
  */
 
225
  uint64_t next_insert_id;
 
226
  uint64_t getNextInsertId()
 
227
  {
 
228
    return next_insert_id;
 
229
  }
 
230
 
 
231
  /**
 
232
    insert id for the current row (*autogenerated*; if not
 
233
    autogenerated, it's 0).
 
234
    At first successful insertion, this variable is stored into
 
235
    Session::first_successful_insert_id_in_cur_stmt.
 
236
  */
 
237
  uint64_t insert_id_for_cur_row;
 
238
  /**
 
239
    Interval returned by get_auto_increment() and being consumed by the
 
240
    inserter.
 
241
  */
 
242
  Discrete_interval auto_inc_interval_for_cur_row;
 
243
 
 
244
  Cursor(plugin::StorageEngine &engine_arg, TableShare &share_arg);
 
245
  virtual ~Cursor(void);
 
246
  virtual Cursor *clone(memory::Root *mem_root);
 
247
 
 
248
  /* ha_ methods: pubilc wrappers for private virtual API */
 
249
 
 
250
  int ha_open(Table *table, const char *name, int mode, int test_if_locked);
 
251
  int ha_index_init(uint32_t idx, bool sorted);
 
252
  int ha_index_end();
 
253
  int ha_rnd_init(bool scan);
 
254
  int ha_rnd_end();
 
255
  int ha_reset();
 
256
 
 
257
  /* this is necessary in many places, e.g. in HANDLER command */
 
258
  int ha_index_or_rnd_end();
 
259
 
 
260
  /**
 
261
    These functions represent the public interface to *users* of the
 
262
    Cursor class, hence they are *not* virtual. For the inheritance
 
263
    interface, see the (private) functions write_row(), update_row(),
 
264
    and delete_row() below.
 
265
  */
 
266
  int ha_external_lock(Session *session, int lock_type);
 
267
  int ha_write_row(unsigned char * buf);
 
268
  int ha_update_row(const unsigned char * old_data, unsigned char * new_data);
 
269
  int ha_delete_row(const unsigned char * buf);
 
270
  void ha_release_auto_increment();
 
271
 
 
272
  /** to be actually called to get 'check()' functionality*/
 
273
  int ha_check(Session *session, HA_CHECK_OPT *check_opt);
 
274
 
 
275
  void ha_start_bulk_insert(ha_rows rows);
 
276
  int ha_end_bulk_insert();
 
277
  int ha_delete_all_rows();
 
278
  int ha_reset_auto_increment(uint64_t value);
 
279
  int ha_analyze(Session* session, HA_CHECK_OPT* check_opt);
 
280
 
 
281
  int ha_disable_indexes(uint32_t mode);
 
282
  int ha_enable_indexes(uint32_t mode);
 
283
  int ha_discard_or_import_tablespace(bool discard);
 
284
  void closeMarkForDelete(const char *name);
 
285
 
 
286
  void adjust_next_insert_id_after_explicit_value(uint64_t nr);
 
287
  int update_auto_increment();
 
288
  virtual void change_table_ptr(Table *table_arg, TableShare *share);
 
289
 
 
290
  /* Estimates calculation */
 
291
  virtual double scan_time(void)
 
292
  { return uint64_t2double(stats.data_file_length) / IO_SIZE + 2; }
 
293
  virtual double read_time(uint32_t, uint32_t ranges, ha_rows rows)
 
294
  { return rows2double(ranges+rows); }
 
295
 
 
296
  virtual double index_only_read_time(uint32_t keynr, double records);
 
297
 
 
298
  virtual ha_rows multi_range_read_info_const(uint32_t keyno, RANGE_SEQ_IF *seq,
 
299
                                              void *seq_init_param,
 
300
                                              uint32_t n_ranges, uint32_t *bufsz,
 
301
                                              uint32_t *flags, COST_VECT *cost);
 
302
  virtual int multi_range_read_info(uint32_t keyno, uint32_t n_ranges, uint32_t keys,
 
303
                                    uint32_t *bufsz, uint32_t *flags, COST_VECT *cost);
 
304
  virtual int multi_range_read_init(RANGE_SEQ_IF *seq, void *seq_init_param,
 
305
                                    uint32_t n_ranges, uint32_t mode,
 
306
                                    HANDLER_BUFFER *buf);
 
307
  virtual int multi_range_read_next(char **range_info);
 
308
 
 
309
 
 
310
  virtual const key_map *keys_to_use_for_scanning();
 
311
  bool has_transactions();
 
312
 
 
313
  /**
 
314
    This method is used to analyse the error to see whether the error
 
315
    is ignorable or not, certain handlers can have more error that are
 
316
    ignorable than others. E.g. the partition Cursor can get inserts
 
317
    into a range where there is no partition and this is an ignorable
 
318
    error.
 
319
    HA_ERR_FOUND_DUP_UNIQUE is a special case in MyISAM that means the
 
320
    same thing as HA_ERR_FOUND_DUP_KEY but can in some cases lead to
 
321
    a slightly different error message.
 
322
  */
 
323
  virtual bool is_fatal_error(int error, uint32_t flags);
 
324
 
 
325
  /**
 
326
    Number of rows in table. It will only be called if
 
327
    (table_flags() & (HA_HAS_RECORDS | HA_STATS_RECORDS_IS_EXACT)) != 0
 
328
  */
 
329
  virtual ha_rows records();
 
330
  virtual uint64_t tableSize();
 
331
  virtual uint64_t rowSize();
 
332
  /**
 
333
    Return upper bound of current number of records in the table
 
334
    (max. of how many records one will retrieve when doing a full table scan)
 
335
    If upper bound is not known, HA_POS_ERROR should be returned as a max
 
336
    possible upper bound.
 
337
  */
 
338
  virtual ha_rows estimate_rows_upper_bound()
 
339
  { return stats.records+EXTRA_RECORDS; }
 
340
 
 
341
  /**
 
342
    Get the row type from the storage engine.  If this method returns
 
343
    ROW_TYPE_NOT_USED, the information in HA_CREATE_INFO should be used.
 
344
  */
 
345
  virtual enum row_type get_row_type() const { return ROW_TYPE_NOT_USED; }
 
346
 
 
347
  virtual const char *index_type(uint32_t)
 
348
  { assert(0); return "";}
 
349
 
 
350
 
 
351
  uint32_t get_index(void) const { return active_index; }
 
352
  virtual int close(void)=0;
 
353
 
 
354
  /**
 
355
     @brief
 
356
     Positions an index cursor to the index specified in the handle. Fetches the
 
357
     row if available. If the key value is null, begin at the first key of the
 
358
     index.
 
359
  */
 
360
  virtual int index_read_map(unsigned char * buf, const unsigned char * key,
 
361
                             key_part_map keypart_map,
 
362
                             enum ha_rkey_function find_flag)
 
363
  {
 
364
    uint32_t key_len= calculate_key_len(table, active_index, key, keypart_map);
 
365
    return  index_read(buf, key, key_len, find_flag);
 
366
  }
 
367
  /**
 
368
     @brief
 
369
     Positions an index cursor to the index specified in the handle. Fetches the
 
370
     row if available. If the key value is null, begin at the first key of the
 
371
     index.
 
372
  */
 
373
  virtual int index_read_idx_map(unsigned char * buf, uint32_t index,
 
374
                                 const unsigned char * key,
 
375
                                 key_part_map keypart_map,
 
376
                                 enum ha_rkey_function find_flag);
 
377
  virtual int index_next(unsigned char *)
 
378
   { return  HA_ERR_WRONG_COMMAND; }
 
379
  virtual int index_prev(unsigned char *)
 
380
   { return  HA_ERR_WRONG_COMMAND; }
 
381
  virtual int index_first(unsigned char *)
 
382
   { return  HA_ERR_WRONG_COMMAND; }
 
383
  virtual int index_last(unsigned char *)
 
384
   { return  HA_ERR_WRONG_COMMAND; }
 
385
  virtual int index_next_same(unsigned char *, const unsigned char *, uint32_t);
 
386
  /**
 
387
     @brief
 
388
     The following functions works like index_read, but it find the last
 
389
     row with the current key value or prefix.
 
390
  */
 
391
  virtual int index_read_last_map(unsigned char * buf, const unsigned char * key,
 
392
                                  key_part_map keypart_map)
 
393
  {
 
394
    uint32_t key_len= calculate_key_len(table, active_index, key, keypart_map);
 
395
    return index_read_last(buf, key, key_len);
 
396
  }
 
397
  virtual int read_range_first(const key_range *start_key,
 
398
                               const key_range *end_key,
 
399
                               bool eq_range, bool sorted);
 
400
  virtual int read_range_next();
 
401
  int compare_key(key_range *range);
 
402
  int compare_key2(key_range *range);
 
403
  virtual int rnd_next(unsigned char *)=0;
 
404
  virtual int rnd_pos(unsigned char *, unsigned char *)=0;
 
405
  /**
 
406
    One has to use this method when to find
 
407
    random position by record as the plain
 
408
    position() call doesn't work for some
 
409
    handlers for random position.
 
410
  */
 
411
  virtual int rnd_pos_by_record(unsigned char *record);
 
412
  virtual int read_first_row(unsigned char *buf, uint32_t primary_key);
 
413
  /**
 
414
    The following function is only needed for tables that may be temporary
 
415
    tables during joins.
 
416
  */
 
417
  virtual int restart_rnd_next(unsigned char *, unsigned char *)
 
418
    { return HA_ERR_WRONG_COMMAND; }
 
419
  virtual int rnd_same(unsigned char *, uint32_t)
 
420
    { return HA_ERR_WRONG_COMMAND; }
 
421
  virtual ha_rows records_in_range(uint32_t, key_range *, key_range *)
 
422
    { return (ha_rows) 10; }
 
423
  virtual void position(const unsigned char *record)=0;
 
424
  virtual int info(uint32_t)=0; // see my_base.h for full description
 
425
  virtual uint32_t calculate_key_hash_value(Field **)
 
426
  { assert(0); return 0; }
 
427
  virtual int extra(enum ha_extra_function)
 
428
  { return 0; }
 
429
  virtual int extra_opt(enum ha_extra_function operation, uint32_t)
 
430
  { return extra(operation); }
 
431
 
 
432
  /**
 
433
    In an UPDATE or DELETE, if the row under the cursor was locked by another
 
434
    transaction, and the engine used an optimistic read of the last
 
435
    committed row value under the cursor, then the engine returns 1 from this
 
436
    function. MySQL must NOT try to update this optimistic value. If the
 
437
    optimistic value does not match the WHERE condition, MySQL can decide to
 
438
    skip over this row. Currently only works for InnoDB. This can be used to
 
439
    avoid unnecessary lock waits.
 
440
 
 
441
    If this method returns nonzero, it will also signal the storage
 
442
    engine that the next read will be a locking re-read of the row.
 
443
  */
 
444
  virtual bool was_semi_consistent_read() { return 0; }
 
445
  /**
 
446
    Tell the engine whether it should avoid unnecessary lock waits.
 
447
    If yes, in an UPDATE or DELETE, if the row under the cursor was locked
 
448
    by another transaction, the engine may try an optimistic read of
 
449
    the last committed row value under the cursor.
 
450
  */
 
451
  virtual void try_semi_consistent_read(bool) {}
 
452
  virtual void unlock_row(void) {}
 
453
  virtual void get_auto_increment(uint64_t offset, uint64_t increment,
 
454
                                  uint64_t nb_desired_values,
 
455
                                  uint64_t *first_value,
 
456
                                  uint64_t *nb_reserved_values);
 
457
  void set_next_insert_id(uint64_t id)
 
458
  {
 
459
    next_insert_id= id;
 
460
  }
 
461
  void restore_auto_increment(uint64_t prev_insert_id)
 
462
  {
 
463
    /*
 
464
      Insertion of a row failed, re-use the lastly generated auto_increment
 
465
      id, for the next row. This is achieved by resetting next_insert_id to
 
466
      what it was before the failed insertion (that old value is provided by
 
467
      the caller). If that value was 0, it was the first row of the INSERT;
 
468
      then if insert_id_for_cur_row contains 0 it means no id was generated
 
469
      for this first row, so no id was generated since the INSERT started, so
 
470
      we should set next_insert_id to 0; if insert_id_for_cur_row is not 0, it
 
471
      is the generated id of the first and failed row, so we use it.
 
472
    */
 
473
    next_insert_id= (prev_insert_id > 0) ? prev_insert_id :
 
474
      insert_id_for_cur_row;
 
475
  }
 
476
 
 
477
  virtual void update_create_info(HA_CREATE_INFO *) {}
 
478
  int check_old_types(void);
 
479
  /* end of the list of admin commands */
 
480
 
 
481
  virtual int indexes_are_disabled(void) {return 0;}
 
482
  virtual void append_create_info(String *)
 
483
  {}
 
484
  /**
 
485
      If index == MAX_KEY then a check for table is made and if index <
 
486
      MAX_KEY then a check is made if the table has foreign keys and if
 
487
      a foreign key uses this index (and thus the index cannot be dropped).
 
488
 
 
489
    @param  index            Index to check if foreign key uses it
 
490
 
 
491
    @retval   true            Foreign key defined on table or index
 
492
    @retval   false           No foreign key defined
 
493
  */
 
494
  virtual char* get_foreign_key_create_info(void)
 
495
  { return NULL;}  /* gets foreign key create string from InnoDB */
 
496
  /** used in ALTER Table; if changing storage engine is allowed.
 
497
      e.g. not be allowed if table has foreign key constraints in engine.
 
498
   */
 
499
  virtual bool can_switch_engines(void) { return true; }
 
500
  /** used in REPLACE; is > 0 if table is referred by a FOREIGN KEY */
 
501
  virtual int get_foreign_key_list(Session *, List<FOREIGN_KEY_INFO> *)
 
502
  { return 0; }
 
503
  virtual uint32_t referenced_by_foreign_key() { return 0;}
 
504
  virtual void free_foreign_key_create_info(char *) {}
 
505
  /** The following can be called without an open Cursor */
 
506
 
 
507
  virtual int add_index(Table *, KEY *, uint32_t)
 
508
  { return (HA_ERR_WRONG_COMMAND); }
 
509
  virtual int prepare_drop_index(Table *, uint32_t *, uint32_t)
 
510
  { return (HA_ERR_WRONG_COMMAND); }
 
511
  virtual int final_drop_index(Table *)
 
512
  { return (HA_ERR_WRONG_COMMAND); }
 
513
 
 
514
  virtual uint32_t checksum(void) const { return 0; }
 
515
 
 
516
  /**
 
517
    Is not invoked for non-transactional temporary tables.
 
518
 
 
519
    @note store_lock() can return more than one lock if the table is MERGE
 
520
    or partitioned.
 
521
 
 
522
    @note that one can NOT rely on table->in_use in store_lock().  It may
 
523
    refer to a different thread if called from mysql_lock_abort_for_thread().
 
524
 
 
525
    @note If the table is MERGE, store_lock() can return less locks
 
526
    than lock_count() claimed. This can happen when the MERGE children
 
527
    are not attached when this is called from another thread.
 
528
  */
 
529
  virtual THR_LOCK_DATA **store_lock(Session *,
 
530
                                     THR_LOCK_DATA **to,
 
531
                                     enum thr_lock_type)
 
532
  {
 
533
    assert(0); // Impossible programming situation
 
534
 
 
535
    return(to);
 
536
  }
 
537
 
 
538
 /*
 
539
   @retval true   Primary key (if there is one) is clustered
 
540
                  key covering all fields
 
541
   @retval false  otherwise
 
542
 */
 
543
 virtual bool primary_key_is_clustered() { return false; }
 
544
 virtual int cmp_ref(const unsigned char *ref1, const unsigned char *ref2)
 
545
 {
 
546
   return memcmp(ref1, ref2, ref_length);
 
547
 }
 
548
 
 
549
  virtual bool isOrdered(void)
 
550
  {
 
551
    return false;
 
552
  }
 
553
 
 
554
 
 
555
protected:
 
556
  /* Service methods for use by storage engines. */
 
557
  void ha_statistic_increment(ulong system_status_var::*offset) const;
 
558
  void **ha_data(Session *) const;
 
559
  Session *ha_session(void) const;
 
560
 
 
561
private:
 
562
  /* Private helpers */
 
563
  inline void setTransactionReadWrite();
 
564
private:
 
565
  /*
 
566
    Low-level primitives for storage engines.  These should be
 
567
    overridden by the storage engine class. To call these methods, use
 
568
    the corresponding 'ha_*' method above.
 
569
  */
 
570
 
 
571
  virtual int open(const char *name, int mode, uint32_t test_if_locked)=0;
 
572
  virtual int index_init(uint32_t idx, bool)
 
573
  { active_index= idx; return 0; }
 
574
  virtual int index_end() { active_index= MAX_KEY; return 0; }
 
575
  /**
 
576
    rnd_init() can be called two times without rnd_end() in between
 
577
    (it only makes sense if scan=1).
 
578
    then the second call should prepare for the new table scan (e.g
 
579
    if rnd_init allocates the cursor, second call should position it
 
580
    to the start of the table, no need to deallocate and allocate it again
 
581
  */
 
582
  virtual int rnd_init(bool scan)= 0;
 
583
  virtual int rnd_end() { return 0; }
 
584
  virtual int write_row(unsigned char *)
 
585
  {
 
586
    return HA_ERR_WRONG_COMMAND;
 
587
  }
 
588
 
 
589
  virtual int update_row(const unsigned char *, unsigned char *)
 
590
  {
 
591
    return HA_ERR_WRONG_COMMAND;
 
592
  }
 
593
 
 
594
  virtual int delete_row(const unsigned char *)
 
595
  {
 
596
    return HA_ERR_WRONG_COMMAND;
 
597
  }
 
598
  /**
 
599
    Reset state of file to after 'open'.
 
600
    This function is called after every statement for all tables used
 
601
    by that statement.
 
602
  */
 
603
  virtual int reset() { return 0; }
 
604
 
 
605
  /**
 
606
    Is not invoked for non-transactional temporary tables.
 
607
 
 
608
    Tells the storage engine that we intend to read or write data
 
609
    from the table. This call is prefixed with a call to Cursor::store_lock()
 
610
    and is invoked only for those Cursor instances that stored the lock.
 
611
 
 
612
    Calls to rnd_init/index_init are prefixed with this call. When table
 
613
    IO is complete, we call external_lock(F_UNLCK).
 
614
    A storage engine writer should expect that each call to
 
615
    ::external_lock(F_[RD|WR]LOCK is followed by a call to
 
616
    ::external_lock(F_UNLCK). If it is not, it is a bug in MySQL.
 
617
 
 
618
    The name and signature originate from the first implementation
 
619
    in MyISAM, which would call fcntl to set/clear an advisory
 
620
    lock on the data file in this method.
 
621
 
 
622
    @param   lock_type    F_RDLCK, F_WRLCK, F_UNLCK
 
623
 
 
624
    @return  non-0 in case of failure, 0 in case of success.
 
625
    When lock_type is F_UNLCK, the return value is ignored.
 
626
  */
 
627
  virtual int external_lock(Session *, int)
 
628
  {
 
629
    return 0;
 
630
  }
 
631
  virtual void release_auto_increment(void) { return; };
 
632
  /** admin commands - called from mysql_admin_table */
 
633
  virtual int check(Session *)
 
634
  { return HA_ADMIN_NOT_IMPLEMENTED; }
 
635
 
 
636
  virtual void start_bulk_insert(ha_rows)
 
637
  {}
 
638
  virtual int end_bulk_insert(void) { return 0; }
 
639
  virtual int index_read(unsigned char *, const unsigned char *,
 
640
                         uint32_t, enum ha_rkey_function)
 
641
   { return  HA_ERR_WRONG_COMMAND; }
 
642
  virtual int index_read_last(unsigned char *, const unsigned char *, uint32_t)
 
643
   { return (errno= HA_ERR_WRONG_COMMAND); }
 
644
  /**
 
645
    This is called to delete all rows in a table
 
646
    If the Cursor don't support this, then this function will
 
647
    return HA_ERR_WRONG_COMMAND and MySQL will delete the rows one
 
648
    by one.
 
649
  */
 
650
  virtual int delete_all_rows(void)
 
651
  { return (errno=HA_ERR_WRONG_COMMAND); }
 
652
  /**
 
653
    Reset the auto-increment counter to the given value, i.e. the next row
 
654
    inserted will get the given value. This is called e.g. after TRUNCATE
 
655
    is emulated by doing a 'DELETE FROM t'. HA_ERR_WRONG_COMMAND is
 
656
    returned by storage engines that don't support this operation.
 
657
  */
 
658
  virtual int reset_auto_increment(uint64_t)
 
659
  { return HA_ERR_WRONG_COMMAND; }
 
660
 
 
661
  virtual int analyze(Session *)
 
662
  { return HA_ADMIN_NOT_IMPLEMENTED; }
 
663
 
 
664
  virtual int disable_indexes(uint32_t)
 
665
  { return HA_ERR_WRONG_COMMAND; }
 
666
 
 
667
  virtual int enable_indexes(uint32_t)
 
668
  { return HA_ERR_WRONG_COMMAND; }
 
669
 
 
670
  virtual int discard_or_import_tablespace(bool)
 
671
  { return (errno=HA_ERR_WRONG_COMMAND); }
 
672
 
 
673
  /* 
 
674
    @todo this is just for the HEAP engine, it should
 
675
    be removed at some point in the future (and
 
676
    no new engine should ever use it). Right
 
677
    now HEAP does rely on it, so we cannot remove it.
 
678
  */
 
679
  virtual void drop_table(const char *name);
 
680
};
 
681
 
 
682
extern const char *ha_row_type[];
 
683
 
 
684
/* basic stuff */
 
685
int ha_init_errors(void);
 
686
int ha_end(void);
 
687
 
 
688
SORT_FIELD * make_unireg_sortorder(order_st *order, uint32_t *length,
 
689
                                   SORT_FIELD *sortorder);
 
690
int setup_order(Session *session, Item **ref_pointer_array, TableList *tables,
 
691
                List<Item> &fields, List <Item> &all_fields, order_st *order);
 
692
int setup_group(Session *session, Item **ref_pointer_array, TableList *tables,
 
693
                List<Item> &fields, List<Item> &all_fields, order_st *order,
 
694
                bool *hidden_group_fields);
 
695
bool fix_inner_refs(Session *session, List<Item> &all_fields, Select_Lex *select,
 
696
                    Item **ref_pointer_array);
 
697
 
 
698
bool handle_select(Session *session, LEX *lex, select_result *result,
 
699
                   uint64_t setup_tables_done_option);
 
700
void free_underlaid_joins(Session *session, Select_Lex *select);
 
701
 
 
702
bool mysql_handle_derived(LEX *lex, bool (*processor)(Session *session,
 
703
                                                      LEX *lex,
 
704
                                                      TableList *table));
 
705
bool mysql_derived_prepare(Session *session, LEX *lex, TableList *t);
 
706
bool mysql_derived_filling(Session *session, LEX *lex, TableList *t);
 
707
int prepare_create_field(CreateField *sql_field,
 
708
                         uint32_t *blob_columns,
 
709
                         int *timestamps, int *timestamps_with_niladic);
 
710
 
 
711
bool mysql_create_table(Session *session,
 
712
                        TableIdentifier &identifier,
 
713
                        HA_CREATE_INFO *create_info,
 
714
                        message::Table &table_proto,
 
715
                        AlterInfo *alter_info,
 
716
                        bool tmp_table, uint32_t select_field_count,
 
717
                        bool is_if_not_exists);
 
718
 
 
719
bool mysql_create_table_no_lock(Session *session,
 
720
                                TableIdentifier &identifier,
 
721
                                HA_CREATE_INFO *create_info,
 
722
                                message::Table &table_proto,
 
723
                                AlterInfo *alter_info,
 
724
                                bool tmp_table,
 
725
                                uint32_t select_field_count,
 
726
                                bool is_if_not_exists);
 
727
 
 
728
bool mysql_create_like_table(Session* session,
 
729
                             TableIdentifier &destination_identifier,
 
730
                             TableList* table, TableList* src_table,
 
731
                             message::Table &create_table_proto,
 
732
                             bool is_if_not_exists,
 
733
                             bool is_engine_set);
 
734
 
 
735
bool mysql_rename_table(plugin::StorageEngine *base, const char *old_db,
 
736
                        const char * old_name, const char *new_db,
 
737
                        const char * new_name, uint32_t flags);
 
738
 
 
739
bool mysql_prepare_update(Session *session, TableList *table_list,
 
740
                          Item **conds, uint32_t order_num, order_st *order);
 
741
int mysql_update(Session *session,TableList *tables,List<Item> &fields,
 
742
                 List<Item> &values,COND *conds,
 
743
                 uint32_t order_num, order_st *order, ha_rows limit,
 
744
                 enum enum_duplicates handle_duplicates, bool ignore);
 
745
bool mysql_prepare_insert(Session *session, TableList *table_list, Table *table,
 
746
                          List<Item> &fields, List_item *values,
 
747
                          List<Item> &update_fields,
 
748
                          List<Item> &update_values, enum_duplicates duplic,
 
749
                          COND **where, bool select_insert,
 
750
                          bool check_fields, bool abort_on_warning);
 
751
bool mysql_insert(Session *session,TableList *table,List<Item> &fields,
 
752
                  List<List_item> &values, List<Item> &update_fields,
 
753
                  List<Item> &update_values, enum_duplicates flag,
 
754
                  bool ignore);
 
755
int check_that_all_fields_are_given_values(Session *session, Table *entry,
 
756
                                           TableList *table_list);
 
757
int mysql_prepare_delete(Session *session, TableList *table_list, Item **conds);
 
758
bool mysql_delete(Session *session, TableList *table_list, COND *conds,
 
759
                  SQL_LIST *order, ha_rows rows, uint64_t options,
 
760
                  bool reset_auto_increment);
 
761
bool mysql_truncate(Session& session, TableList *table_list);
 
762
TableShare *get_table_share(Session *session, TableList *table_list, char *key,
 
763
                             uint32_t key_length, uint32_t db_flags, int *error);
 
764
TableShare *get_cached_table_share(const char *db, const char *table_name);
 
765
bool reopen_name_locked_table(Session* session, TableList* table_list, bool link_in);
 
766
Table *table_cache_insert_placeholder(Session *session, const char *key,
 
767
                                      uint32_t key_length);
 
768
bool lock_table_name_if_not_cached(Session *session, const char *db,
 
769
                                   const char *table_name, Table **table);
 
770
bool reopen_table(Table *table);
 
771
bool reopen_tables(Session *session,bool get_locks,bool in_refresh);
 
772
void close_data_files_and_morph_locks(Session *session, const char *db,
 
773
                                      const char *table_name);
 
774
void close_handle_and_leave_table_as_lock(Table *table);
 
775
bool wait_for_tables(Session *session);
 
776
bool table_is_used(Table *table, bool wait_for_name_lock);
 
777
Table *drop_locked_tables(Session *session,const char *db, const char *table_name);
 
778
void abort_locked_tables(Session *session,const char *db, const char *table_name);
 
779
extern Field *not_found_field;
 
780
extern Field *view_ref_found;
 
781
 
 
782
Field *
 
783
find_field_in_tables(Session *session, Item_ident *item,
 
784
                     TableList *first_table, TableList *last_table,
 
785
                     Item **ref, find_item_error_report_type report_error,
 
786
                     bool register_tree_change);
 
787
Field *
 
788
find_field_in_table_ref(Session *session, TableList *table_list,
 
789
                        const char *name, uint32_t length,
 
790
                        const char *item_name, const char *db_name,
 
791
                        const char *table_name, Item **ref,
 
792
                        bool allow_rowid,
 
793
                        uint32_t *cached_field_index_ptr,
 
794
                        bool register_tree_change, TableList **actual_table);
 
795
Field *
 
796
find_field_in_table(Session *session, Table *table, const char *name, uint32_t length,
 
797
                    bool allow_rowid, uint32_t *cached_field_index_ptr);
 
798
 
 
799
} /* namespace drizzled */
 
800
 
 
801
#endif /* DRIZZLED_CURSOR_H */