My Project
log_event_old.h
Go to the documentation of this file.
00001 /* Copyright (c) 2007, 2013, 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 LOG_EVENT_OLD_H
00017 #define LOG_EVENT_OLD_H
00018 
00019 /*
00020   Need to include this file at the proper position of log_event.h
00021  */
00022 
00023 
00030 /*
00031   Around 2007-10-31, I made these classes completely separated from
00032   the new classes (before, there was a complex class hierarchy
00033   involving multiple inheritance; see BUG#31581), by simply copying
00034   and pasting the entire contents of Rows_log_event into
00035   Old_rows_log_event and the entire contents of
00036   {Write|Update|Delete}_rows_log_event into
00037   {Write|Update|Delete}_rows_log_event_old.  For clarity, I will keep
00038   the comments marking which code was cut-and-pasted for some time.
00039   With the classes collapsed into one, there is probably some
00040   redundancy (maybe some methods can be simplified and/or removed),
00041   but we keep them this way for now.  /Sven
00042 */
00043 
00044 /* These classes are based on the v1 RowsHeaderLen */
00045 #define ROWS_HEADER_LEN ROWS_HEADER_LEN_V1
00046 
00056 class Old_rows_log_event : public Log_event
00057 {
00058   /********** BEGIN CUT & PASTE FROM Rows_log_event **********/
00059 public:
00063   enum enum_error
00064   {
00065     ERR_OPEN_FAILURE = -1,               
00066     ERR_OK = 0,                                 
00067     ERR_TABLE_LIMIT_EXCEEDED = 1,      
00068     ERR_OUT_OF_MEM = 2,                         
00069     ERR_BAD_TABLE_DEF = 3,     
00070     ERR_RBR_TO_SBR = 4  
00071   };
00072 
00073   /*
00074     These definitions allow you to combine the flags into an
00075     appropriate flag set using the normal bitwise operators.  The
00076     implicit conversion from an enum-constant to an integer is
00077     accepted by the compiler, which is then used to set the real set
00078     of flags.
00079   */
00080   enum enum_flag
00081   {
00082     /* Last event of a statement */
00083     STMT_END_F = (1U << 0),
00084 
00085     /* Value of the OPTION_NO_FOREIGN_KEY_CHECKS flag in thd->options */
00086     NO_FOREIGN_KEY_CHECKS_F = (1U << 1),
00087 
00088     /* Value of the OPTION_RELAXED_UNIQUE_CHECKS flag in thd->options */
00089     RELAXED_UNIQUE_CHECKS_F = (1U << 2),
00090 
00095     COMPLETE_ROWS_F = (1U << 3)
00096   };
00097 
00098   typedef uint16 flag_set;
00099 
00100   /* Special constants representing sets of flags */
00101   enum 
00102   {
00103       RLE_NO_FLAGS = 0U
00104   };
00105 
00106   virtual ~Old_rows_log_event();
00107 
00108   void set_flags(flag_set flags_arg) { m_flags |= flags_arg; }
00109   void clear_flags(flag_set flags_arg) { m_flags &= ~flags_arg; }
00110   flag_set get_flags(flag_set flags_arg) const { return m_flags & flags_arg; }
00111 
00112 #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
00113   virtual int pack_info(Protocol *protocol);
00114 #endif
00115 
00116 #ifdef MYSQL_CLIENT
00117   /* not for direct call, each derived has its own ::print() */
00118   virtual void print(FILE *file, PRINT_EVENT_INFO *print_event_info)= 0;
00119 #endif
00120 
00121 #ifndef MYSQL_CLIENT
00122   int add_row_data(uchar *data, size_t length)
00123   {
00124     return do_add_row_data(data,length); 
00125   }
00126 #endif
00127 
00128   /* Member functions to implement superclass interface */
00129   virtual int get_data_size();
00130 
00131   MY_BITMAP const *get_cols() const { return &m_cols; }
00132   size_t get_width() const          { return m_width; }
00133   const Table_id& get_table_id() const { return m_table_id; }
00134 
00135 #ifndef MYSQL_CLIENT
00136   virtual bool write_data_header(IO_CACHE *file);
00137   virtual bool write_data_body(IO_CACHE *file);
00138   virtual const char *get_db() { return m_table->s->db.str; }
00139 #endif
00140   /*
00141     Check that malloc() succeeded in allocating memory for the rows
00142     buffer and the COLS vector. Checking that an Update_rows_log_event_old
00143     is valid is done in the Update_rows_log_event_old::is_valid()
00144     function.
00145   */
00146   virtual bool is_valid() const
00147   {
00148     return m_rows_buf && m_cols.bitmap;
00149   }
00150 
00151   uint     m_row_count;         /* The number of rows added to the event */
00152 
00153 protected:
00154   /* 
00155      The constructors are protected since you're supposed to inherit
00156      this class, not create instances of this class.
00157   */
00158 #ifndef MYSQL_CLIENT
00159   Old_rows_log_event(THD*, TABLE*, ulong table_id,
00160                      MY_BITMAP const *cols, bool is_transactional);
00161 #endif
00162   Old_rows_log_event(const char *row_data, uint event_len,
00163                      Log_event_type event_type,
00164                      const Format_description_log_event *description_event);
00165 
00166 #ifdef MYSQL_CLIENT
00167   void print_helper(FILE *, PRINT_EVENT_INFO *, char const *const name);
00168 #endif
00169 
00170 #ifndef MYSQL_CLIENT
00171   virtual int do_add_row_data(uchar *data, size_t length);
00172 #endif
00173 
00174 #ifndef MYSQL_CLIENT
00175   TABLE *m_table;               /* The table the rows belong to */
00176 #endif
00177   Table_id    m_table_id;       /* Table ID */
00178   MY_BITMAP   m_cols;           /* Bitmap denoting columns available */
00179   ulong       m_width;          /* The width of the columns bitmap */
00180 
00181   ulong       m_master_reclength; /* Length of record on master side */
00182 
00183   /* Bit buffers in the same memory as the class */
00184   uint32    m_bitbuf[128/(sizeof(uint32)*8)];
00185   uint32    m_bitbuf_ai[128/(sizeof(uint32)*8)];
00186 
00187   uchar    *m_rows_buf;         /* The rows in packed format */
00188   uchar    *m_rows_cur;         /* One-after the end of the data */
00189   uchar    *m_rows_end;         /* One-after the end of the allocated space */
00190 
00191   flag_set m_flags;             /* Flags for row-level events */
00192 
00193   /* helper functions */
00194 
00195 #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
00196   const uchar *m_curr_row;     /* Start of the row being processed */
00197   const uchar *m_curr_row_end; /* One-after the end of the current row */
00198   uchar    *m_key;      /* Buffer to keep key value during searches */
00199 
00200   int find_row(const Relay_log_info *const);
00201   int write_row(const Relay_log_info *const, const bool);
00202 
00203   // Unpack the current row into m_table->record[0]
00204   int unpack_current_row(const Relay_log_info *const rli)
00205   { 
00206     DBUG_ASSERT(m_table);
00207     ASSERT_OR_RETURN_ERROR(m_curr_row < m_rows_end, HA_ERR_CORRUPT_EVENT);
00208     return ::unpack_row(rli, m_table, m_width, m_curr_row, &m_cols,
00209                                    &m_curr_row_end, &m_master_reclength, m_rows_end);
00210   }
00211 #endif
00212 
00213 private:
00214 
00215 #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
00216   virtual int do_apply_event(Relay_log_info const *rli);
00217   virtual int do_update_pos(Relay_log_info *rli);
00218   virtual enum_skip_reason do_shall_skip(Relay_log_info *rli);
00219 
00220   /*
00221     Primitive to prepare for a sequence of row executions.
00222 
00223     DESCRIPTION
00224 
00225       Before doing a sequence of do_prepare_row() and do_exec_row()
00226       calls, this member function should be called to prepare for the
00227       entire sequence. Typically, this member function will allocate
00228       space for any buffers that are needed for the two member
00229       functions mentioned above.
00230 
00231     RETURN VALUE
00232 
00233       The member function will return 0 if all went OK, or a non-zero
00234       error code otherwise.
00235   */
00236   virtual 
00237   int do_before_row_operations(const Slave_reporting_capability *const log) = 0;
00238 
00239   /*
00240     Primitive to clean up after a sequence of row executions.
00241 
00242     DESCRIPTION
00243     
00244       After doing a sequence of do_prepare_row() and do_exec_row(),
00245       this member function should be called to clean up and release
00246       any allocated buffers.
00247       
00248       The error argument, if non-zero, indicates an error which happened during
00249       row processing before this function was called. In this case, even if 
00250       function is successful, it should return the error code given in the argument.
00251   */
00252   virtual 
00253   int do_after_row_operations(const Slave_reporting_capability *const log,
00254                               int error) = 0;
00255 
00256   /*
00257     Primitive to do the actual execution necessary for a row.
00258 
00259     DESCRIPTION
00260       The member function will do the actual execution needed to handle a row.
00261       The row is located at m_curr_row. When the function returns, 
00262       m_curr_row_end should point at the next row (one byte after the end
00263       of the current row).    
00264 
00265     RETURN VALUE
00266       0 if execution succeeded, 1 if execution failed.
00267       
00268   */
00269   virtual int do_exec_row(const Relay_log_info *const rli) = 0;
00270 #endif /* !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) */
00271 
00272   /********** END OF CUT & PASTE FROM Rows_log_event **********/
00273  protected:
00274   
00275 #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
00276 
00277   int do_apply_event(Old_rows_log_event*,const Relay_log_info*);
00278 
00279   /*
00280     Primitive to prepare for a sequence of row executions.
00281 
00282     DESCRIPTION
00283 
00284       Before doing a sequence of do_prepare_row() and do_exec_row()
00285       calls, this member function should be called to prepare for the
00286       entire sequence. Typically, this member function will allocate
00287       space for any buffers that are needed for the two member
00288       functions mentioned above.
00289 
00290     RETURN VALUE
00291 
00292       The member function will return 0 if all went OK, or a non-zero
00293       error code otherwise.
00294   */
00295   virtual int do_before_row_operations(TABLE *table) = 0;
00296 
00297   /*
00298     Primitive to clean up after a sequence of row executions.
00299 
00300     DESCRIPTION
00301     
00302       After doing a sequence of do_prepare_row() and do_exec_row(),
00303       this member function should be called to clean up and release
00304       any allocated buffers.
00305   */
00306   virtual int do_after_row_operations(TABLE *table, int error) = 0;
00307 
00308   /*
00309     Primitive to prepare for handling one row in a row-level event.
00310     
00311     DESCRIPTION 
00312 
00313       The member function prepares for execution of operations needed for one
00314       row in a row-level event by reading up data from the buffer containing
00315       the row. No specific interpretation of the data is normally done here,
00316       since SQL thread specific data is not available: that data is made
00317       available for the do_exec function.
00318 
00319       A pointer to the start of the next row, or NULL if the preparation
00320       failed. Currently, preparation cannot fail, but don't rely on this
00321       behavior. 
00322 
00323     RETURN VALUE
00324       Error code, if something went wrong, 0 otherwise.
00325    */
00326   virtual int do_prepare_row(THD*, Relay_log_info const*, TABLE*,
00327                              uchar const *row_start,
00328                              uchar const **row_end) = 0;
00329 
00330   /*
00331     Primitive to do the actual execution necessary for a row.
00332 
00333     DESCRIPTION
00334       The member function will do the actual execution needed to handle a row.
00335 
00336     RETURN VALUE
00337       0 if execution succeeded, 1 if execution failed.
00338       
00339   */
00340   virtual int do_exec_row(TABLE *table) = 0;
00341 
00342 #endif /* !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) */
00343 };
00344 
00345 
00355 class Write_rows_log_event_old : public Old_rows_log_event
00356 {
00357   /********** BEGIN CUT & PASTE FROM Write_rows_log_event **********/
00358 public:
00359 #if !defined(MYSQL_CLIENT)
00360   Write_rows_log_event_old(THD*, TABLE*, ulong table_id,
00361                            MY_BITMAP const *cols,
00362                            bool is_transactional);
00363 #endif
00364 #ifdef HAVE_REPLICATION
00365   Write_rows_log_event_old(const char *buf, uint event_len,
00366                            const Format_description_log_event *description_event);
00367 #endif
00368 #if !defined(MYSQL_CLIENT) 
00369   static bool binlog_row_logging_function(THD *thd, TABLE *table,
00370                                           bool is_transactional,
00371                                           const uchar *before_record
00372                                           __attribute__((unused)),
00373                                           const uchar *after_record)
00374   {
00375     return thd->binlog_write_row(table, is_transactional,
00376                                  after_record, NULL);
00377   }
00378 #endif
00379 
00380 private:
00381 #ifdef MYSQL_CLIENT
00382   void print(FILE *file, PRINT_EVENT_INFO *print_event_info);
00383 #endif
00384 
00385 #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
00386   virtual int do_before_row_operations(const Slave_reporting_capability *const);
00387   virtual int do_after_row_operations(const Slave_reporting_capability *const,int);
00388   virtual int do_exec_row(const Relay_log_info *const);
00389 #endif
00390   /********** END OF CUT & PASTE FROM Write_rows_log_event **********/
00391 
00392 public:
00393   enum
00394   {
00395     /* Support interface to THD::binlog_prepare_pending_rows_event */
00396     TYPE_CODE = PRE_GA_WRITE_ROWS_EVENT
00397   };
00398 
00399 private:
00400   virtual Log_event_type get_type_code() { return (Log_event_type)TYPE_CODE; }
00401 
00402 #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
00403   // use old definition of do_apply_event()
00404   virtual int do_apply_event(const Relay_log_info *rli)
00405   { return Old_rows_log_event::do_apply_event(this,rli); }
00406 
00407   // primitives for old version of do_apply_event()
00408   virtual int do_before_row_operations(TABLE *table);
00409   virtual int do_after_row_operations(TABLE *table, int error);
00410   virtual int do_prepare_row(THD*, Relay_log_info const*, TABLE*,
00411                              uchar const *row_start, uchar const **row_end);
00412   virtual int do_exec_row(TABLE *table);
00413 
00414 #endif
00415 };
00416 
00417 
00428 class Update_rows_log_event_old : public Old_rows_log_event
00429 {
00430   /********** BEGIN CUT & PASTE FROM Update_rows_log_event **********/
00431 public:
00432 #ifndef MYSQL_CLIENT
00433   Update_rows_log_event_old(THD*, TABLE*, ulong table_id,
00434                             MY_BITMAP const *cols,
00435                             bool is_transactional);
00436 #endif
00437 
00438 #ifdef HAVE_REPLICATION
00439   Update_rows_log_event_old(const char *buf, uint event_len,
00440                             const Format_description_log_event *description_event);
00441 #endif
00442 
00443 #if !defined(MYSQL_CLIENT) 
00444   static bool binlog_row_logging_function(THD *thd, TABLE *table,
00445                                           bool is_transactional,
00446                                           const uchar *before_record,
00447                                           const uchar *after_record)
00448   {
00449     return thd->binlog_update_row(table, is_transactional,
00450                                   before_record, after_record, NULL);
00451   }
00452 #endif
00453 
00454 protected:
00455 #ifdef MYSQL_CLIENT
00456   void print(FILE *file, PRINT_EVENT_INFO *print_event_info);
00457 #endif
00458 
00459 #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
00460   virtual int do_before_row_operations(const Slave_reporting_capability *const);
00461   virtual int do_after_row_operations(const Slave_reporting_capability *const,int);
00462   virtual int do_exec_row(const Relay_log_info *const);
00463 #endif /* !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) */
00464   /********** END OF CUT & PASTE FROM Update_rows_log_event **********/
00465 
00466   uchar *m_after_image, *m_memory;
00467   
00468 public:
00469   enum 
00470   {
00471     /* Support interface to THD::binlog_prepare_pending_rows_event */
00472     TYPE_CODE = PRE_GA_UPDATE_ROWS_EVENT
00473   };
00474 
00475 private:
00476   virtual Log_event_type get_type_code() { return (Log_event_type)TYPE_CODE; }
00477 
00478 #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
00479   // use old definition of do_apply_event()
00480   virtual int do_apply_event(const Relay_log_info *rli)
00481   { return Old_rows_log_event::do_apply_event(this,rli); }
00482 
00483   // primitives for old version of do_apply_event()
00484   virtual int do_before_row_operations(TABLE *table);
00485   virtual int do_after_row_operations(TABLE *table, int error);
00486   virtual int do_prepare_row(THD*, Relay_log_info const*, TABLE*,
00487                              uchar const *row_start, uchar const **row_end);
00488   virtual int do_exec_row(TABLE *table);
00489 #endif /* !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) */
00490 };
00491 
00492 
00503 class Delete_rows_log_event_old : public Old_rows_log_event
00504 {
00505   /********** BEGIN CUT & PASTE FROM Update_rows_log_event **********/
00506 public:
00507 #ifndef MYSQL_CLIENT
00508   Delete_rows_log_event_old(THD*, TABLE*, ulong,
00509                             MY_BITMAP const *cols,
00510                             bool is_transactional);
00511 #endif
00512 #ifdef HAVE_REPLICATION
00513   Delete_rows_log_event_old(const char *buf, uint event_len,
00514                             const Format_description_log_event *description_event);
00515 #endif
00516 #if !defined(MYSQL_CLIENT) 
00517   static bool binlog_row_logging_function(THD *thd, TABLE *table,
00518                                           bool is_transactional,
00519                                           const uchar *before_record,
00520                                           const uchar *after_record
00521                                           __attribute__((unused)))
00522   {
00523     return thd->binlog_delete_row(table, is_transactional,
00524                                   before_record, NULL);
00525   }
00526 #endif
00527   
00528 protected:
00529 #ifdef MYSQL_CLIENT
00530   void print(FILE *file, PRINT_EVENT_INFO *print_event_info);
00531 #endif
00532 
00533 #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
00534   virtual int do_before_row_operations(const Slave_reporting_capability *const);
00535   virtual int do_after_row_operations(const Slave_reporting_capability *const,int);
00536   virtual int do_exec_row(const Relay_log_info *const);
00537 #endif
00538   /********** END CUT & PASTE FROM Delete_rows_log_event **********/
00539 
00540   uchar *m_after_image, *m_memory;
00541  
00542 public:
00543   enum 
00544   {
00545     /* Support interface to THD::binlog_prepare_pending_rows_event */
00546     TYPE_CODE = PRE_GA_DELETE_ROWS_EVENT
00547   };
00548 
00549 private:
00550   virtual Log_event_type get_type_code() { return (Log_event_type)TYPE_CODE; }
00551 
00552 #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
00553   // use old definition of do_apply_event()
00554   virtual int do_apply_event(const Relay_log_info *rli)
00555   { return Old_rows_log_event::do_apply_event(this,rli); }
00556 
00557   // primitives for old version of do_apply_event()
00558   virtual int do_before_row_operations(TABLE *table);
00559   virtual int do_after_row_operations(TABLE *table, int error);
00560   virtual int do_prepare_row(THD*, Relay_log_info const*, TABLE*,
00561                              uchar const *row_start, uchar const **row_end);
00562   virtual int do_exec_row(TABLE *table);
00563 #endif
00564 };
00565 
00566 
00567 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines