My Project
|
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;