ha_ndbcluster.h 13.4 KB
Newer Older
unknown's avatar
unknown committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
/* 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
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.

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

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

#include <ndbapi_limits.h>

class Ndb;             // Forward declaration
class NdbOperation;    // Forward declaration
32
class NdbTransaction;  // Forward declaration
unknown's avatar
unknown committed
33
class NdbRecAttr;      // Forward declaration
unknown's avatar
unknown committed
34
class NdbScanOperation; 
35
class NdbScanFilter; 
unknown's avatar
unknown committed
36
class NdbIndexScanOperation; 
unknown's avatar
unknown committed
37
class NdbBlob;
unknown's avatar
unknown committed
38

39 40
// connectstring to cluster if given by mysqld
extern const char *ndbcluster_connectstring;
41

unknown's avatar
unknown committed
42 43 44
typedef enum ndb_index_type {
  UNDEFINED_INDEX = 0,
  PRIMARY_KEY_INDEX = 1,
45 46 47 48
  PRIMARY_KEY_ORDERED_INDEX = 2,
  UNIQUE_INDEX = 3,
  UNIQUE_ORDERED_INDEX = 4,
  ORDERED_INDEX = 5
unknown's avatar
unknown committed
49 50
} NDB_INDEX_TYPE;

51 52 53 54 55
typedef struct ndb_index_data {
  NDB_INDEX_TYPE type;
  void *index;
  void *unique_index;
} NDB_INDEX_DATA;
unknown's avatar
unknown committed
56 57 58 59 60 61 62 63

typedef struct st_ndbcluster_share {
  THR_LOCK lock;
  pthread_mutex_t mutex;
  char *table_name;
  uint table_name_length,use_count;
} NDB_SHARE;

64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
typedef enum ndb_item_type {
  NDB_VALUE = 0,   // Qualified more with Item::Type
  NDB_FIELD = 1,   // Qualified from table definition
  NDB_FUNCTION = 2 // Qualified from Item_func::Functype
} NDB_ITEM_TYPE;

typedef union ndb_item_qualification {
  Item::Type value_type; 
  enum_field_types field_type;       // Instead of Item::FIELD_ITEM
  Item_func::Functype function_type; // Instead of Item::FUNC_ITEM
} NDB_ITEM_QUALIFICATION;

class Ndb_item_string_value {
 public:
  String s;
  CHARSET_INFO *c;
};

typedef struct ndb_item_field_value {
  Field* field;
  int column_no;
} NDB_ITEM_FIELD_VALUE;

typedef union ndb_item_value {
  longlong int_value;
  double real_value;
  Ndb_item_string_value *string_value;
  NDB_ITEM_FIELD_VALUE *field_value;
} NDB_ITEM_VALUE;

class Ndb_item {
 public:
  Ndb_item(NDB_ITEM_TYPE item_type, 
	   NDB_ITEM_QUALIFICATION item_qualification,
	   const Item *item_value);
  Ndb_item(longlong int_value);
  Ndb_item(double real_value);
  Ndb_item();
  Ndb_item(Field *field, int column_no);
  Ndb_item(Item_func::Functype func_type);
  ~Ndb_item();
  void print(String *str);
106
  uint32 pack_length() { return value.field_value->field->pack_length(); };
107
  // Getters and Setters
108 109 110 111 112 113
  longlong get_int_value() { return value.int_value; };
  double get_real_value() { return value.real_value; };
  String * get_string_value() { return &value.string_value->s; };
  CHARSET_INFO * get_string_charset() { return value.string_value->c; };
  Field * get_field() { return value.field_value->field; };
  int get_field_no() { return value.field_value->column_no; };
114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203

 public:
  NDB_ITEM_TYPE type;
  NDB_ITEM_QUALIFICATION qualification;


 private:
  NDB_ITEM_VALUE value;

};

class Ndb_cond {
 public:
  Ndb_cond() : ndb_item(NULL), next(NULL), prev(NULL) {};
  ~Ndb_cond() 
  { 
    if (ndb_item) delete ndb_item; 
    ndb_item= NULL; 
    if (next) delete next;
    next= prev= NULL; 
  };
  Ndb_item *ndb_item;
  Ndb_cond *next;
  Ndb_cond *prev;
};

class Ndb_cond_stack {
 public:
  Ndb_cond_stack() : ndb_cond(NULL), next(NULL) {};
  ~Ndb_cond_stack() 
  { 
    if (ndb_cond) delete ndb_cond; 
    ndb_cond= NULL; 
    next= NULL; 
  };
  Ndb_cond *ndb_cond;
  Ndb_cond_stack *next;
};

class Ndb_cond_traverse_context {
 public:
  Ndb_cond_traverse_context(TABLE *tab, void* ndb_tab, 
			    bool *supported, Ndb_cond_stack* stack)
    : table(tab), ndb_table(ndb_tab), 
    supported_ptr(supported), stack_ptr(stack), cond_ptr(NULL),
    expect_mask(0), expect_field_result_mask(0)
  {
    if (stack)
      cond_ptr= stack->ndb_cond;
  };
  void expect(Item::Type type)
  {
    expect_mask|= (1 << type);
  };
  void dont_expect(Item::Type type)
  {
    expect_mask&= ~(1 << type);
  };
  bool expecting(Item::Type type)
  {
    return (expect_mask & (1 << type));
  };
  void expect_nothing()
  {
    expect_mask= 0;
  };

  void expect_field_result(Item_result result)
  {
    expect_field_result_mask|= (1 << result);
  };
  bool expecting_field_result(Item_result result)
  {
    return (expect_field_result_mask & (1 << result));
  };
  void expect_no_field_result()
  {
    expect_field_result_mask= 0;
  };

  TABLE* table;
  void* ndb_table;
  bool *supported_ptr;
  Ndb_cond_stack* stack_ptr;
  Ndb_cond* cond_ptr;
  private:
  uint expect_mask;
  uint expect_field_result_mask;
};

204 205 206 207 208 209 210 211 212 213 214
/*
  Place holder for ha_ndbcluster thread specific data
*/

class Thd_ndb {
 public:
  Thd_ndb();
  ~Thd_ndb();
  Ndb *ndb;
  ulong count;
  uint lock_count;
215
  int error;
216 217
};

unknown's avatar
unknown committed
218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239
class ha_ndbcluster: public handler
{
 public:
  ha_ndbcluster(TABLE *table);
  ~ha_ndbcluster();

  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);
  int index_init(uint index);
  int index_end();
  int index_read(byte *buf, const byte *key, uint key_len, 
		 enum ha_rkey_function find_flag);
  int index_read_idx(byte *buf, uint index, const byte *key, uint key_len, 
		     enum ha_rkey_function find_flag);
  int index_next(byte *buf);
  int index_prev(byte *buf);
  int index_first(byte *buf);
  int index_last(byte *buf);
240
  int index_read_last(byte * buf, const byte * key, uint key_len);
241
  int rnd_init(bool scan);
unknown's avatar
unknown committed
242 243 244 245
  int rnd_end();
  int rnd_next(byte *buf);
  int rnd_pos(byte *buf, byte *pos);
  void position(const byte *record);
246 247
  int read_range_first(const key_range *start_key,
		       const key_range *end_key,
248
		       bool eq_range, bool sorted);
249 250 251 252
  int read_range_first_to_buf(const key_range *start_key,
			      const key_range *end_key,
			      bool eq_range, bool sorted,
			      byte* buf);
253
  int read_range_next();
254

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

263
  bool get_error_message(int error, String *buf);
unknown's avatar
unknown committed
264 265 266 267 268
  void info(uint);
  int extra(enum ha_extra_function operation);
  int extra_opt(enum ha_extra_function operation, ulong cache_size);
  int external_lock(THD *thd, int lock_type);
  int start_stmt(THD *thd);
269
  const char * table_type() const;
unknown's avatar
unknown committed
270
  const char ** bas_ext() const;
271
  ulong table_flags(void) const;
272
  ulong index_flags(uint idx, uint part, bool all_parts) const;
273 274 275 276
  uint max_supported_record_length() const;
  uint max_supported_keys() const;
  uint max_supported_key_parts() const;
  uint max_supported_key_length() const;
unknown's avatar
unknown committed
277 278 279 280 281 282 283 284

  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);
  THR_LOCK_DATA **store_lock(THD *thd,
			     THR_LOCK_DATA **to,
			     enum thr_lock_type lock_type);

285 286 287
  bool low_byte_first() const;
  bool has_transactions();
  const char* index_type(uint key_number);
unknown's avatar
unknown committed
288 289

  double scan_time();
unknown's avatar
unknown committed
290
  ha_rows records_in_range(uint inx, key_range *min_key, key_range *max_key);
291 292
  void start_bulk_insert(ha_rows rows);
  int end_bulk_insert();
unknown's avatar
unknown committed
293

294 295
  static Thd_ndb* seize_thd_ndb();
  static void release_thd_ndb(Thd_ndb* thd_ndb);
296 297 298 299 300 301 302
 
  /*
    Condition pushdown
  */
  const COND *cond_push(const COND *cond);
  void cond_pop();

303
  uint8 table_cache_type();
unknown's avatar
unknown committed
304 305
    
 private:
306
  int alter_table_name(const char *to);
unknown's avatar
unknown committed
307
  int drop_table();
308 309 310
  int create_index(const char *name, KEY *key_info, bool unique);
  int create_ordered_index(const char *name, KEY *key_info);
  int create_unique_index(const char *name, KEY *key_info);
unknown's avatar
unknown committed
311
  int initialize_autoincrement(const void *table);
unknown's avatar
unknown committed
312 313
  enum ILBP {ILBP_CREATE = 0, ILBP_OPEN = 1}; // Index List Build Phase
  int build_index_list(TABLE *tab, enum ILBP phase);
unknown's avatar
unknown committed
314 315 316 317
  int get_metadata(const char* path);
  void release_metadata();
  NDB_INDEX_TYPE get_index_type(uint idx_no) const;
  NDB_INDEX_TYPE get_index_type_from_table(uint index_no) const;
318 319
  int check_index_fields_not_null(uint index_no);

320 321
  int pk_read(const byte *key, uint key_len, byte *buf);
  int complemented_pk_read(const byte *old_data, byte *new_data);
322
  int peek_row();
unknown's avatar
unknown committed
323 324
  int unique_index_read(const byte *key, uint key_len, 
			byte *buf);
325 326
  int ordered_index_scan(const key_range *start_key,
			 const key_range *end_key,
327
			 bool sorted, bool descending, byte* buf);
unknown's avatar
unknown committed
328
  int full_table_scan(byte * buf);
unknown's avatar
unknown committed
329
  int fetch_next(NdbScanOperation* op);
unknown's avatar
unknown committed
330
  int next_result(byte *buf); 
331
  int define_read_attrs(byte* buf, NdbOperation* op);
unknown's avatar
unknown committed
332 333 334
  int filtered_scan(const byte *key, uint key_len, 
		    byte *buf,
		    enum ha_rkey_function find_flag);
335
  int close_scan();
unknown's avatar
unknown committed
336
  void unpack_record(byte *buf);
unknown's avatar
unknown committed
337
  int get_ndb_lock_type(enum thr_lock_type type);
unknown's avatar
unknown committed
338 339 340 341 342 343 344 345 346

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

  bool set_hidden_key(NdbOperation*,
		      uint fieldnr, const byte* field_ptr);
  int set_ndb_key(NdbOperation*, Field *field,
		  uint fieldnr, const byte* field_ptr);
347
  int set_ndb_value(NdbOperation*, Field *field, uint fieldnr, bool *set_blob_value= 0);
unknown's avatar
unknown committed
348
  int get_ndb_value(NdbOperation*, Field *field, uint fieldnr, byte*);
unknown's avatar
unknown committed
349
  friend int g_get_ndb_blobs_value(NdbBlob *ndb_blob, void *arg);
unknown's avatar
unknown committed
350
  int get_ndb_blobs_value(NdbBlob *last_ndb_blob);
unknown's avatar
unknown committed
351 352
  int set_primary_key(NdbOperation *op, const byte *key);
  int set_primary_key(NdbOperation *op);
353
  int set_primary_key_from_old_data(NdbOperation *op, const byte *old_data);
354
  int set_bounds(NdbIndexScanOperation*, const key_range *keys[2], uint= 0);
unknown's avatar
unknown committed
355
  int key_cmp(uint keynr, const byte * old_row, const byte * new_row);
356
  int set_index_key(NdbOperation *, const KEY *key_info, const byte *key_ptr);
unknown's avatar
unknown committed
357 358
  void print_results();

359
  ulonglong get_auto_increment();
360
  int ndb_err(NdbTransaction*);
unknown's avatar
unknown committed
361
  bool uses_blob_value(bool all_fields);
unknown's avatar
unknown committed
362

363 364
  int write_ndb_file();

unknown's avatar
unknown committed
365 366
  int check_ndb_connection();

367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386
  void set_rec_per_key();
  void records_update();
  void no_uncommitted_rows_execute_failure();
  void no_uncommitted_rows_update(int);
  void no_uncommitted_rows_init(THD *);
  void no_uncommitted_rows_reset(THD *);

  /*
    Condition Pushdown to Handler (CPDH), private methods
  */
  void cond_clear();
  bool serialize_cond(const COND *cond, Ndb_cond_stack *ndb_cond);
  Ndb_cond * build_scan_filter_predicate(Ndb_cond* cond, 
					 NdbScanFilter* filter);
  Ndb_cond * build_scan_filter_group(Ndb_cond* cond, 
				     NdbScanFilter* filter);
  void build_scan_filter(Ndb_cond* cond, NdbScanFilter* filter);
  void generate_scan_filter(Ndb_cond_stack* cond_stack, 
			    NdbScanOperation* op);

unknown's avatar
unknown committed
387 388 389
  friend int execute_commit(ha_ndbcluster*, NdbTransaction*);
  friend int execute_no_commit(ha_ndbcluster*, NdbTransaction*);
  friend int execute_no_commit_ie(ha_ndbcluster*, NdbTransaction*);
390

391
  NdbTransaction *m_active_trans;
unknown's avatar
unknown committed
392
  NdbScanOperation *m_active_cursor;
393 394
  void *m_table;
  void *m_table_info;
unknown's avatar
unknown committed
395 396 397 398 399 400
  char m_dbname[FN_HEADLEN];
  //char m_schemaname[FN_HEADLEN];
  char m_tabname[FN_HEADLEN];
  ulong m_table_flags;
  THR_LOCK_DATA m_lock;
  NDB_SHARE *m_share;
401
  NDB_INDEX_DATA  m_index[MAX_KEY];
unknown's avatar
unknown committed
402
  // NdbRecAttr has no reference to blob
403
  typedef union { const NdbRecAttr *rec; NdbBlob *blob; void *ptr; } NdbValue;
unknown's avatar
unknown committed
404
  NdbValue m_value[NDB_MAX_ATTRIBUTES_IN_TABLE];
unknown's avatar
unknown committed
405
  bool m_use_write;
406
  bool m_ignore_dup_key;
407 408
  bool m_primary_key_update;
  bool m_retrieve_all_fields;
409
  bool m_retrieve_primary_key;
410 411 412 413 414 415 416
  ha_rows m_rows_to_insert;
  ha_rows m_rows_inserted;
  ha_rows m_bulk_insert_rows;
  bool m_bulk_insert_not_flushed;
  ha_rows m_ops_pending;
  bool m_skip_auto_increment;
  bool m_blobs_pending;
unknown's avatar
unknown committed
417
  // memory for blobs in one tuple
418 419 420
  char *m_blobs_buffer;
  uint32 m_blobs_buffer_size;
  uint m_dupkey;
unknown's avatar
unknown committed
421
  // set from thread variables at external lock
422 423 424 425
  bool m_ha_not_exact_count;
  bool m_force_send;
  ha_rows m_autoincrement_prefetch;
  bool m_transaction_on;
unknown's avatar
unknown committed
426
  bool m_use_local_query_cache;
427
  Ndb_cond_stack *m_cond_stack;
428
  bool m_disable_multi_read;
unknown's avatar
unknown committed
429
  byte *m_multi_range_result_ptr;
430 431
  KEY_MULTI_RANGE *m_multi_ranges;
  KEY_MULTI_RANGE *m_multi_range_defined;
unknown's avatar
unknown committed
432 433 434
  const NdbOperation *m_current_multi_operation;
  NdbIndexScanOperation *m_multi_cursor;
  byte *m_multi_range_cursor_result_ptr;
435
  int setup_recattr(const NdbRecAttr*);
436
  Ndb *get_ndb();
unknown's avatar
unknown committed
437 438 439 440 441 442 443 444 445 446
};

bool ndbcluster_init(void);
bool ndbcluster_end(void);

int ndbcluster_commit(THD *thd, void* ndb_transaction);
int ndbcluster_rollback(THD *thd, void* ndb_transaction);

void ndbcluster_close_connection(THD *thd);

447
int ndbcluster_discover(THD* thd, const char* dbname, const char* name,
unknown's avatar
unknown committed
448
			const void** frmblob, uint* frmlen);
449
int ndbcluster_find_files(THD *thd,const char *db,const char *path,
unknown's avatar
unknown committed
450
			  const char *wild, bool dir, List<char> *files);
451
int ndbcluster_table_exists(THD* thd, const char *db, const char *name);
unknown's avatar
unknown committed
452 453
int ndbcluster_drop_database(const char* path);

454
void ndbcluster_print_error(int error, const NdbOperation *error_op);