My Project
ha_ndbcluster.h
00001 /*
00002    Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
00003 
00004    This program is free software; you can redistribute it and/or modify
00005    it under the terms of the GNU General Public License as published by
00006    the Free Software Foundation; version 2 of the License.
00007 
00008    This program is distributed in the hope that it will be useful,
00009    but WITHOUT ANY WARRANTY; without even the implied warranty of
00010    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00011    GNU General Public License for more details.
00012 
00013    You should have received a copy of the GNU General Public License
00014    along with this program; if not, write to the Free Software
00015    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
00016 */
00017 
00018 /*
00019   This file defines the NDB Cluster handler: the interface between MySQL and
00020   NDB Cluster
00021 */
00022 
00023 
00024 /* Blob tables and events are internal to NDB and must never be accessed */
00025 #define IS_NDB_BLOB_PREFIX(A) is_prefix(A, "NDB$BLOB")
00026 
00027 #include <ndbapi/NdbApi.hpp>
00028 #include <ndbapi/ndbapi_limits.h>
00029 #include <kernel/ndb_limits.h>
00030 
00031 #define NDB_IGNORE_VALUE(x) (void)x
00032 
00033 #define NDB_HIDDEN_PRIMARY_KEY_LENGTH 8
00034 
00035 class Ndb;             // Forward declaration
00036 class NdbOperation;    // Forward declaration
00037 class NdbTransaction;  // Forward declaration
00038 class NdbRecAttr;      // Forward declaration
00039 class NdbScanOperation; 
00040 class NdbIndexScanOperation; 
00041 class NdbBlob;
00042 class NdbIndexStat;
00043 class NdbEventOperation;
00044 class ha_ndbcluster_cond;
00045 class Ndb_event_data;
00046 class NdbQuery;
00047 class NdbQueryOperation;
00048 class NdbQueryOperationTypeWrapper;
00049 class NdbQueryParamValue;
00050 class ndb_pushed_join;
00051 
00052 typedef enum ndb_index_type {
00053   UNDEFINED_INDEX = 0,
00054   PRIMARY_KEY_INDEX = 1,
00055   PRIMARY_KEY_ORDERED_INDEX = 2,
00056   UNIQUE_INDEX = 3,
00057   UNIQUE_ORDERED_INDEX = 4,
00058   ORDERED_INDEX = 5
00059 } NDB_INDEX_TYPE;
00060 
00061 typedef enum ndb_index_status {
00062   UNDEFINED = 0,
00063   ACTIVE = 1,
00064   TO_BE_DROPPED = 2
00065 } NDB_INDEX_STATUS;
00066 
00067 typedef struct ndb_index_data {
00068   NDB_INDEX_TYPE type;
00069   NDB_INDEX_STATUS status;  
00070   const NdbDictionary::Index *index;
00071   const NdbDictionary::Index *unique_index;
00072   unsigned char *unique_index_attrid_map;
00073   bool null_in_unique_index;
00074   /*
00075     In mysqld, keys and rows are stored differently (using KEY_PART_INFO for
00076     keys and Field for rows).
00077     So we need to use different NdbRecord for an index for passing values
00078     from a key and from a row.
00079   */
00080   NdbRecord *ndb_record_key;
00081   NdbRecord *ndb_unique_record_key;
00082   NdbRecord *ndb_unique_record_row;
00083 } NDB_INDEX_DATA;
00084 
00085 typedef enum ndb_write_op {
00086   NDB_INSERT = 0,
00087   NDB_UPDATE = 1,
00088   NDB_PK_UPDATE = 2
00089 } NDB_WRITE_OP;
00090 
00091 class NDB_ALTER_DATA : public Sql_alloc
00092 {
00093 public:
00094   NDB_ALTER_DATA(NdbDictionary::Dictionary *dict,
00095                  const NdbDictionary::Table *table) :
00096     dictionary(dict),
00097     old_table(table),
00098     new_table(new NdbDictionary::Table(*table)),
00099       table_id(table->getObjectId()),
00100       old_table_version(table->getObjectVersion())
00101   {}
00102   ~NDB_ALTER_DATA()
00103   { delete new_table; }
00104   NdbDictionary::Dictionary *dictionary;
00105   const  NdbDictionary::Table *old_table;
00106   NdbDictionary::Table *new_table;
00107   Uint32 table_id;
00108   Uint32 old_table_version;
00109 };
00110 
00111 typedef union { const NdbRecAttr *rec; NdbBlob *blob; void *ptr; } NdbValue;
00112 
00113 int get_ndb_blobs_value(TABLE* table, NdbValue* value_array,
00114                         uchar*& buffer, uint& buffer_size,
00115                         my_ptrdiff_t ptrdiff);
00116 
00117 #include "ndb_share.h"
00118 
00119 struct Ndb_tuple_id_range_guard {
00120   Ndb_tuple_id_range_guard(NDB_SHARE* _share) :
00121     share(_share),
00122     range(share->tuple_id_range) {
00123     pthread_mutex_lock(&share->mutex);
00124   }
00125   ~Ndb_tuple_id_range_guard() {
00126     pthread_mutex_unlock(&share->mutex);
00127   }
00128   NDB_SHARE* share;
00129   Ndb::TupleIdRange& range;
00130 };
00131 
00132 /* NDB_SHARE.flags */
00133 #define NSF_HIDDEN_PK   1u /* table has hidden primary key */
00134 #define NSF_BLOB_FLAG   2u /* table has blob attributes */
00135 #define NSF_NO_BINLOG   4u /* table should not be binlogged */
00136 #define NSF_BINLOG_FULL 8u /* table should be binlogged with full rows */
00137 #define NSF_BINLOG_USE_UPDATE 16u  /* table update should be binlogged using
00138                                      update log event */
00139 inline void set_binlog_logging(NDB_SHARE *share)
00140 {
00141   DBUG_PRINT("info", ("set_binlog_logging"));
00142   share->flags&= ~NSF_NO_BINLOG;
00143 }
00144 inline void set_binlog_nologging(NDB_SHARE *share)
00145 {
00146   DBUG_PRINT("info", ("set_binlog_nologging"));
00147   share->flags|= NSF_NO_BINLOG;
00148 }
00149 inline my_bool get_binlog_nologging(NDB_SHARE *share)
00150 { return (share->flags & NSF_NO_BINLOG) != 0; }
00151 inline void set_binlog_updated_only(NDB_SHARE *share)
00152 {
00153   DBUG_PRINT("info", ("set_binlog_updated_only"));
00154   share->flags&= ~NSF_BINLOG_FULL;
00155 }
00156 inline void set_binlog_full(NDB_SHARE *share)
00157 {
00158   DBUG_PRINT("info", ("set_binlog_full"));
00159   share->flags|= NSF_BINLOG_FULL;
00160 }
00161 inline my_bool get_binlog_full(NDB_SHARE *share)
00162 { return (share->flags & NSF_BINLOG_FULL) != 0; }
00163 inline void set_binlog_use_write(NDB_SHARE *share)
00164 {
00165   DBUG_PRINT("info", ("set_binlog_use_write"));
00166   share->flags&= ~NSF_BINLOG_USE_UPDATE;
00167 }
00168 inline void set_binlog_use_update(NDB_SHARE *share)
00169 {
00170   DBUG_PRINT("info", ("set_binlog_use_update"));
00171   share->flags|= NSF_BINLOG_USE_UPDATE;
00172 }
00173 inline my_bool get_binlog_use_update(NDB_SHARE *share)
00174 { return (share->flags & NSF_BINLOG_USE_UPDATE) != 0; }
00175 
00176 /*
00177   State associated with the Slave thread
00178   (From the Ndb handler's point of view)
00179 */
00180 struct st_ndb_slave_state
00181 {
00182   /* Counter values for current slave transaction */
00183   Uint32 current_conflict_defined_op_count;
00184   Uint32 current_violation_count[CFT_NUMBER_OF_CFTS];
00185   Uint64 current_master_server_epoch;
00186   Uint64 current_max_rep_epoch;
00187 
00188   /* Cumulative counter values */
00189   Uint64 total_violation_count[CFT_NUMBER_OF_CFTS];
00190   Uint64 max_rep_epoch;
00191   Uint32 sql_run_id;
00192 
00193   /* Methods */
00194   void atTransactionCommit();
00195   void atTransactionAbort();
00196   void atResetSlave();
00197 
00198   void atApplyStatusWrite(Uint32 master_server_id,
00199                           Uint32 row_server_id,
00200                           Uint64 row_epoch,
00201                           bool is_row_server_id_local);
00202 
00203   st_ndb_slave_state();
00204 };
00205 
00206 struct Ndb_local_table_statistics {
00207   int no_uncommitted_rows_count;
00208   ulong last_count;
00209   ha_rows records;
00210 };
00211 
00212 #include "ndb_thd_ndb.h"
00213 
00214 struct st_ndb_status {
00215   st_ndb_status() { memset(this, 0, sizeof(struct st_ndb_status)); }
00216   long cluster_node_id;
00217   const char * connected_host;
00218   long connected_port;
00219   long number_of_replicas;
00220   long number_of_data_nodes;
00221   long number_of_ready_data_nodes;
00222   long connect_count;
00223   long execute_count;
00224   long scan_count;
00225   long pruned_scan_count;
00226   long schema_locks_count;
00227   long sorted_scan_count;
00228   long pushed_queries_defined;
00229   long pushed_queries_dropped;
00230   long pushed_queries_executed;
00231   long pushed_reads;
00232   long transaction_no_hint_count[MAX_NDB_NODES];
00233   long transaction_hint_count[MAX_NDB_NODES];
00234   long long api_client_stats[Ndb::NumClientStatistics];
00235 };
00236 
00237 int ndbcluster_commit(handlerton *hton, THD *thd, bool all);
00238 class ha_ndbcluster: public handler
00239 {
00240   friend class ndb_pushed_builder_ctx;
00241 
00242  public:
00243   ha_ndbcluster(handlerton *hton, TABLE_SHARE *table);
00244   ~ha_ndbcluster();
00245 
00246   int open(const char *name, int mode, uint test_if_locked);
00247   int close(void);
00248   void local_close(THD *thd, bool release_metadata);
00249 
00250   int optimize(THD* thd, HA_CHECK_OPT* check_opt);
00251   int analyze(THD* thd, HA_CHECK_OPT* check_opt);
00252   int analyze_index(THD* thd);
00253 
00254   int write_row(uchar *buf);
00255   int update_row(const uchar *old_data, uchar *new_data);
00256   int delete_row(const uchar *buf);
00257   int index_init(uint index, bool sorted);
00258   int index_end();
00259   int index_read_idx_map(uchar *buf, uint index, const uchar *key,
00260                          key_part_map keypart_map,
00261                          enum ha_rkey_function find_flag);
00262   int index_read(uchar *buf, const uchar *key, uint key_len, 
00263                  enum ha_rkey_function find_flag);
00264   int index_next(uchar *buf);
00265   int index_prev(uchar *buf);
00266   int index_first(uchar *buf);
00267   int index_last(uchar *buf);
00268   int index_read_last(uchar * buf, const uchar * key, uint key_len);
00269   int rnd_init(bool scan);
00270   int rnd_end();
00271   int rnd_next(uchar *buf);
00272   int rnd_pos(uchar *buf, uchar *pos);
00273   void position(const uchar *record);
00274   int read_first_row(uchar *buf, uint primary_key);
00275   virtual int cmp_ref(const uchar * ref1, const uchar * ref2);
00276   int read_range_first(const key_range *start_key,
00277                        const key_range *end_key,
00278                        bool eq_range, bool sorted);
00279   int read_range_first_to_buf(const key_range *start_key,
00280                               const key_range *end_key,
00281                               bool eq_range, bool sorted,
00282                               uchar* buf);
00283   int read_range_next();
00284 
00285 #ifndef NDB_WITH_NEW_MRR_INTERFACE
00286 
00289   int read_multi_range_first(KEY_MULTI_RANGE **found_range_p,
00290                              KEY_MULTI_RANGE*ranges, uint range_count,
00291                              bool sorted, HANDLER_BUFFER *buffer);
00292   int read_multi_range_next(KEY_MULTI_RANGE **found_range_p);
00293   bool null_value_index_search(KEY_MULTI_RANGE *ranges,
00294                                KEY_MULTI_RANGE *end_range,
00295                                HANDLER_BUFFER *buffer);
00296 #endif
00297 
00298   bool get_error_message(int error, String *buf);
00299   ha_rows records();
00300   ha_rows estimate_rows_upper_bound()
00301     { return HA_POS_ERROR; }
00302   int info(uint);
00303 #if MYSQL_VERSION_ID < 50501
00304   typedef PARTITION_INFO PARTITION_STATS;
00305 #endif
00306   void get_dynamic_partition_info(PARTITION_STATS *stat_info, uint part_id);
00307   uint32 calculate_key_hash_value(Field **field_array);
00308   bool start_read_removal(void);
00309   ha_rows end_read_removal(void);
00310   int extra(enum ha_extra_function operation);
00311   int extra_opt(enum ha_extra_function operation, ulong cache_size);
00312   int reset();
00313   int external_lock(THD *thd, int lock_type);
00314   void unlock_row();
00315   int start_stmt(THD *thd, thr_lock_type lock_type);
00316   void update_create_info(HA_CREATE_INFO *create_info);
00317   void print_error(int error, myf errflag);
00318   const char * table_type() const;
00319   const char ** bas_ext() const;
00320   ulonglong table_flags(void) const;
00321   void set_part_info(partition_info *part_info, bool early);
00322   ulong index_flags(uint idx, uint part, bool all_parts) const;
00323   virtual const key_map *keys_to_use_for_scanning() { return &btree_keys; }
00324   bool primary_key_is_clustered();
00325   uint max_supported_record_length() const;
00326   uint max_supported_keys() const;
00327   uint max_supported_key_parts() const;
00328   uint max_supported_key_length() const;
00329   uint max_supported_key_part_length() const;
00330 
00331   int rename_table(const char *from, const char *to);
00332   int delete_table(const char *name);
00333   int create(const char *name, TABLE *form, HA_CREATE_INFO *info);
00334   int get_default_no_partitions(HA_CREATE_INFO *info);
00335   bool get_no_parts(const char *name, uint *no_parts);
00336   void set_auto_partitions(partition_info *part_info);
00337   virtual bool is_fatal_error(int error, uint flags)
00338   {
00339     if (!handler::is_fatal_error(error, flags) ||
00340         error == HA_ERR_NO_PARTITION_FOUND)
00341       return FALSE;
00342     return TRUE;
00343   }
00344 
00345   THR_LOCK_DATA **store_lock(THD *thd,
00346                              THR_LOCK_DATA **to,
00347                              enum thr_lock_type lock_type);
00348 
00349   bool low_byte_first() const;
00350 
00351   const char* index_type(uint key_number);
00352 
00353   double scan_time();
00354   ha_rows records_in_range(uint inx, key_range *min_key, key_range *max_key);
00355   void start_bulk_insert(ha_rows rows);
00356   int end_bulk_insert();
00357 
00358   bool start_bulk_update();
00359   int bulk_update_row(const uchar *old_data, uchar *new_data,
00360                       uint *dup_key_found);
00361   int exec_bulk_update(uint *dup_key_found);
00362   void end_bulk_update();
00363   int ndb_update_row(const uchar *old_data, uchar *new_data,
00364                      int is_bulk_update);
00365 
00366 static void set_dbname(const char *pathname, char *dbname);
00367 static void set_tabname(const char *pathname, char *tabname);
00368 
00369   /*
00370     static member function as it needs to access private
00371     NdbTransaction methods
00372   */
00373   static void release_completed_operations(NdbTransaction*);
00374 
00375   /*
00376     Condition pushdown
00377   */
00378 
00379  /*
00380    Push condition down to the table handler.
00381    SYNOPSIS
00382      cond_push()
00383      cond   Condition to be pushed. The condition tree must not be
00384      modified by the by the caller.
00385    RETURN
00386      The 'remainder' condition that caller must use to filter out records.
00387      NULL means the handler will not return rows that do not match the
00388      passed condition.
00389    NOTES
00390    The pushed conditions form a stack (from which one can remove the
00391    last pushed condition using cond_pop).
00392    The table handler filters out rows using (pushed_cond1 AND pushed_cond2 
00393    AND ... AND pushed_condN)
00394    or less restrictive condition, depending on handler's capabilities.
00395    
00396    handler->reset() call empties the condition stack.
00397    Calls to rnd_init/rnd_end, index_init/index_end etc do not affect the  
00398    condition stack.
00399    The current implementation supports arbitrary AND/OR nested conditions
00400    with comparisons between columns and constants (including constant
00401    expressions and function calls) and the following comparison operators:
00402    =, !=, >, >=, <, <=, like, "not like", "is null", and "is not null". 
00403    Negated conditions are supported by NOT which generate NAND/NOR groups.
00404  */ 
00405   const Item *cond_push(const Item *cond);
00406  /*
00407    Pop the top condition from the condition stack of the handler instance.
00408    SYNOPSIS
00409      cond_pop()
00410      Pops the top if condition stack, if stack is not empty
00411  */
00412   void cond_pop();
00413 
00414   bool maybe_pushable_join(const char*& reason) const;
00415   int assign_pushed_join(const ndb_pushed_join* pushed_join);
00416 
00417   uint number_of_pushed_joins() const;
00418   const TABLE* root_of_pushed_join() const;
00419   const TABLE* parent_of_pushed_join() const;
00420 
00421   int index_read_pushed(uchar *buf, const uchar *key,
00422                         key_part_map keypart_map);
00423 
00424   int index_next_pushed(uchar * buf);
00425 
00426   uint8 table_cache_type();
00427 
00428   /*
00429    * Internal to ha_ndbcluster, used by C functions
00430    */
00431   int ndb_err(NdbTransaction*, bool have_lock= FALSE);
00432 
00433   my_bool register_query_cache_table(THD *thd, char *table_key,
00434                                      uint key_length,
00435                                      qc_engine_callback *engine_callback,
00436                                      ulonglong *engine_data);
00437 
00438 #ifndef NDB_WITHOUT_ONLINE_ALTER
00439   int check_if_supported_alter(TABLE *altered_table,
00440                                HA_CREATE_INFO *create_info,
00441                                Alter_info *alter_info,
00442                                HA_ALTER_FLAGS *alter_flags,
00443                                uint table_changes);
00444 
00445   int alter_table_phase1(THD *thd,
00446                          TABLE *altered_table,
00447                          HA_CREATE_INFO *create_info,
00448                          HA_ALTER_INFO *alter_info,
00449                          HA_ALTER_FLAGS *alter_flags);
00450 
00451   int alter_table_phase2(THD *thd,
00452                          TABLE *altered_table,
00453                          HA_CREATE_INFO *create_info,
00454                          HA_ALTER_INFO *alter_info,
00455                          HA_ALTER_FLAGS *alter_flags);
00456 
00457   int alter_table_phase3(THD *thd, TABLE *table,
00458                          HA_CREATE_INFO *create_info,
00459                          HA_ALTER_INFO *alter_info,
00460                          HA_ALTER_FLAGS *alter_flags);
00461 #endif
00462 
00463 private:
00464 #ifdef HAVE_NDB_BINLOG
00465   int prepare_conflict_detection(enum_conflicting_op_type op_type,
00466                                  const NdbRecord* key_rec,
00467                                  const uchar* old_data,
00468                                  const uchar* new_data,
00469                                  NdbInterpretedCode* code,
00470                                  NdbOperation::OperationOptions* options);
00471 #endif
00472   void setup_key_ref_for_ndb_record(const NdbRecord **key_rec,
00473                                     const uchar **key_row,
00474                                     const uchar *record,
00475                                     bool use_active_index);
00476   friend int ndbcluster_drop_database_impl(THD *thd, const char *path);
00477   friend int ndb_handle_schema_change(THD *thd, 
00478                                       Ndb *ndb, NdbEventOperation *pOp,
00479                                       NDB_SHARE *share);
00480 
00481   void check_read_before_write_removal();
00482   static int drop_table_impl(THD *thd, ha_ndbcluster *h, Ndb *ndb,
00483                              const char *path,
00484                              const char *db,
00485                              const char *table_name);
00486 
00487   int add_index_impl(THD *thd, TABLE *table_arg,
00488                      KEY *key_info, uint num_of_keys);
00489   int create_ndb_index(THD *thd, const char *name, KEY *key_info, bool unique);
00490   int create_ordered_index(THD *thd, const char *name, KEY *key_info);
00491   int create_unique_index(THD *thd, const char *name, KEY *key_info);
00492   int create_index(THD *thd, const char *name, KEY *key_info, 
00493                    NDB_INDEX_TYPE idx_type, uint idx_no);
00494 // Index list management
00495   int create_indexes(THD *thd, Ndb *ndb, TABLE *tab);
00496   int open_indexes(THD *thd, Ndb *ndb, TABLE *tab, bool ignore_error);
00497   void renumber_indexes(Ndb *ndb, TABLE *tab);
00498   int drop_indexes(Ndb *ndb, TABLE *tab);
00499   int add_index_handle(THD *thd, NdbDictionary::Dictionary *dict,
00500                        KEY *key_info, const char *key_name, uint index_no);
00501   int add_table_ndb_record(NdbDictionary::Dictionary *dict);
00502   int add_hidden_pk_ndb_record(NdbDictionary::Dictionary *dict);
00503   int add_index_ndb_record(NdbDictionary::Dictionary *dict,
00504                            KEY *key_info, uint index_no);
00505   int check_default_values(const NdbDictionary::Table* ndbtab);
00506   int get_metadata(THD *thd, const char* path);
00507   void release_metadata(THD *thd, Ndb *ndb);
00508   NDB_INDEX_TYPE get_index_type(uint idx_no) const;
00509   NDB_INDEX_TYPE get_index_type_from_table(uint index_no) const;
00510   NDB_INDEX_TYPE get_index_type_from_key(uint index_no, KEY *key_info, 
00511                                          bool primary) const;
00512   bool has_null_in_unique_index(uint idx_no) const;
00513   bool check_index_fields_not_null(KEY *key_info);
00514 
00515   bool check_if_pushable(int type, //NdbQueryOperationDef::Type,
00516                          uint idx= MAX_KEY,
00517                          bool rootSorted= false) const;
00518   bool check_is_pushed() const;
00519   int create_pushed_join(const NdbQueryParamValue* keyFieldParams=NULL,
00520                          uint paramCnt= 0);
00521 
00522   int set_up_partition_info(partition_info *part_info,
00523                             NdbDictionary::Table&) const;
00524   int set_range_data(const partition_info* part_info,
00525                      NdbDictionary::Table&) const;
00526   int set_list_data(const partition_info* part_info,
00527                     NdbDictionary::Table&) const;
00528   int ndb_pk_update_row(THD *thd, 
00529                         const uchar *old_data, uchar *new_data,
00530                         uint32 old_part_id);
00531   int pk_read(const uchar *key, uint key_len, uchar *buf, uint32 *part_id);
00532   int ordered_index_scan(const key_range *start_key,
00533                          const key_range *end_key,
00534                          bool sorted, bool descending, uchar* buf,
00535                          part_id_range *part_spec);
00536   int unique_index_read(const uchar *key, uint key_len, 
00537                         uchar *buf);
00538   int full_table_scan(const KEY* key_info, 
00539                       const key_range *start_key,
00540                       const key_range *end_key,
00541                       uchar *buf);
00542   int flush_bulk_insert(bool allow_batch= FALSE);
00543   int ndb_write_row(uchar *record, bool primary_key_update,
00544                     bool batched_update);
00545 
00546   bool start_bulk_delete();
00547   int end_bulk_delete();
00548   int ndb_delete_row(const uchar *record, bool primary_key_update);
00549 
00550   int ndb_optimize_table(THD* thd, uint delay);
00551 
00552 #ifndef NDB_WITHOUT_ONLINE_ALTER
00553   int alter_frm(THD *thd, const char *file, NDB_ALTER_DATA *alter_data);
00554 #endif
00555 
00556   bool check_all_operations_for_error(NdbTransaction *trans,
00557                                       const NdbOperation *first,
00558                                       const NdbOperation *last,
00559                                       uint errcode);
00560   int peek_indexed_rows(const uchar *record, NDB_WRITE_OP write_op);
00561   int scan_handle_lock_tuple(NdbScanOperation *scanOp, NdbTransaction *trans);
00562   int fetch_next(NdbScanOperation* op);
00563   int fetch_next_pushed();
00564   int set_auto_inc(THD *thd, Field *field);
00565   int set_auto_inc_val(THD *thd, Uint64 value);
00566   int next_result(uchar *buf); 
00567   int close_scan();
00568   void unpack_record(uchar *dst_row, const uchar *src_row);
00569 
00570   void set_dbname(const char *pathname);
00571   void set_tabname(const char *pathname);
00572 
00573   const NdbDictionary::Column *get_hidden_key_column() {
00574     return m_table->getColumn(table_share->fields);
00575   }
00576   const NdbDictionary::Column *get_partition_id_column() {
00577     Uint32 index= table_share->fields + (table_share->primary_key == MAX_KEY);
00578     return m_table->getColumn(index);
00579   }
00580 
00581   bool add_row_check_if_batch_full_size(Thd_ndb *thd_ndb, uint size);
00582   bool add_row_check_if_batch_full(Thd_ndb *thd_ndb) {
00583     return add_row_check_if_batch_full_size(thd_ndb, m_bytes_per_write);
00584   }
00585   uchar *get_buffer(Thd_ndb *thd_ndb, uint size);
00586   uchar *copy_row_to_buffer(Thd_ndb *thd_ndb, const uchar *record);
00587 
00588   int get_blob_values(const NdbOperation *ndb_op, uchar *dst_record,
00589                       const MY_BITMAP *bitmap);
00590   int set_blob_values(const NdbOperation *ndb_op, my_ptrdiff_t row_offset,
00591                       const MY_BITMAP *bitmap, uint *set_count, bool batch);
00592   friend int g_get_ndb_blobs_value(NdbBlob *ndb_blob, void *arg);
00593   void release_blobs_buffer();
00594   Uint32 setup_get_hidden_fields(NdbOperation::GetValueSpec gets[2]);
00595   void get_hidden_fields_keyop(NdbOperation::OperationOptions *options,
00596                                NdbOperation::GetValueSpec gets[2]);
00597   void get_hidden_fields_scan(NdbScanOperation::ScanOptions *options,
00598                               NdbOperation::GetValueSpec gets[2]);
00599   void eventSetAnyValue(THD *thd,
00600                         NdbOperation::OperationOptions *options) const;
00601   bool check_index_fields_in_write_set(uint keyno);
00602 
00603   const NdbOperation *pk_unique_index_read_key(uint idx, 
00604                                                const uchar *key, uchar *buf,
00605                                                NdbOperation::LockMode lm,
00606                                                Uint32 *ppartition_id);
00607   int pk_unique_index_read_key_pushed(uint idx, 
00608                                       const uchar *key,
00609                                       Uint32 *ppartition_id);
00610 
00611   int read_multi_range_fetch_next();
00612   
00613   int primary_key_cmp(const uchar * old_row, const uchar * new_row);
00614   void print_results();
00615 
00616   virtual void get_auto_increment(ulonglong offset, ulonglong increment,
00617                                   ulonglong nb_desired_values,
00618                                   ulonglong *first_value,
00619                                   ulonglong *nb_reserved_values);
00620   bool uses_blob_value(const MY_BITMAP *bitmap) const;
00621 
00622   static inline bool isManualBinlogExec(THD *thd);
00623 
00624   char *update_table_comment(const char * comment);
00625 
00626   int write_ndb_file(const char *name);
00627 
00628   int check_ndb_connection(THD* thd);
00629 
00630   void set_rec_per_key();
00631   int records_update();
00632   void no_uncommitted_rows_execute_failure();
00633   void no_uncommitted_rows_update(int);
00634   void no_uncommitted_rows_reset(THD *);
00635 
00636   /* Ordered index statistics v4 */
00637   int ndb_index_stat_query(uint inx,
00638                            const key_range *min_key,
00639                            const key_range *max_key,
00640                            NdbIndexStat::Stat& stat,
00641                            int from);
00642   int ndb_index_stat_get_rir(uint inx,
00643                              key_range *min_key,
00644                              key_range *max_key,
00645                              ha_rows *rows_out);
00646   int ndb_index_stat_set_rpk(uint inx);
00647   int ndb_index_stat_analyze(Ndb *ndb,
00648                              uint *inx_list,
00649                              uint inx_count);
00650 
00651   NdbTransaction *start_transaction_part_id(uint32 part_id, int &error);
00652   inline NdbTransaction *get_transaction_part_id(uint32 part_id, int &error)
00653   {
00654     if (m_thd_ndb->trans)
00655       return m_thd_ndb->trans;
00656     return start_transaction_part_id(part_id, error);
00657   }
00658 
00659   NdbTransaction *start_transaction(int &error);
00660   inline NdbTransaction *get_transaction(int &error)
00661   {
00662     if (m_thd_ndb->trans)
00663       return m_thd_ndb->trans;
00664     return start_transaction(error);
00665   }
00666 
00667   NdbTransaction *start_transaction_row(const NdbRecord *ndb_record,
00668                                         const uchar *record,
00669                                         int &error);
00670   NdbTransaction *start_transaction_key(uint index,
00671                                         const uchar *key_data,
00672                                         int &error);
00673 
00674   friend int check_completed_operations_pre_commit(Thd_ndb*,
00675                                                    NdbTransaction*,
00676                                                    const NdbOperation*,
00677                                                    uint *ignore_count);
00678   friend int ndbcluster_commit(handlerton *hton, THD *thd, bool all);
00679   int start_statement(THD *thd, Thd_ndb *thd_ndb, uint table_count);
00680   int init_handler_for_statement(THD *thd);
00681 
00682   Thd_ndb *m_thd_ndb;
00683   NdbScanOperation *m_active_cursor;
00684   const NdbDictionary::Table *m_table;
00685   /*
00686     Normal NdbRecord for accessing rows, with all fields including hidden
00687     fields (hidden primary key, user-defined partitioning function value).
00688   */
00689   NdbRecord *m_ndb_record;
00690   /* NdbRecord for accessing tuple by hidden Uint64 primary key. */
00691   NdbRecord *m_ndb_hidden_key_record;
00692 
00693   /* Bitmap used for NdbRecord operation column mask. */
00694   MY_BITMAP m_bitmap;
00695   my_bitmap_map m_bitmap_buf[(NDB_MAX_ATTRIBUTES_IN_TABLE +
00696                               8*sizeof(my_bitmap_map) - 1) /
00697                              (8*sizeof(my_bitmap_map))]; // Buffer for m_bitmap
00698   /* Bitmap with bit set for all primary key columns. */
00699   MY_BITMAP *m_pk_bitmap_p;
00700   my_bitmap_map m_pk_bitmap_buf[(NDB_MAX_ATTRIBUTES_IN_TABLE +
00701                                  8*sizeof(my_bitmap_map) - 1) /
00702                                 (8*sizeof(my_bitmap_map))]; // Buffer for m_pk_bitmap
00703   struct Ndb_local_table_statistics *m_table_info;
00704   struct Ndb_local_table_statistics m_table_info_instance;
00705   char m_dbname[FN_HEADLEN];
00706   //char m_schemaname[FN_HEADLEN];
00707   char m_tabname[FN_HEADLEN];
00708   THR_LOCK_DATA m_lock;
00709   bool m_lock_tuple;
00710   NDB_SHARE *m_share;
00711   NDB_INDEX_DATA  m_index[MAX_KEY];
00712   key_map btree_keys;
00713 
00714   /*
00715     Pointer to row returned from scan nextResult().
00716   */
00717   union
00718   {
00719     const char *_m_next_row;
00720     const uchar *m_next_row;
00721   };
00722   /* For read_multi_range scans, the get_range_no() of current row. */
00723   int m_current_range_no;
00724 
00725   MY_BITMAP **m_key_fields;
00726   // NdbRecAttr has no reference to blob
00727   NdbValue m_value[NDB_MAX_ATTRIBUTES_IN_TABLE];
00728   Uint64 m_ref;
00729   partition_info *m_part_info;
00730   uint32 m_part_id;
00731   bool m_user_defined_partitioning;
00732   bool m_use_partition_pruning;
00733   bool m_sorted;
00734   bool m_use_write;
00735   bool m_ignore_dup_key;
00736   bool m_has_unique_index;
00737   bool m_ignore_no_key;
00738   bool m_read_before_write_removal_possible;
00739   bool m_read_before_write_removal_used;
00740   ha_rows m_rows_updated;
00741   ha_rows m_rows_deleted;
00742   ha_rows m_rows_to_insert; // TODO: merge it with handler::estimation_rows_to_insert?
00743   ha_rows m_rows_inserted;
00744   ha_rows m_rows_changed;
00745   bool m_delete_cannot_batch;
00746   bool m_update_cannot_batch;
00747   uint m_bytes_per_write;
00748   bool m_skip_auto_increment;
00749   bool m_blobs_pending;
00750   bool m_slow_path;
00751   bool m_is_bulk_delete;
00752 
00753   /* State for setActiveHook() callback for reading blob data. */
00754   uint m_blob_counter;
00755   uint m_blob_expected_count_per_row;
00756   uchar *m_blob_destination_record;
00757   Uint64 m_blobs_row_total_size; /* Bytes needed for all blobs in current row */
00758   
00759   // memory for blobs in one tuple
00760   uchar *m_blobs_buffer;
00761   Uint64 m_blobs_buffer_size;
00762   uint m_dupkey;
00763   // set from thread variables at external lock
00764   ha_rows m_autoincrement_prefetch;
00765 
00766   // Joins pushed to NDB.
00767   const ndb_pushed_join
00768        *m_pushed_join_member;            // Pushed join def. I am member of
00769   int m_pushed_join_operation;           // Op. id. in above pushed join
00770   static const int PUSHED_ROOT= 0;       // Op. id. if I'm root
00771 
00772   bool m_disable_pushed_join;            // Pushed execution allowed?
00773   NdbQuery* m_active_query;              // Pushed query instance executing
00774   NdbQueryOperation* m_pushed_operation; // Pushed operation instance
00775 
00776   ha_ndbcluster_cond *m_cond;
00777   bool m_disable_multi_read;
00778   const uchar *m_multi_range_result_ptr;
00779   KEY_MULTI_RANGE *m_multi_ranges;
00780   /*
00781     Points 1 past the end of last multi range operation currently being
00782     executed, to support splitting large multi range reands into manageable
00783     pieces.
00784   */
00785   KEY_MULTI_RANGE *m_multi_range_defined_end;
00786   NdbIndexScanOperation *m_multi_cursor;
00787   Ndb *get_ndb(THD *thd);
00788 
00789   int update_stats(THD *thd, bool do_read_stat, bool have_lock= FALSE,
00790                    uint part_id= ~(uint)0);
00791   int add_handler_to_open_tables(THD*, Thd_ndb*, ha_ndbcluster* handler);
00792 };
00793 
00794 int ndbcluster_discover(THD* thd, const char* dbname, const char* name,
00795                         const void** frmblob, uint* frmlen);
00796 int ndbcluster_table_exists_in_engine(THD* thd,
00797                                       const char *db, const char *name);
00798 void ndbcluster_print_error(int error, const NdbOperation *error_op);
00799 
00800 static const char ndbcluster_hton_name[]= "ndbcluster";
00801 static const int ndbcluster_hton_name_length=sizeof(ndbcluster_hton_name)-1;
00802 extern int ndbcluster_terminating;
00803 extern int ndb_util_thread_running;
00804 extern pthread_cond_t COND_ndb_util_ready;
00805 extern int ndb_index_stat_thread_running;
00806 extern pthread_cond_t COND_ndb_index_stat_ready;
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines