My Project
|
00001 /* Copyright (c) 2006, 2014, Oracle and/or its affiliates. All rights reserved. 00002 00003 This program is free software; you can redistribute it and/or modify 00004 it under the terms of the GNU General Public License as published by 00005 the Free Software Foundation; version 2 of the License. 00006 00007 This program is distributed in the hope that it will be useful, 00008 but WITHOUT ANY WARRANTY; without even the implied warranty of 00009 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00010 GNU General Public License for more details. 00011 00012 You should have received a copy of the GNU General Public License 00013 along with this program; if not, write to the Free Software 00014 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ 00015 00016 #ifndef RPL_UTILITY_H 00017 #define RPL_UTILITY_H 00018 00019 #ifndef __cplusplus 00020 #error "Don't include this C++ header file from a non-C++ file!" 00021 #endif 00022 00023 #include "sql_priv.h" 00024 #include "m_string.h" 00025 #ifdef MYSQL_SERVER 00026 #include "table.h" /* TABLE_LIST */ 00027 #endif 00028 #include "mysql_com.h" 00029 #include <hash.h> 00030 00031 00032 class Relay_log_info; 00033 class Log_event; 00034 #ifndef MYSQL_CLIENT 00035 00041 typedef struct hash_row_pos_st 00042 { 00048 const uchar *bi_start; 00049 const uchar *bi_ends; 00050 00051 } HASH_ROW_POS; 00052 00053 00061 typedef struct hash_row_preamble_st 00062 { 00063 /* 00064 The actual key. 00065 */ 00066 my_hash_value_type hash_value; 00067 00071 uint length; 00072 00077 HASH_SEARCH_STATE search_state; 00078 00082 bool is_search_state_inited; 00083 00084 } HASH_ROW_PREAMBLE; 00085 00086 typedef struct hash_row_entry_st 00087 { 00088 HASH_ROW_PREAMBLE *preamble; 00089 HASH_ROW_POS *positions; 00090 } HASH_ROW_ENTRY; 00091 00092 class Hash_slave_rows 00093 { 00094 public: 00095 00102 HASH_ROW_ENTRY* make_entry(); 00103 00114 HASH_ROW_ENTRY* make_entry(const uchar *bi_start, const uchar *bi_ends); 00115 00116 00128 bool put(TABLE* table, MY_BITMAP *cols, HASH_ROW_ENTRY* entry); 00129 00143 HASH_ROW_ENTRY* get(TABLE *table, MY_BITMAP *cols); 00144 00161 bool next(HASH_ROW_ENTRY** entry); 00162 00172 bool del(HASH_ROW_ENTRY* entry); 00173 00179 bool init(void); 00180 00186 bool deinit(void); 00187 00193 bool is_empty(void); 00194 00200 int size(); 00201 00202 private: 00203 00207 HASH m_hash; 00208 00218 my_hash_value_type make_hash_key(TABLE *table, MY_BITMAP* cols); 00219 }; 00220 00221 #endif 00222 00232 class table_def 00233 { 00234 public: 00244 table_def(unsigned char *types, ulong size, uchar *field_metadata, 00245 int metadata_size, uchar *null_bitmap, uint16 flags); 00246 00247 ~table_def(); 00248 00254 ulong size() const { return m_size; } 00255 00256 00257 /* 00258 Returns internal binlog type code for one field, 00259 without translation to real types. 00260 */ 00261 enum_field_types binlog_type(ulong index) const 00262 { 00263 return static_cast<enum_field_types>(m_type[index]); 00264 } 00265 /* 00266 Return a representation of the type data for one field. 00267 00268 @param index Field index to return data for 00269 00270 @return Will return a representation of the type data for field 00271 <code>index</code>. Currently, only the type identifier is 00272 returned. 00273 */ 00274 enum_field_types type(ulong index) const 00275 { 00276 DBUG_ASSERT(index < m_size); 00277 /* 00278 If the source type is MYSQL_TYPE_STRING, it can in reality be 00279 either MYSQL_TYPE_STRING, MYSQL_TYPE_ENUM, or MYSQL_TYPE_SET, so 00280 we might need to modify the type to get the real type. 00281 */ 00282 enum_field_types source_type= binlog_type(index); 00283 uint16 source_metadata= m_field_metadata[index]; 00284 switch (source_type) 00285 { 00286 case MYSQL_TYPE_STRING: 00287 { 00288 int real_type= source_metadata >> 8; 00289 if (real_type == MYSQL_TYPE_ENUM || real_type == MYSQL_TYPE_SET) 00290 source_type= static_cast<enum_field_types>(real_type); 00291 break; 00292 } 00293 00294 /* 00295 This type has not been used since before row-based replication, 00296 so we can safely assume that it really is MYSQL_TYPE_NEWDATE. 00297 */ 00298 case MYSQL_TYPE_DATE: 00299 source_type= MYSQL_TYPE_NEWDATE; 00300 break; 00301 00302 default: 00303 /* Do nothing */ 00304 break; 00305 } 00306 00307 return source_type; 00308 } 00309 00310 00311 /* 00312 This function allows callers to get the extra field data from the 00313 table map for a given field. If there is no metadata for that field 00314 or there is no extra metadata at all, the function returns 0. 00315 00316 The function returns the value for the field metadata for column at 00317 position indicated by index. As mentioned, if the field was a type 00318 that stores field metadata, that value is returned else zero (0) is 00319 returned. This method is used in the unpack() methods of the 00320 corresponding fields to properly extract the data from the binary log 00321 in the event that the master's field is smaller than the slave. 00322 */ 00323 uint16 field_metadata(uint index) const 00324 { 00325 DBUG_ASSERT(index < m_size); 00326 if (m_field_metadata_size) 00327 return m_field_metadata[index]; 00328 else 00329 return 0; 00330 } 00331 00332 /* 00333 This function returns whether the field on the master can be null. 00334 This value is derived from field->maybe_null(). 00335 */ 00336 my_bool maybe_null(uint index) const 00337 { 00338 DBUG_ASSERT(index < m_size); 00339 return ((m_null_bits[(index / 8)] & 00340 (1 << (index % 8))) == (1 << (index %8))); 00341 } 00342 00343 /* 00344 This function returns the field size in raw bytes based on the type 00345 and the encoded field data from the master's raw data. This method can 00346 be used for situations where the slave needs to skip a column (e.g., 00347 WL#3915) or needs to advance the pointer for the fields in the raw 00348 data from the master to a specific column. 00349 */ 00350 uint32 calc_field_size(uint col, uchar *master_data) const; 00351 00378 #ifndef MYSQL_CLIENT 00379 bool compatible_with(THD *thd, Relay_log_info *rli, TABLE *table, 00380 TABLE **conv_table_var) const; 00381 00404 TABLE *create_conversion_table(THD *thd, Relay_log_info *rli, TABLE *target_table) const; 00405 #endif 00406 00407 00408 private: 00409 ulong m_size; // Number of elements in the types array 00410 unsigned char *m_type; // Array of type descriptors 00411 uint m_field_metadata_size; 00412 uint16 *m_field_metadata; 00413 uchar *m_null_bits; 00414 uint16 m_flags; // Table flags 00415 uchar *m_memory; 00416 }; 00417 00418 00419 #ifndef MYSQL_CLIENT 00420 00424 struct RPL_TABLE_LIST 00425 : public TABLE_LIST 00426 { 00427 bool m_tabledef_valid; 00428 table_def m_tabledef; 00429 TABLE *m_conv_table; 00430 }; 00431 00432 00433 /* Anonymous namespace for template functions/classes */ 00434 CPP_UNNAMED_NS_START 00435 00436 /* 00437 Smart pointer that will automatically call my_afree (a macro) when 00438 the pointer goes out of scope. This is used so that I do not have 00439 to remember to call my_afree() before each return. There is no 00440 overhead associated with this, since all functions are inline. 00441 00442 I (Matz) would prefer to use the free function as a template 00443 parameter, but that is not possible when the "function" is a 00444 macro. 00445 */ 00446 template <class Obj> 00447 class auto_afree_ptr 00448 { 00449 Obj* m_ptr; 00450 public: 00451 auto_afree_ptr(Obj* ptr) : m_ptr(ptr) { } 00452 ~auto_afree_ptr() { if (m_ptr) my_afree(m_ptr); } 00453 void assign(Obj* ptr) { 00454 /* Only to be called if it hasn't been given a value before. */ 00455 DBUG_ASSERT(m_ptr == NULL); 00456 m_ptr= ptr; 00457 } 00458 Obj* get() { return m_ptr; } 00459 }; 00460 00461 CPP_UNNAMED_NS_END 00462 00463 class Deferred_log_events 00464 { 00465 private: 00466 DYNAMIC_ARRAY array; 00467 00468 public: 00469 Deferred_log_events(Relay_log_info *rli); 00470 ~Deferred_log_events(); 00471 /* queue for exection at Query-log-event time prior the Query */ 00472 int add(Log_event *ev); 00473 bool is_empty(); 00474 bool execute(Relay_log_info *rli); 00475 void rewind(); 00476 }; 00477 00478 #endif 00479 00480 // NB. number of printed bit values is limited to sizeof(buf) - 1 00481 #define DBUG_PRINT_BITSET(N,FRM,BS) \ 00482 do { \ 00483 char buf[256]; \ 00484 uint i; \ 00485 for (i = 0 ; i < MY_MIN(sizeof(buf) - 1, (BS)->n_bits) ; i++) \ 00486 buf[i] = bitmap_is_set((BS), i) ? '1' : '0'; \ 00487 buf[i] = '\0'; \ 00488 DBUG_PRINT((N), ((FRM), buf)); \ 00489 } while (0) 00490 00491 #endif /* RPL_UTILITY_H */ 00492