My Project
rpl_utility.h
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 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines