1 /* Copyright (c) 2006, 2014, Oracle and/or its affiliates. All rights reserved.
2 
3    This program is free software; you can redistribute it and/or modify
4    it under the terms of the GNU General Public License, version 2.0,
5    as published by the Free Software Foundation.
6 
7    This program is also distributed with certain software (including
8    but not limited to OpenSSL) that is licensed under separate terms,
9    as designated in a particular file or component or in included license
10    documentation.  The authors of MySQL hereby grant you an additional
11    permission to link the program and your derivative works with the
12    separately licensed software that they have included with MySQL.
13 
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License, version 2.0, for more details.
18 
19    You should have received a copy of the GNU General Public License
20    along with this program; if not, write to the Free Software
21    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
22 
23 #ifndef RPL_UTILITY_H
24 #define RPL_UTILITY_H
25 
26 #ifndef __cplusplus
27 #error "Don't include this C++ header file from a non-C++ file!"
28 #endif
29 
30 #include "sql_priv.h"
31 #include "m_string.h"
32 #ifdef MYSQL_SERVER
33 #include "table.h"                              /* TABLE_LIST */
34 #endif
35 #include "mysql_com.h"
36 #include <hash.h>
37 
38 
39 class Relay_log_info;
40 class Log_event;
41 #ifndef MYSQL_CLIENT
42 
43 /**
44    Hash table used when applying row events on the slave and there is
45    no index on the slave's table.
46  */
47 
48 typedef struct hash_row_pos_st
49 {
50   /**
51       Points at the position where the row starts in the
52       event buffer (ie, area in memory before unpacking takes
53       place).
54   */
55   const uchar *bi_start;
56   const uchar *bi_ends;
57 
58 } HASH_ROW_POS;
59 
60 
61 /**
62    Internal structure that acts as a preamble for HASH_ROW_POS
63    in memory structure.
64 
65    Allocation is done in Hash_slave_rows::make_entry as part of
66    the entry allocation.
67  */
68 typedef struct hash_row_preamble_st
69 {
70   /*
71     The actual key.
72    */
73   my_hash_value_type hash_value;
74 
75   /**
76     Length of the key.
77    */
78   uint length;
79 
80   /**
81     The search state used to iterate over multiple entries for a
82     given key.
83    */
84   HASH_SEARCH_STATE search_state;
85 
86   /**
87     Wether this search_state is usable or not.
88    */
89   bool is_search_state_inited;
90 
91 } HASH_ROW_PREAMBLE;
92 
93 typedef struct hash_row_entry_st
94 {
95   HASH_ROW_PREAMBLE *preamble;
96   HASH_ROW_POS *positions;
97 } HASH_ROW_ENTRY;
98 
99 class Hash_slave_rows
100 {
101 public:
102 
103   /**
104      Allocates an empty entry to be added to the hash table.
105      It should be called before calling member function @c put.
106 
107      @returns NULL if a problem occured, a valid pointer otherwise.
108   */
109   HASH_ROW_ENTRY* make_entry();
110 
111   /**
112      Allocates an entry to be added to the hash table. It should be
113      called before calling member function @c put.
114 
115      @param bi_start the position to where in the rows buffer the
116                      before image begins.
117      @param bi_ends  the position to where in the rows buffer the
118                      before image ends.
119      @returns NULL if a problem occured, a valid pointer otherwise.
120    */
121   HASH_ROW_ENTRY* make_entry(const uchar *bi_start, const uchar *bi_ends);
122 
123 
124   /**
125      Puts data into the hash table. It calculates the key taking
126      the data on @c TABLE::record as the input for hash computation.
127 
128      @param table   The table holding the buffer used to calculate the
129                     key, ie, table->record[0].
130      @param cols    The read_set bitmap signaling which columns are used.
131      @param entry   The entry with the values to store.
132 
133      @returns true if something went wrong, false otherwise.
134    */
135   bool put(TABLE* table, MY_BITMAP *cols, HASH_ROW_ENTRY* entry);
136 
137   /**
138      Gets the entry, from the hash table, that matches the data in
139      table->record[0] and signaled using cols.
140 
141      @param table   The table holding the buffer containing data used to
142                     make the entry lookup.
143      @param cols    Bitmap signaling which columns, from
144                     table->record[0], should be used.
145 
146      @returns a pointer that will hold a reference to the entry
147               found. If the entry is not found then NULL shall be
148               returned.
149    */
150   HASH_ROW_ENTRY* get(TABLE *table, MY_BITMAP *cols);
151 
152   /**
153      Gets the entry that stands next to the one pointed to by
154      *entry. Before calling this member function, the entry that one
155      uses as parameter must have: 1. been obtained through get() or
156      next() invocations; and 2. must have not been used before in a
157      next() operation.
158 
159      @param entry[IN/OUT] contains a pointer to an entry that we can
160                           use to search for another adjacent entry
161                           (ie, that shares the same key).
162 
163      @returns true if something went wrong, false otherwise. In the
164               case that this entry was already used in a next()
165               operation this member function returns true and does not
166               update the pointer.
167    */
168   bool next(HASH_ROW_ENTRY** entry);
169 
170   /**
171      Deletes the entry pointed by entry. It also frees memory used
172      holding entry contents. This is the way to release memeory
173      used for entry, freeing it explicitly with my_free will cause
174      undefined behavior.
175 
176      @param entry  Pointer to the entry to be deleted.
177      @returns true if something went wrong, false otherwise.
178    */
179   bool del(HASH_ROW_ENTRY* entry);
180 
181   /**
182      Initializes the hash table.
183 
184      @returns true if something went wrong, false otherwise.
185    */
186   bool init(void);
187 
188   /**
189      De-initializes the hash table.
190 
191      @returns true if something went wrong, false otherwise.
192    */
193   bool deinit(void);
194 
195   /**
196      Checks if the hash table is empty or not.
197 
198      @returns true if the hash table has zero entries, false otherwise.
199    */
200   bool is_empty(void);
201 
202   /**
203      Returns the number of entries in the hash table.
204 
205      @returns the number of entries in the hash table.
206    */
207   int size();
208 
209 private:
210 
211   /**
212      The hashtable itself.
213    */
214   HASH m_hash;
215 
216   /**
217      Auxiliar and internal method used to create an hash key, based on
218      the data in table->record[0] buffer and signaled as used in cols.
219 
220      @param table  The table that is being scanned
221      @param cols   The read_set bitmap signaling which columns are used.
222 
223      @retuns the hash key created.
224    */
225   my_hash_value_type make_hash_key(TABLE *table, MY_BITMAP* cols);
226 };
227 
228 #endif
229 
230 /**
231   A table definition from the master.
232 
233   The responsibilities of this class is:
234   - Extract and decode table definition data from the table map event
235   - Check if table definition in table map is compatible with table
236     definition on slave
237  */
238 
239 class table_def
240 {
241 public:
242   /**
243     Constructor.
244 
245     @param types Array of types, each stored as a byte
246     @param size  Number of elements in array 'types'
247     @param field_metadata Array of extra information about fields
248     @param metadata_size Size of the field_metadata array
249     @param null_bitmap The bitmap of fields that can be null
250    */
251   table_def(unsigned char *types, ulong size, uchar *field_metadata,
252             int metadata_size, uchar *null_bitmap, uint16 flags);
253 
254   ~table_def();
255 
256   /**
257     Return the number of fields there is type data for.
258 
259     @return The number of fields that there is type data for.
260    */
size()261   ulong size() const { return m_size; }
262 
263 
264   /*
265     Returns internal binlog type code for one field,
266     without translation to real types.
267   */
binlog_type(ulong index)268   enum_field_types binlog_type(ulong index) const
269   {
270     return static_cast<enum_field_types>(m_type[index]);
271   }
272   /*
273     Return a representation of the type data for one field.
274 
275     @param index Field index to return data for
276 
277     @return Will return a representation of the type data for field
278     <code>index</code>. Currently, only the type identifier is
279     returned.
280    */
type(ulong index)281   enum_field_types type(ulong index) const
282   {
283     DBUG_ASSERT(index < m_size);
284     /*
285       If the source type is MYSQL_TYPE_STRING, it can in reality be
286       either MYSQL_TYPE_STRING, MYSQL_TYPE_ENUM, or MYSQL_TYPE_SET, so
287       we might need to modify the type to get the real type.
288     */
289     enum_field_types source_type= binlog_type(index);
290     uint16 source_metadata= m_field_metadata[index];
291     switch (source_type)
292     {
293     case MYSQL_TYPE_STRING:
294     {
295       int real_type= source_metadata >> 8;
296       if (real_type == MYSQL_TYPE_ENUM || real_type == MYSQL_TYPE_SET)
297         source_type= static_cast<enum_field_types>(real_type);
298       break;
299     }
300 
301     /*
302       This type has not been used since before row-based replication,
303       so we can safely assume that it really is MYSQL_TYPE_NEWDATE.
304     */
305     case MYSQL_TYPE_DATE:
306       source_type= MYSQL_TYPE_NEWDATE;
307       break;
308 
309     default:
310       /* Do nothing */
311       break;
312     }
313 
314     return source_type;
315   }
316 
317 
318   /*
319     This function allows callers to get the extra field data from the
320     table map for a given field. If there is no metadata for that field
321     or there is no extra metadata at all, the function returns 0.
322 
323     The function returns the value for the field metadata for column at
324     position indicated by index. As mentioned, if the field was a type
325     that stores field metadata, that value is returned else zero (0) is
326     returned. This method is used in the unpack() methods of the
327     corresponding fields to properly extract the data from the binary log
328     in the event that the master's field is smaller than the slave.
329   */
field_metadata(uint index)330   uint16 field_metadata(uint index) const
331   {
332     DBUG_ASSERT(index < m_size);
333     if (m_field_metadata_size)
334       return m_field_metadata[index];
335     else
336       return 0;
337   }
338 
339   /*
340     This function returns whether the field on the master can be null.
341     This value is derived from field->maybe_null().
342   */
maybe_null(uint index)343   my_bool maybe_null(uint index) const
344   {
345     DBUG_ASSERT(index < m_size);
346     return ((m_null_bits[(index / 8)] &
347             (1 << (index % 8))) == (1 << (index %8)));
348   }
349 
350   /*
351     This function returns the field size in raw bytes based on the type
352     and the encoded field data from the master's raw data. This method can
353     be used for situations where the slave needs to skip a column (e.g.,
354     WL#3915) or needs to advance the pointer for the fields in the raw
355     data from the master to a specific column.
356   */
357   uint32 calc_field_size(uint col, uchar *master_data) const;
358 
359   /**
360     Decide if the table definition is compatible with a table.
361 
362     Compare the definition with a table to see if it is compatible
363     with it.
364 
365     A table definition is compatible with a table if:
366       - The columns types of the table definition is a (not
367         necessarily proper) prefix of the column type of the table.
368 
369       - The other way around.
370 
371       - Each column on the master that also exists on the slave can be
372         converted according to the current settings of @c
373         SLAVE_TYPE_CONVERSIONS.
374 
375     @param thd
376     @param rli   Pointer to relay log info
377     @param table Pointer to table to compare with.
378 
379     @param[out] tmp_table_var Pointer to temporary table for holding
380     conversion table.
381 
382     @retval 1  if the table definition is not compatible with @c table
383     @retval 0  if the table definition is compatible with @c table
384   */
385 #ifndef MYSQL_CLIENT
386   bool compatible_with(THD *thd, Relay_log_info *rli, TABLE *table,
387                       TABLE **conv_table_var) const;
388 
389   /**
390    Create a virtual in-memory temporary table structure.
391 
392    The table structure has records and field array so that a row can
393    be unpacked into the record for further processing.
394 
395    In the virtual table, each field that requires conversion will
396    have a non-NULL value, while fields that do not require
397    conversion will have a NULL value.
398 
399    Some information that is missing in the events, such as the
400    character set for string types, are taken from the table that the
401    field is going to be pushed into, so the target table that the data
402    eventually need to be pushed into need to be supplied.
403 
404    @param thd Thread to allocate memory from.
405    @param rli Relay log info structure, for error reporting.
406    @param target_table Target table for fields.
407 
408    @return A pointer to a temporary table with memory allocated in the
409    thread's memroot, NULL if the table could not be created
410    */
411   TABLE *create_conversion_table(THD *thd, Relay_log_info *rli, TABLE *target_table) const;
412 #endif
413 
414 
415 private:
416   ulong m_size;           // Number of elements in the types array
417   unsigned char *m_type;  // Array of type descriptors
418   uint m_field_metadata_size;
419   uint16 *m_field_metadata;
420   uchar *m_null_bits;
421   uint16 m_flags;         // Table flags
422   uchar *m_memory;
423 };
424 
425 
426 #ifndef MYSQL_CLIENT
427 /**
428    Extend the normal table list with a few new fields needed by the
429    slave thread, but nowhere else.
430  */
431 struct RPL_TABLE_LIST
432   : public TABLE_LIST
433 {
434   bool m_tabledef_valid;
435   table_def m_tabledef;
436   TABLE *m_conv_table;
437 };
438 
439 
440 /* Anonymous namespace for template functions/classes */
441 CPP_UNNAMED_NS_START
442 
443   /*
444     Smart pointer that will automatically call my_afree (a macro) when
445     the pointer goes out of scope.  This is used so that I do not have
446     to remember to call my_afree() before each return.  There is no
447     overhead associated with this, since all functions are inline.
448 
449     I (Matz) would prefer to use the free function as a template
450     parameter, but that is not possible when the "function" is a
451     macro.
452   */
453   template <class Obj>
454   class auto_afree_ptr
455   {
456     Obj* m_ptr;
457   public:
auto_afree_ptr(Obj * ptr)458     auto_afree_ptr(Obj* ptr) : m_ptr(ptr) { }
~auto_afree_ptr()459     ~auto_afree_ptr() { if (m_ptr) my_afree(m_ptr); }
assign(Obj * ptr)460     void assign(Obj* ptr) {
461       /* Only to be called if it hasn't been given a value before. */
462       DBUG_ASSERT(m_ptr == NULL);
463       m_ptr= ptr;
464     }
get()465     Obj* get() { return m_ptr; }
466   };
467 
468 CPP_UNNAMED_NS_END
469 
470 class Deferred_log_events
471 {
472 private:
473   DYNAMIC_ARRAY array;
474 
475 public:
476   Deferred_log_events(Relay_log_info *rli);
477   ~Deferred_log_events();
478   /* queue for exection at Query-log-event time prior the Query */
479   int add(Log_event *ev);
480   bool is_empty();
481   bool execute(Relay_log_info *rli);
482   void rewind();
483 };
484 
485 #endif
486 
487 // NB. number of printed bit values is limited to sizeof(buf) - 1
488 #define DBUG_PRINT_BITSET(N,FRM,BS)                \
489   do {                                             \
490     char buf[256];                                 \
491     uint i;                                        \
492     for (i = 0 ; i < MY_MIN(sizeof(buf) - 1, (BS)->n_bits) ; i++) \
493       buf[i] = bitmap_is_set((BS), i) ? '1' : '0'; \
494     buf[i] = '\0';                                 \
495     DBUG_PRINT((N), ((FRM), buf));                 \
496   } while (0)
497 
498 #endif /* RPL_UTILITY_H */
499 
500