ha_ndbcluster.h 18.8 KB
Newer Older
1 2 3 4
/* Copyright (C) 2000-2003 MySQL AB

   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
5
   the Free Software Foundation; version 2 of the License.
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22

   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.

   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 */

/*
  This file defines the NDB Cluster handler: the interface between MySQL and
  NDB Cluster
*/

/* The class defining a handle to an NDB Cluster table */

23
#ifdef USE_PRAGMA_INTERFACE
24 25 26
#pragma interface                       /* gcc class implementation */
#endif

27 28 29
/* Blob tables and events are internal to NDB and must never be accessed */
#define IS_NDB_BLOB_PREFIX(A) is_prefix(A, "NDB$BLOB")

30
#include <NdbApi.hpp>
31 32
#include <ndbapi_limits.h>

33 34
#define NDB_HIDDEN_PRIMARY_KEY_LENGTH 8

35 36
class Ndb;             // Forward declaration
class NdbOperation;    // Forward declaration
37
class NdbTransaction;  // Forward declaration
38
class NdbRecAttr;      // Forward declaration
joreland@mysql.com's avatar
joreland@mysql.com committed
39 40
class NdbScanOperation; 
class NdbIndexScanOperation; 
pekka@mysql.com's avatar
pekka@mysql.com committed
41
class NdbBlob;
42
class NdbIndexStat;
43
class NdbEventOperation;
44
class ha_ndbcluster_cond;
45

46 47
// connectstring to cluster if given by mysqld
extern const char *ndbcluster_connectstring;
48
extern ulong ndb_cache_check_time;
tomas@poseidon.ndb.mysql.com's avatar
tomas@poseidon.ndb.mysql.com committed
49
#ifdef HAVE_NDB_BINLOG
50 51
extern ulong ndb_report_thresh_binlog_epoch_slip;
extern ulong ndb_report_thresh_binlog_mem_usage;
tomas@poseidon.ndb.mysql.com's avatar
tomas@poseidon.ndb.mysql.com committed
52
#endif
53

54 55 56
typedef enum ndb_index_type {
  UNDEFINED_INDEX = 0,
  PRIMARY_KEY_INDEX = 1,
57 58 59 60
  PRIMARY_KEY_ORDERED_INDEX = 2,
  UNIQUE_INDEX = 3,
  UNIQUE_ORDERED_INDEX = 4,
  ORDERED_INDEX = 5
61 62
} NDB_INDEX_TYPE;

63 64
typedef enum ndb_index_status {
  UNDEFINED = 0,
65 66
  ACTIVE = 1,
  TO_BE_DROPPED = 2
67 68
} NDB_INDEX_STATUS;

69 70
typedef struct ndb_index_data {
  NDB_INDEX_TYPE type;
71
  NDB_INDEX_STATUS status;  
72 73
  const NdbDictionary::Index *index;
  const NdbDictionary::Index *unique_index;
74
  unsigned char *unique_index_attrid_map;
75
  bool null_in_unique_index;
76 77 78 79 80 81
  // In this version stats are not shared between threads
  NdbIndexStat* index_stat;
  uint index_stat_cache_entries;
  // Simple counter mechanism to decide when to connect to db
  uint index_stat_update_freq;
  uint index_stat_query_count;
82
} NDB_INDEX_DATA;
83

84 85
typedef union { const NdbRecAttr *rec; NdbBlob *blob; void *ptr; } NdbValue;

86 87 88 89
int get_ndb_blobs_value(TABLE* table, NdbValue* value_array,
                        byte*& buffer, uint& buffer_size,
                        my_ptrdiff_t ptrdiff);

90 91
typedef enum {
  NSS_INITIAL= 0,
92 93
  NSS_DROPPED,
  NSS_ALTERED 
94 95
} NDB_SHARE_STATE;

96
typedef struct st_ndbcluster_share {
97
  NDB_SHARE_STATE state;
98
  MEM_ROOT mem_root;
99 100
  THR_LOCK lock;
  pthread_mutex_t mutex;
101 102 103 104
  char *key;
  uint key_length;
  THD *util_lock;
  uint use_count;
105
  uint commit_count_lock;
106
  ulonglong commit_count;
107 108
  char *db;
  char *table_name;
109
  Ndb::TupleIdRange tuple_id_range;
tomas@poseidon.ndb.mysql.com's avatar
tomas@poseidon.ndb.mysql.com committed
110
#ifdef HAVE_NDB_BINLOG
111
  uint32 connect_count;
tomas@poseidon.ndb.mysql.com's avatar
tomas@poseidon.ndb.mysql.com committed
112 113 114 115 116 117
  uint32 flags;
  NdbEventOperation *op;
  NdbEventOperation *op_old; // for rename table
  char *old_names; // for rename table
  TABLE_SHARE *table_share;
  TABLE *table;
118
  byte *record[2]; // pointer to allocated records for receiving data
tomas@poseidon.ndb.mysql.com's avatar
tomas@poseidon.ndb.mysql.com committed
119 120 121
  NdbValue *ndb_value[2];
  MY_BITMAP *subscriber_bitmap;
#endif
122 123
} NDB_SHARE;

124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143
inline
NDB_SHARE_STATE
get_ndb_share_state(NDB_SHARE *share)
{
  NDB_SHARE_STATE state;
  pthread_mutex_lock(&share->mutex);
  state= share->state;
  pthread_mutex_unlock(&share->mutex);
  return state;
}

inline
void
set_ndb_share_state(NDB_SHARE *share, NDB_SHARE_STATE state)
{
  pthread_mutex_lock(&share->mutex);
  share->state= state;
  pthread_mutex_unlock(&share->mutex);
}

144 145 146 147 148 149 150 151 152 153 154 155 156
struct Ndb_tuple_id_range_guard {
  Ndb_tuple_id_range_guard(NDB_SHARE* _share) :
    share(_share),
    range(share->tuple_id_range) {
    pthread_mutex_lock(&share->mutex);
  }
  ~Ndb_tuple_id_range_guard() {
    pthread_mutex_unlock(&share->mutex);
  }
  NDB_SHARE* share;
  Ndb::TupleIdRange& range;
};

tomas@poseidon.ndb.mysql.com's avatar
tomas@poseidon.ndb.mysql.com committed
157 158 159
#ifdef HAVE_NDB_BINLOG
/* NDB_SHARE.flags */
#define NSF_HIDDEN_PK 1 /* table has hidden primary key */
160
#define NSF_BLOB_FLAG 2 /* table has blob attributes */
161
#define NSF_NO_BINLOG 4 /* table should not be binlogged */
tomas@poseidon.ndb.mysql.com's avatar
tomas@poseidon.ndb.mysql.com committed
162 163
#endif

164 165 166 167 168
typedef enum ndb_query_state_bits {
  NDB_QUERY_NORMAL = 0,
  NDB_QUERY_MULTI_READ_RANGE = 1
} NDB_QUERY_STATE_BITS;

169 170 171 172
/*
  Place holder for ha_ndbcluster thread specific data
*/

tomas@poseidon.ndb.mysql.com's avatar
tomas@poseidon.ndb.mysql.com committed
173 174 175 176 177
enum THD_NDB_OPTIONS
{
  TNO_NO_LOG_SCHEMA_OP= 1 << 0
};

178 179 180 181 182
enum THD_NDB_TRANS_OPTIONS
{
  TNTO_INJECTED_APPLY_STATUS= 1 << 0
};

183 184 185 186 187 188 189 190 191 192 193
struct Ndb_local_table_statistics {
  int no_uncommitted_rows_count;
  ulong last_count;
  ha_rows records;
};

typedef struct st_thd_ndb_share {
  const void *key;
  struct Ndb_local_table_statistics stat;
} THD_NDB_SHARE;

194 195
class Thd_ndb 
{
196 197 198
 public:
  Thd_ndb();
  ~Thd_ndb();
199 200 201 202

  void init_open_tables();
  THD_NDB_SHARE *get_open_table(THD *thd, const void *key);

203 204 205
  Ndb *ndb;
  ulong count;
  uint lock_count;
206 207
  NdbTransaction *all;
  NdbTransaction *stmt;
208 209
  bool m_error;
  bool m_slow_path;
tomas@poseidon.ndb.mysql.com's avatar
tomas@poseidon.ndb.mysql.com committed
210
  uint32 options;
211
  uint32 trans_options;
212
  List<NDB_SHARE> changed_tables;
213
  uint query_state;
214
  HASH open_tables;
215 216
};

217 218 219
class ha_ndbcluster: public handler
{
 public:
220
  ha_ndbcluster(handlerton *hton, TABLE_SHARE *table);
221 222
  ~ha_ndbcluster();

223
  int ha_initialise();
224 225 226 227 228 229
  int open(const char *name, int mode, uint test_if_locked);
  int close(void);

  int write_row(byte *buf);
  int update_row(const byte *old_data, byte *new_data);
  int delete_row(const byte *buf);
230
  int index_init(uint index, bool sorted);
231 232
  int index_end();
  int index_read(byte *buf, const byte *key, uint key_len, 
233
                 enum ha_rkey_function find_flag);
234 235 236 237
  int index_next(byte *buf);
  int index_prev(byte *buf);
  int index_first(byte *buf);
  int index_last(byte *buf);
238
  int index_read_last(byte * buf, const byte * key, uint key_len);
239
  int rnd_init(bool scan);
240 241 242 243
  int rnd_end();
  int rnd_next(byte *buf);
  int rnd_pos(byte *buf, byte *pos);
  void position(const byte *record);
244
  int read_range_first(const key_range *start_key,
245 246
                       const key_range *end_key,
                       bool eq_range, bool sorted);
247
  int read_range_first_to_buf(const key_range *start_key,
248 249 250
                              const key_range *end_key,
                              bool eq_range, bool sorted,
                              byte* buf);
251
  int read_range_next();
252
  int alter_tablespace(st_alter_tablespace *info);
253

254 255 256
  /**
   * Multi range stuff
   */
257
  int read_multi_range_first(KEY_MULTI_RANGE **found_range_p,
258 259
                             KEY_MULTI_RANGE*ranges, uint range_count,
                             bool sorted, HANDLER_BUFFER *buffer);
260
  int read_multi_range_next(KEY_MULTI_RANGE **found_range_p);
261 262 263
  bool null_value_index_search(KEY_MULTI_RANGE *ranges,
			       KEY_MULTI_RANGE *end_range,
			       HANDLER_BUFFER *buffer);
264

265
  bool get_error_message(int error, String *buf);
266
  ha_rows records();
267 268
  ha_rows estimate_rows_upper_bound()
    { return HA_POS_ERROR; }
269
  int info(uint);
270
  void get_dynamic_partition_info(PARTITION_INFO *stat_info, uint part_id);
271 272
  int extra(enum ha_extra_function operation);
  int extra_opt(enum ha_extra_function operation, ulong cache_size);
273
  int reset();
274
  int external_lock(THD *thd, int lock_type);
275
  void unlock_row();
serg@serg.mylan's avatar
serg@serg.mylan committed
276
  int start_stmt(THD *thd, thr_lock_type lock_type);
277
  void print_error(int error, myf errflag);
278
  const char * table_type() const;
279
  const char ** bas_ext() const;
280
  ulonglong table_flags(void) const;
281
  void prepare_for_alter();
282 283 284
  int add_index(TABLE *table_arg, KEY *key_info, uint num_of_keys);
  int prepare_drop_index(TABLE *table_arg, uint *key_num, uint num_of_keys);
  int final_drop_index(TABLE *table_arg);
285
  void set_part_info(partition_info *part_info);
286
  ulong index_flags(uint idx, uint part, bool all_parts) const;
287 288 289 290
  uint max_supported_record_length() const;
  uint max_supported_keys() const;
  uint max_supported_key_parts() const;
  uint max_supported_key_length() const;
pekka@mysql.com's avatar
pekka@mysql.com committed
291
  uint max_supported_key_part_length() const;
292 293 294 295

  int rename_table(const char *from, const char *to);
  int delete_table(const char *name);
  int create(const char *name, TABLE *form, HA_CREATE_INFO *info);
296
  int create_handler_files(const char *file, const char *old_name,
297
                           int action_flag, HA_CREATE_INFO *info);
298
  int get_default_no_partitions(HA_CREATE_INFO *info);
299 300
  bool get_no_parts(const char *name, uint *no_parts);
  void set_auto_partitions(partition_info *part_info);
301
  virtual bool is_fatal_error(int error, uint flags)
302
  {
303 304
    if (!handler::is_fatal_error(error, flags) ||
        error == HA_ERR_NO_PARTITION_FOUND)
305 306 307
      return FALSE;
    return TRUE;
  }
308

309
  THR_LOCK_DATA **store_lock(THD *thd,
310 311
                             THR_LOCK_DATA **to,
                             enum thr_lock_type lock_type);
312

313
  bool low_byte_first() const;
tomas@poseidon.ndb.mysql.com's avatar
tomas@poseidon.ndb.mysql.com committed
314

315
  const char* index_type(uint key_number);
316 317

  double scan_time();
318
  ha_rows records_in_range(uint inx, key_range *min_key, key_range *max_key);
319 320
  void start_bulk_insert(ha_rows rows);
  int end_bulk_insert();
321

322 323
  static Thd_ndb* seize_thd_ndb();
  static void release_thd_ndb(Thd_ndb* thd_ndb);
324
 
mskold@mysql.com's avatar
Merge  
mskold@mysql.com committed
325 326 327
static void set_dbname(const char *pathname, char *dbname);
static void set_tabname(const char *pathname, char *tabname);

328 329 330
  /*
    Condition pushdown
  */
331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348

 /*
   Push condition down to the table handler.
   SYNOPSIS
     cond_push()
     cond   Condition to be pushed. The condition tree must not be
     modified by the by the caller.
   RETURN
     The 'remainder' condition that caller must use to filter out records.
     NULL means the handler will not return rows that do not match the
     passed condition.
   NOTES
   The pushed conditions form a stack (from which one can remove the
   last pushed condition using cond_pop).
   The table handler filters out rows using (pushed_cond1 AND pushed_cond2 
   AND ... AND pushed_condN)
   or less restrictive condition, depending on handler's capabilities.
   
349
   handler->reset() call empties the condition stack.
350 351 352 353 354 355 356 357
   Calls to rnd_init/rnd_end, index_init/index_end etc do not affect the  
   condition stack.
   The current implementation supports arbitrary AND/OR nested conditions
   with comparisons between columns and constants (including constant
   expressions and function calls) and the following comparison operators:
   =, !=, >, >=, <, <=, like, "not like", "is null", and "is not null". 
   Negated conditions are supported by NOT which generate NAND/NOR groups.
 */ 
358
  const COND *cond_push(const COND *cond);
359 360 361 362 363 364
 /*
   Pop the top condition from the condition stack of the handler instance.
   SYNOPSIS
     cond_pop()
     Pops the top if condition stack, if stack is not empty
 */
365 366
  void cond_pop();

367
  uint8 table_cache_type();
368 369 370 371

  /*
   * Internal to ha_ndbcluster, used by C functions
   */
372
  int ndb_err(NdbTransaction*);
373

374
  my_bool register_query_cache_table(THD *thd, char *table_key,
375 376 377
                                     uint key_length,
                                     qc_engine_callback *engine_callback,
                                     ulonglong *engine_data);
378

379 380
  bool check_if_incompatible_data(HA_CREATE_INFO *info,
				  uint table_changes);
381

382
private:
383
  friend int ndbcluster_drop_database_impl(const char *path);
384 385 386 387
  friend int ndb_handle_schema_change(THD *thd, 
                                      Ndb *ndb, NdbEventOperation *pOp,
                                      NDB_SHARE *share);

388 389 390 391
  static int delete_table(ha_ndbcluster *h, Ndb *ndb,
			  const char *path,
			  const char *db,
			  const char *table_name);
392
  int create_ndb_index(const char *name, KEY *key_info, bool unique);
393 394
  int create_ordered_index(const char *name, KEY *key_info);
  int create_unique_index(const char *name, KEY *key_info);
395 396 397 398
  int create_index(const char *name, KEY *key_info, 
                   NDB_INDEX_TYPE idx_type, uint idx_no);
// Index list management
  int create_indexes(Ndb *ndb, TABLE *tab);
399
  int open_indexes(Ndb *ndb, TABLE *tab, bool ignore_error);
400
  void renumber_indexes(Ndb *ndb, TABLE *tab);
401 402 403
  int drop_indexes(Ndb *ndb, TABLE *tab);
  int add_index_handle(THD *thd, NdbDictionary::Dictionary *dict,
                       KEY *key_info, const char *index_name, uint index_no);
404
  int get_metadata(const char* path);
405
  void release_metadata(THD *thd, Ndb *ndb);
406 407
  NDB_INDEX_TYPE get_index_type(uint idx_no) const;
  NDB_INDEX_TYPE get_index_type_from_table(uint index_no) const;
408 409
  NDB_INDEX_TYPE get_index_type_from_key(uint index_no, KEY *key_info, 
                                         bool primary) const;
410 411
  bool has_null_in_unique_index(uint idx_no) const;
  bool check_index_fields_not_null(KEY *key_info);
412

413 414 415
  uint set_up_partition_info(partition_info *part_info,
                             TABLE *table,
                             void *tab);
416
  char* get_tablespace_name(THD *thd, char *name, uint name_len);
417 418
  int set_range_data(void *tab, partition_info* part_info);
  int set_list_data(void *tab, partition_info* part_info);
419 420
  int complemented_read(const byte *old_data, byte *new_data,
                        uint32 old_part_id);
421
  int pk_read(const byte *key, uint key_len, byte *buf, uint32 part_id);
422
  int ordered_index_scan(const key_range *start_key,
423
                         const key_range *end_key,
424 425
                         bool sorted, bool descending, byte* buf,
                         part_id_range *part_spec);
426 427 428 429 430 431
  int unique_index_read(const byte *key, uint key_len, 
                        byte *buf);
  int unique_index_scan(const KEY* key_info, 
			const byte *key, 
			uint key_len,
			byte *buf);
432
  int full_table_scan(byte * buf);
433

434 435 436 437
  bool check_all_operations_for_error(NdbTransaction *trans,
                                      const NdbOperation *first,
                                      const NdbOperation *last,
                                      uint errcode);
438
  int peek_indexed_rows(const byte *record, bool check_pk);
439
  int fetch_next(NdbScanOperation* op);
440
  int next_result(byte *buf); 
441
  int define_read_attrs(byte* buf, NdbOperation* op);
442
  int filtered_scan(const byte *key, uint key_len, 
443 444
                    byte *buf,
                    enum ha_rkey_function find_flag);
445
  int close_scan();
446
  void unpack_record(byte *buf);
pekka@mysql.com's avatar
pekka@mysql.com committed
447
  int get_ndb_lock_type(enum thr_lock_type type);
448 449 450 451 452

  void set_dbname(const char *pathname);
  void set_tabname(const char *pathname);

  bool set_hidden_key(NdbOperation*,
453
                      uint fieldnr, const byte* field_ptr);
454
  int set_ndb_key(NdbOperation*, Field *field,
455
                  uint fieldnr, const byte* field_ptr);
456 457
  int set_ndb_value(NdbOperation*, Field *field, uint fieldnr,
		    int row_offset= 0, bool *set_blob_value= 0);
joreland@mysql.com's avatar
joreland@mysql.com committed
458
  int get_ndb_value(NdbOperation*, Field *field, uint fieldnr, byte*);
knielsen@mysql.com's avatar
knielsen@mysql.com committed
459
  int get_ndb_partition_id(NdbOperation *);
460
  friend int g_get_ndb_blobs_value(NdbBlob *ndb_blob, void *arg);
461
  int set_primary_key(NdbOperation *op, const byte *key);
462
  int set_primary_key_from_record(NdbOperation *op, const byte *record);
463 464
  int set_index_key_from_record(NdbOperation *op, const byte *record,
                                uint keyno);
465 466
  int set_bounds(NdbIndexScanOperation*, uint inx, bool rir,
                 const key_range *keys[2], uint= 0);
467
  int key_cmp(uint keynr, const byte * old_row, const byte * new_row);
468
  int set_index_key(NdbOperation *, const KEY *key_info, const byte *key_ptr);
469 470
  void print_results();

471 472 473 474
  virtual void get_auto_increment(ulonglong offset, ulonglong increment,
                                  ulonglong nb_desired_values,
                                  ulonglong *first_value,
                                  ulonglong *nb_reserved_values);
475
  bool uses_blob_value();
476

mskold@mysql.com's avatar
mskold@mysql.com committed
477 478
  char *update_table_comment(const char * comment);

479
  int write_ndb_file(const char *name);
480

481
  int check_ndb_connection(THD* thd= current_thd);
482

483
  void set_rec_per_key();
484
  int records_update();
485 486 487 488
  void no_uncommitted_rows_execute_failure();
  void no_uncommitted_rows_update(int);
  void no_uncommitted_rows_reset(THD *);

489 490
  void release_completed_operations(NdbTransaction*, bool);

491
  friend int execute_commit(ha_ndbcluster*, NdbTransaction*);
492
  friend int execute_no_commit_ignore_no_key(ha_ndbcluster*, NdbTransaction*);
493 494
  friend int execute_no_commit(ha_ndbcluster*, NdbTransaction*, bool);
  friend int execute_no_commit_ie(ha_ndbcluster*, NdbTransaction*, bool);
495

496
  NdbTransaction *m_active_trans;
497
  NdbScanOperation *m_active_cursor;
498
  const NdbDictionary::Table *m_table;
499
  struct Ndb_local_table_statistics *m_table_info;
500 501 502
  char m_dbname[FN_HEADLEN];
  //char m_schemaname[FN_HEADLEN];
  char m_tabname[FN_HEADLEN];
monty@mysql.com's avatar
monty@mysql.com committed
503
  ulonglong m_table_flags;
504
  THR_LOCK_DATA m_lock;
505
  bool m_lock_tuple;
506
  NDB_SHARE *m_share;
507
  NDB_INDEX_DATA  m_index[MAX_KEY];
508
  THD_NDB_SHARE *m_thd_ndb_share;
pekka@mysql.com's avatar
pekka@mysql.com committed
509 510
  // NdbRecAttr has no reference to blob
  NdbValue m_value[NDB_MAX_ATTRIBUTES_IN_TABLE];
511
  byte m_ref[NDB_HIDDEN_PRIMARY_KEY_LENGTH];
512
  partition_info *m_part_info;
513
  uint32 m_part_id;
514 515 516 517
  byte *m_rec0;
  Field **m_part_field_array;
  bool m_use_partition_function;
  bool m_sorted;
518
  bool m_use_write;
519
  bool m_ignore_dup_key;
520
  bool m_has_unique_index;
521
  bool m_primary_key_update;
522
  bool m_write_op;
523
  bool m_ignore_no_key;
524
  ha_rows m_rows_to_insert; // TODO: merge it with handler::estimation_rows_to_insert?
525 526
  ha_rows m_rows_inserted;
  ha_rows m_bulk_insert_rows;
527
  ha_rows m_rows_changed;
528
  bool m_bulk_insert_not_flushed;
529 530
  bool m_delete_cannot_batch;
  bool m_update_cannot_batch;
531 532 533
  ha_rows m_ops_pending;
  bool m_skip_auto_increment;
  bool m_blobs_pending;
534
  bool m_slow_path;
535
  my_ptrdiff_t m_blobs_offset;
pekka@mysql.com's avatar
pekka@mysql.com committed
536
  // memory for blobs in one tuple
537 538 539
  char *m_blobs_buffer;
  uint32 m_blobs_buffer_size;
  uint m_dupkey;
540
  // set from thread variables at external lock
541 542 543 544
  bool m_ha_not_exact_count;
  bool m_force_send;
  ha_rows m_autoincrement_prefetch;
  bool m_transaction_on;
545

546
  ha_ndbcluster_cond *m_cond;
547
  bool m_disable_multi_read;
548
  byte *m_multi_range_result_ptr;
549 550
  KEY_MULTI_RANGE *m_multi_ranges;
  KEY_MULTI_RANGE *m_multi_range_defined;
551 552 553
  const NdbOperation *m_current_multi_operation;
  NdbIndexScanOperation *m_multi_cursor;
  byte *m_multi_range_cursor_result_ptr;
554
  int setup_recattr(const NdbRecAttr*);
555
  Ndb *get_ndb();
556 557
};

serg@serg.mylan's avatar
serg@serg.mylan committed
558
extern SHOW_VAR ndb_status_variables[];
559

560
int ndbcluster_discover(THD* thd, const char* dbname, const char* name,
561
                        const void** frmblob, uint* frmlen);
562
int ndbcluster_find_files(THD *thd,const char *db,const char *path,
563
                          const char *wild, bool dir, List<char> *files);
564 565
int ndbcluster_table_exists_in_engine(THD* thd,
                                      const char *db, const char *name);
566
void ndbcluster_print_error(int error, const NdbOperation *error_op);
567 568 569

static const char ndbcluster_hton_name[]= "ndbcluster";
static const int ndbcluster_hton_name_length=sizeof(ndbcluster_hton_name)-1;
570 571 572
extern int ndbcluster_terminating;
extern int ndb_util_thread_running;
extern pthread_cond_t COND_ndb_util_ready;