1 /* Copyright (c) 2014, 2021, Oracle and/or its affiliates.
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 /**
24   @addtogroup Replication
25   @{
26 
27   @file load_data_events.h
28 
29   @brief LOAD DATA INFILE is not written to the binary log like other
30   statements. It is written as one or more events in a packed format,
31   not as a cleartext statement in the binary log. The events indicate
32   what options are present in the statement and how to process the data file.
33 */
34 
35 #ifndef LOAD_DATA_EVENTS_INCLUDED
36 #define	LOAD_DATA_EVENTS_INCLUDED
37 
38 #include "statement_events.h"
39 #include "table_id.h"
40 
41 /*
42   These are flags and structs to handle all the LOAD DATA INFILE options (LINES
43   TERMINATED etc).
44   DUMPFILE_FLAG is probably not used (DUMPFILE is a clause of SELECT,
45   not of LOAD DATA).
46 */
47 #define DUMPFILE_FLAG           0x1
48 #define OPT_ENCLOSED_FLAG       0x2
49 #define REPLACE_FLAG            0x4
50 #define IGNORE_FLAG             0x8
51 
52 #define FIELD_TERM_EMPTY        0x1
53 #define ENCLOSED_EMPTY          0x2
54 #define LINE_TERM_EMPTY         0x4
55 #define LINE_START_EMPTY        0x8
56 #define ESCAPED_EMPTY           0x10
57 
58 namespace binary_log
59 {
60 /**
61   @struct old_sql_ex
62 
63   This structure holds the single character field/line options in the
64   LOAD_DATA_INFILE statement. It is used for server versions prior to
65   5.0.3, where a single character separator was supported for
66   LOAD_DATA_INFILE statements.
67 
68   The structure contains the foloowing components.
69   <table>
70   <caption>old_sql_ex members for Load_event</caption>
71 
72   <tr>
73     <th>Name</th>
74     <th>Format</th>
75     <th>Description</th>
76   </tr>
77 
78   <tr>
79     <td>field_term</td>
80     <td>a single character</td>
81     <td>field terminating character spcified by the subclause
82         'FIELDS TERMINATED BY'
83     </td>
84   </tr>
85 
86   <tr>
87     <td>enclosed</td>
88     <td>a single character</td>
89     <td>character used for enclosing field data, specified by
90         the subclause 'FIELDS ENCLOSED BY'
91     </td>
92   </tr>
93 
94   <tr>
95     <td>line_term</td>
96     <td>a single character</td>
97     <td>line terminating character, specified by the subclause
98         'LINES TERMINATED BY'
99     </td>
100   </tr>
101 
102   <tr>
103     <td>line_start</td>
104     <td>a single character</td>
105     <td>character indicating the start of a line, specified by
106        the subclause 'LINES STARTING BY'
107     </td>
108   </tr>
109 
110   <tr>
111     <td>escaped</td>
112     <td>a single character</td>
113     <td>escape character for a field, specified by the subclause
114        'FIELD ESCAPED BY'
115     </td>
116   </tr>
117 
118   <tr>
119     <td>opt_flags</td>
120     <td>8 bit bitfield value </td>
121     <td>bitfield indicating the presence of the keywords REPLACE,
122         IGNORE, and OPTIONALLY
123     </td>
124   </tr>
125 
126   <tr>
127     <td>empty_flags</td>
128     <td>8 bit bitfield value </td>
129     <td>The low 5 bits of empty_flags indicate which of the five strings
130         have length 0.  For each of the following flags that is set, the
131         corresponding string has length 0; for the flags that are not set,
132         the string has length 1: FIELD_TERM_EMPTY==0x1,
133         ENCLOSED_EMPTY==0x2, LINE_TERM_EMPTY==0x4, LINE_START_EMPTY==0x8,
134         ESCAPED_EMPTY==0x10.
135     </td>
136   </tr>
137 */
138 struct old_sql_ex
139 {
140   char field_term;
141   char enclosed;
142   char line_term;
143   char line_start;
144   char escaped;
145   char opt_flags;
146   char empty_flags;
147 };
148 
149 /**
150   @struct sql_ex_data_info
151 
152   This structure holds the multi character field/line options in the
153   LOAD_DATA_INFILE statement. It is used for server versions newer than
154   5.0.3, where multicharacter separators were supported for
155   LOAD_DATA_INFILE SQL Query.
156 
157   The structure is simlar to old_sql_ex defined above.
158   The new and old format differ in the way the five strings indicating the
159   terminating characters in the query are stored.
160 
161   To know more, read comments in the class Load_event and struct
162   old_sql_ex.
163 */
164 struct sql_ex_data_info
165 {
sql_ex_data_infosql_ex_data_info166   sql_ex_data_info()
167   : cached_new_format(0)
168   {
169   }
170   const char* field_term;
171   const char* enclosed;
172   const char* line_term;
173   const char* line_start;
174   const char* escaped;
175   uint8_t field_term_len, enclosed_len, line_term_len,
176           line_start_len, escaped_len;
177 
178   char opt_flags;
179   char empty_flags;
180 
181   int cached_new_format;
182 
183   /** store in new format even if old is possible */
force_new_formatsql_ex_data_info184   void force_new_format() { cached_new_format = 1;}
data_sizesql_ex_data_info185   int data_size()
186   {
187     return (new_format() ?
188             field_term_len + enclosed_len + line_term_len +
189             line_start_len + escaped_len + 6 : 7);
190   }
191   const char* init(const char* buf, const char* buf_end, bool use_new_format);
new_formatsql_ex_data_info192   bool new_format()
193   {
194     return ((cached_new_format != -1) ? cached_new_format :
195             (cached_new_format= (field_term_len > 1 ||
196                                  enclosed_len > 1 ||
197                                  line_term_len > 1 || line_start_len > 1 ||
198                                  escaped_len > 1)));
199   }
200 };
201 
202 /**
203   Elements of this enum describe how LOAD DATA handles duplicates.
204 */
205 enum enum_load_dup_handling
206 {
207   LOAD_DUP_ERROR= 0,
208   LOAD_DUP_IGNORE,
209   LOAD_DUP_REPLACE
210 };
211 
212 /**
213   @class Execute_load_query_event
214 
215   Event responsible for LOAD DATA execution, it similar to Query_event
216   but before executing the query it substitutes original filename in LOAD DATA
217   query with name of temporary file.
218 
219   The first 13 bytes of the Post-Header for this event are the same as for
220   Query_event, as is the initial status variable block in the Body.
221 
222   @section Execute_load_query_event_binary_format Binary Format
223 
224   The additional members of the events are the following:
225 
226    <table>
227    <caption>Body for Execute_load_query_event</caption>
228 
229    <tr>
230      <th>Name</th>
231      <th>Format</th>
232      <th>Description</th>
233    </tr>
234 
235    <tr>
236      <td>file_id</td>
237      <td>4 byte unsigned integer</td>
238      <td>ID of the temporary file to load</td>
239    </tr>
240 
241    <tr>
242      <td>fn_pos_start</td>
243      <td>4 byte unsigned integer</td>
244      <td>The start position within the statement for filename substitution</td>
245    </tr>
246    <tr>
247 
248      <td>fn_pos_end</td>
249      <td>4 byte unsigned integer</td>
250      <td>The end position within the statement for filename substitution</td>
251    </tr>
252 
253    <tr>
254      <td>dup_handling</td>
255      <td>enum_load_dup_handling</td>
256      <td>Represents information on how to handle duplicates:
257           LOAD_DUP_ERROR= 0, LOAD_DUP_IGNORE= 1, LOAD_DUP_REPLACE= 2</td>
258    </tr>
259 */
260 class Execute_load_query_event : public virtual Query_event
261 {
262 public:
263   enum Execute_load_query_event_offset{
264    /** ELQ = "Execute Load Query" */
265    ELQ_FILE_ID_OFFSET= QUERY_HEADER_LEN,
266    ELQ_FN_POS_START_OFFSET= ELQ_FILE_ID_OFFSET + 4,
267    ELQ_FN_POS_END_OFFSET= ELQ_FILE_ID_OFFSET + 8,
268    ELQ_DUP_HANDLING_OFFSET= ELQ_FILE_ID_OFFSET + 12
269   };
270 
271   int32_t file_id;        /** file_id of temporary file */
272   uint32_t fn_pos_start;  /** pointer to the part of the query that should
273                              be substituted */
274   uint32_t fn_pos_end;    /** pointer to the end of this part of query */
275 
276   /**
277     We have to store type of duplicate handling explicitly, because
278     for LOAD DATA it also depends on LOCAL option. And this part
279     of query will be rewritten during replication so this information
280     may be lost...
281   */
282   enum_load_dup_handling dup_handling;
283 
284   Execute_load_query_event(uint32_t file_id_arg, uint32_t fn_pos_start,
285                            uint32_t fn_pos_end, enum_load_dup_handling dup);
286 
287   /**
288     The constructor receives a buffer and instantiates a Execute_load_uery_event
289     filled in with the data from the buffer.
290 
291     <pre>
292     The fixed event data part buffer layout is as follows:
293     +---------------------------------------------------------------------+
294     | thread_id | query_exec_time | db_len | error_code | status_vars_len |
295     +---------------------------------------------------------------------+
296     +----------------------------------------------------+
297     | file_id | fn_pos_start | fn_pos_end | dup_handling |
298     +----------------------------------------------------+
299     </pre>
300 
301     <pre>
302     The fixed event data part buffer layout is as follows:
303     +------------------------------------------------------------------+
304     | Zero or more status variables | db |  LOAD DATA INFILE statement |
305     +------------------------------------------------------------------+
306     </pre>
307 
308     @param buf                Contains the serialized event.
309     @param length             Length of the serialized event.
310     @param description_event  An FDE event, used to get the
311                               following information
312                               -binlog_version
313                               -server_version
314                               -post_header_len
315                               -common_header_len
316                               The content of this object
317                               depends on the binlog-version currently in use.
318     @param event_type         Required to determine whether the event type is
319                               QUERY_EVENT or EXECUTE_LOAD_QUERY_EVENT
320   */
321   Execute_load_query_event(const char* buf, unsigned int event_len,
322                            const Format_description_event *description_event);
323 
~Execute_load_query_event()324   ~Execute_load_query_event() {}
325 
326 };
327 
328 /**
329   @class Load_event
330 
331   This event corresponds to a "LOAD DATA INFILE" SQL query in the
332   following form:
333 
334   @verbatim
335    (1)    USE db;
336    (2)    LOAD DATA [CONCURRENT] [LOCAL] INFILE 'file_name'
337    (3)    [REPLACE | IGNORE]
338    (4)    INTO TABLE 'table_name'
339    (5)    [FIELDS
340    (6)      [TERMINATED BY 'field_term']
341    (7)      [[OPTIONALLY] ENCLOSED BY 'enclosed']
342    (8)      [ESCAPED BY 'escaped']
343    (9)    ]
344   (10)    [LINES
345   (11)      [TERMINATED BY 'line_term']
346   (12)      [LINES STARTING BY 'line_start']
347   (13)    ]
348   (14)    [IGNORE skip_lines LINES]
349   (15)    (field_1, field_2, ..., field_n)
350   @endverbatim
351 
352   @section Load_event_binary_format Binary Format
353 
354   The Post-Header consists of the following six components.
355 
356   <table>
357   <caption>Post-Header for Load_event</caption>
358 
359   <tr>
360     <th>Name</th>
361     <th>Format</th>
362     <th>Description</th>
363   </tr>
364 
365   <tr>
366     <td>slave_proxy_id</td>
367     <td>4 byte unsigned integer</td>
368     <td>An integer identifying the client thread that issued the
369     query.  The id is unique per server.  (Note, however, that two
370     threads on different servers may have the same slave_proxy_id.)
371     This is used when a client thread creates a temporary table local
372     to the client.  The slave_proxy_id is used to distinguish
373     temporary tables that belong to different clients.
374     </td>
375   </tr>
376 
377   <tr>
378     <td>load_exec_time</td>
379     <td>4 byte unsigned integer</td>
380     <td>The time from when the query started to when it was logged in
381     the binlog, in seconds.</td>
382   </tr>
383 
384   <tr>
385     <td>skip_lines</td>
386     <td>4 byte unsigned integer</td>
387     <td>The number on line (14) above, if present, or 0 if line (14)
388     is left out.
389     </td>
390   </tr>
391 
392   <tr>
393     <td>table_name_len</td>
394     <td>1 byte unsigned integer</td>
395     <td>The length of 'table_name' on line (4) above.</td>
396   </tr>
397 
398   <tr>
399     <td>db_len</td>
400     <td>1 byte unsigned integer</td>
401     <td>The length of 'db' on line (1) above.</td>
402   </tr>
403 
404   <tr>
405     <td>num_fields</td>
406     <td>4 byte unsigned integer</td>
407     <td>The number n of fields on line (15) above.</td>
408   </tr>
409   </table>
410 
411   The Body contains the following components.
412 
413   <table>
414   <caption>Body of Load_event</caption>
415 
416   <tr>
417     <th>Name</th>
418     <th>Format</th>
419     <th>Description</th>
420   </tr>
421 
422   <tr>
423     <td>sql_ex</td>
424     <td>variable length</td>
425 
426     <td>Describes the part of the query on lines (3) and
427     (5)&ndash;(13) above.  More precisely, it stores the five strings
428     (on lines) field_term (6), enclosed (7), escaped (8), line_term
429     (11), and line_start (12); as well as a bitfield indicating the
430     presence of the keywords REPLACE (3), IGNORE (3), and OPTIONALLY
431     (7).
432 
433     The data is stored in one of two formats, called "old" and "new".
434     The type field of Common-Header determines which of these two
435     formats is used: type LOAD_EVENT means that the old format is
436     used, and type NEW_LOAD_EVENT means that the new format is used.
437     When MySQL writes a Load_event, it uses the new format if at
438     least one of the five strings is two or more bytes long.
439     Otherwise (i.e., if all strings are 0 or 1 bytes long), the old
440     format is used.
441 
442     The new and old format differ in the way the five strings are
443     stored.
444 
445     <ul>
446     <li> In the new format, the strings are stored in the order
447     field_term, enclosed, escaped, line_term, line_start. Each string
448     consists of a length (1 byte), followed by a sequence of
449     characters (0-255 bytes).  Finally, a boolean combination of the
450     following flags is stored in 1 byte: REPLACE_FLAG==0x4,
451     IGNORE_FLAG==0x8, and OPT_ENCLOSED_FLAG==0x2.  If a flag is set,
452     it indicates the presence of the corresponding keyword in the SQL
453     query.
454 
455     <li> In the old format, we know that each string has length 0 or
456     1.  Therefore, only the first byte of each string is stored.  The
457     order of the strings is the same as in the new format.  These five
458     bytes are followed by the same 1 byte bitfield as in the new
459     format.  Finally, a 1 byte bitfield called empty_flags is stored.
460     The low 5 bits of empty_flags indicate which of the five strings
461     have length 0.  For each of the following flags that is set, the
462     corresponding string has length 0; for the flags that are not set,
463     the string has length 1: FIELD_TERM_EMPTY==0x1,
464     ENCLOSED_EMPTY==0x2, LINE_TERM_EMPTY==0x4, LINE_START_EMPTY==0x8,
465     ESCAPED_EMPTY==0x10.
466     </ul>
467 
468     Thus, the size of the new format is 6 bytes + the sum of the sizes
469     of the five strings.  The size of the old format is always 7
470     bytes.
471     </td>
472   </tr>
473 
474   <tr>
475     <td>field_lens</td>
476     <td>num_fields 1 byte unsigned integers</td>
477     <td>An array of num_fields integers representing the length of
478     each field in the query.  (num_fields is from the Post-Header).
479     </td>
480   </tr>
481 
482   <tr>
483     <td>fields</td>
484     <td>num_fields null-terminated strings</td>
485     <td>An array of num_fields null-terminated strings, each
486     representing a field in the query.  (The trailing zero is
487     redundant, since the length are stored in the num_fields array.)
488     The total length of all strings equals to the sum of all
489     field_lens, plus num_fields bytes for all the trailing zeros.
490     </td>
491   </tr>
492 
493   <tr>
494     <td>table_name</td>
495     <td>null-terminated string of length table_len + 1 bytes</td>
496     <td>The 'table_name' from the query, as a null-terminated string.
497     (The trailing zero is actually redundant since the table_len is
498     known from Post-Header.)
499     </td>
500   </tr>
501 
502   <tr>
503     <td>db</td>
504     <td>null-terminated string of length db_len + 1 bytes</td>
505     <td>The 'db' from the query, as a null-terminated string.
506     (The trailing zero is actually redundant since the db_len is known
507     from Post-Header.)
508     </td>
509   </tr>
510 
511   <tr>
512     <td>fname</td>
513     <td>variable length string without trailing zero, extending to the
514     end of the event (determined by the length field of the
515     Common-Header)
516     </td>
517     <td>The 'file_name' from the query.
518     </td>
519   </tr>
520 
521   </table>
522 
523   @subsection Load_event_notes_on_previous_versions Notes on Previous Versions
524 
525   This event type is understood by current versions, but only
526   generated by MySQL 3.23 and earlier.
527 */
528 class Load_event: public Binary_log_event
529 {
530 protected:
531   int copy_load_event(const char *buf, unsigned long event_len,
532                       int body_offset,
533                       const Format_description_event* description_event);
534   // Required by Load_event(THD* ...) in the server
535   explicit Load_event(Log_event_type type_code_arg= NEW_LOAD_EVENT)
Binary_log_event(type_code_arg)536     : Binary_log_event(type_code_arg),
537       num_fields(0),
538       fields(0),
539       field_lens(0),
540       field_block_len(0)
541   {}
542 public:
543   enum Load_event_offset {
544     L_THREAD_ID_OFFSET= 0,
545     L_EXEC_TIME_OFFSET= 4,
546     L_SKIP_LINES_OFFSET= 8,
547     L_TBL_LEN_OFFSET= 12,
548     L_DB_LEN_OFFSET= 13,
549     L_NUM_FIELDS_OFFSET= 14,
550     L_SQL_EX_OFFSET= 18,
551     L_DATA_OFFSET= LOAD_HEADER_LEN
552   };
553 
554   /**
555    This is the execution time stored in the post header.
556    Make sure to use it to set the exec_time variable in class Log_event
557   */
558   uint32_t load_exec_time;
559 
560   uint32_t slave_proxy_id;
561   size_t table_name_len;
562 
563   /**
564     No need to have a catalog, as these events can only come from 4.x.
565   */
566   size_t db_len;
567   size_t fname_len;
568   uint32_t num_fields;
569 
570   const char* fields;
571   const unsigned char* field_lens;
572   uint32_t field_block_len;
573 
574   const char* table_name;
575   const char* db;
576   const char* fname;
577   uint32_t skip_lines;
578   sql_ex_data_info sql_ex_data;
579   bool local_fname;
580 
581   /**
582     Indicates that this event corresponds to LOAD DATA CONCURRENT,
583 
584     @note Since Load_event event coming from the binary log
585           lacks information whether LOAD DATA on master was concurrent
586           or not, this flag is only set to TRUE for an auxiliary
587           Load_event object which is used in mysql_load() to
588           re-construct LOAD DATA statement from function parameters,
589           for logging.
590   */
591   bool is_concurrent;
592 
593   /**
594     Note that for all the events related to LOAD DATA (Load_event,
595     Create_file/Append/Exec/Delete, we pass description_event; however as
596     logging of LOAD DATA is changed, this is only used
597     for the common_header_len (post_header_len is not changed).
598 
599     <pre>
600     The fixed event data part buffer layout is as follows:
601     +--------------------------------------------------------------------------------+
602     | thread_id | load_exec_time | skip_lines | table_name_len | db_len | num_fields |
603     +--------------------------------------------------------------------------------+
604     </pre>
605 
606     <pre>
607     Variable data part
608     +---------------------------------------------------------------------+
609     | sql_ex_data struct | len of col names to load | col_names | tb_name |
610     +-------------------------------------------------------------- ------+
611     +----------------+
612     |db_name | fname |
613     +----------------+
614     </pre>
615     @param buf                Contains the serialized event.
616     @param length             Length of the serialized event.
617     @param description_event  An FDE event, used to get the
618                               following information
619                               -binlog_version
620                               -server_version
621                               -post_header_len
622                               -common_header_len
623                               The content of this object
624                               depends on the binlog-version currently in use.
625   */
626   Load_event(const char* buf, unsigned int event_len,
627              const Format_description_event* description_event);
628 
~Load_event()629   ~Load_event()
630   {
631   }
632 
get_data_size()633   size_t get_data_size()
634   {
635     return (table_name_len + db_len + 2 + fname_len
636             + static_cast<unsigned int>(LOAD_HEADER_LEN)
637             + sql_ex_data.data_size() + field_block_len + num_fields);
638   }
639 #ifndef HAVE_MYSYS
640   //TODO(WL#7684): Implement the method print_event_info and print_long_info for
641   //            all the events supported  in  MySQL Binlog
print_event_info(std::ostream & info)642   void print_event_info(std::ostream& info) {};
print_long_info(std::ostream & info)643   void print_long_info(std::ostream& info) {};
644 #endif
645 
646 };
647 
648 /* the classes below are for the new LOAD DATA INFILE logging */
649 
650 /**
651   @class Create_file_event
652 
653   The Create_file_event contains the options to LOAD DATA INFILE.
654   This was a design flaw since the file cannot be loaded until the
655   Exec_load_event is seen. The use of this event was deprecated from
656   MySQL server version 5.0.3 and above.
657 
658   @section Create_file_event_binary_format Binary Format
659 
660   The post header contains the following:
661 
662   <table>
663   <caption>Post header for Create_file_event</caption>
664 
665   <tr>
666     <th>Name</th>
667     <th>Format</th>
668     <th>Description</th>
669   </tr>
670 
671   <tr>
672     <td>file_id</td>
673     <td>32 bit integer</td>
674     <td>The ID of the temporary file created by the slave to which
675         the first data block is copied</td>
676   </tr>
677   </table>
678 */
679 class Create_file_event: public virtual Load_event
680 {
681 protected:
682   /**
683     Pretend we are Load event, so we can write out just
684     our Load part - used on the slave when writing event out to
685     SQL_LOAD-*.info file
686   */
687   bool fake_base;
688 public:
689   enum Create_file_offset {
690    /** CF = "Create File" */
691    CF_FILE_ID_OFFSET= 0,
692    CF_DATA_OFFSET= CREATE_FILE_HEADER_LEN
693   };
694 
695   unsigned char* block;
696   const char *event_buf;
697   unsigned int block_len;
698   unsigned int file_id;
699   bool inited_from_old;
700 
701   /**
702     The buffer layout for variable data part is as follows:
703     <pre>
704     +-------------------------------------------------------------------+
705     | name_len | name | is_null | type | charset_number | val_len | val |
706     +-------------------------------------------------------------------+
707     </pre>
708 
709     @param buf                Contains the serialized event.
710     @param length             Length of the serialized event.
711     @param description_event  An FDE event, used to get the
712                               following information
713                               -binlog_version
714                               -server_version
715                               -post_header_len
716                               -common_header_len
717                               The content of this object
718                               depends on the binlog-version currently in use.
719   */
720   Create_file_event(const char* buf, unsigned int event_len,
721                     const Format_description_event* description_event);
722 
723 
~Create_file_event()724   ~Create_file_event()
725   {
726      bapi_free(const_cast<char*>(event_buf));
727   }
get_data_size()728   size_t get_data_size()
729   {
730     return (fake_base ? Load_event::get_data_size() :
731             Load_event::get_data_size() +
732             4 + 1 + block_len);
733   }
734 
735 
736 };
737 
738 /**
739   @class Delete_file_event
740 
741   DELETE_FILE_EVENT occurs when the LOAD DATA failed on the master.
742   This event notifies the slave not to do the load and to delete
743   the temporary file.
744 
745   @section Delete_file_event_binary_format Binary Format
746 
747   The variable data part is empty. The post header contains the following:
748 
749   <table>
750   <caption>Post header for Delete_file_event</caption>
751 
752   <tr>
753     <th>Name</th>
754     <th>Format</th>
755     <th>Description</th>
756   </tr>
757 
758   <tr>
759     <td>file_id</td>
760     <td>32 bit integer</td>
761     <td>The ID of the file to be deleted</td>
762   </tr>
763   </table>
764 */
765 class Delete_file_event: public Binary_log_event
766 {
767 protected:
768   // Required by Delete_file_log_event(THD* ..)
Delete_file_event(uint32_t file_id_arg,const char * db_arg)769   Delete_file_event(uint32_t file_id_arg, const char* db_arg)
770     : Binary_log_event(DELETE_FILE_EVENT),
771       file_id(file_id_arg),
772       db(db_arg)
773   {}
774 public:
775   enum Delete_file_offset {
776     /** DF = "Delete File" */
777     DF_FILE_ID_OFFSET= 0
778   };
779 
780   uint32_t file_id;
781   const char* db; /** see comment in Append_block_event */
782 
783    /**
784     The buffer layout for fixed data part is as follows:
785     <pre>
786     +---------+
787     | file_id |
788     +---------+
789     </pre>
790 
791     @param buf                Contains the serialized event.
792     @param length             Length of the serialized event.
793     @param description_event  An FDE event, used to get the
794                               following information
795                               -binlog_version
796                               -server_version
797                               -post_header_len
798                               -common_header_len
799                               The content of this object
800                               depends on the binlog-version currently in use.
801   */
802   Delete_file_event(const char* buf, unsigned int event_len,
803                     const Format_description_event* description_event);
804 
~Delete_file_event()805   ~Delete_file_event() {}
806 
807 #ifndef HAVE_MYSYS
808   //TODO(WL#7684): Implement the method print_event_info and print_long_info for
809   //            all the events supported  in  MySQL Binlog
print_event_info(std::ostream & info)810   void print_event_info(std::ostream& info) {};
print_long_info(std::ostream & info)811   void print_long_info(std::ostream& info) {};
812 #endif
813 };
814 
815 /**
816   @class Execute_load_event
817 
818   Execute_load_event is created when the LOAD_DATA query succeeds on
819   the master. The slave should be notified to load the temporary file into
820   the table. For server versions > 5.0.3, the temporary files that stores
821   the parameters to LOAD DATA INFILE is not needed anymore, since they are
822   stored in this event. There is still a temp file containing all the data
823   to be loaded.
824 
825   @section Execute_load_event_binary_format Binary Format
826 
827   The variable data part is empty. The post header contains the following:
828 
829   <table>
830   <caption>Post header for Execute_load_event</caption>
831 
832   <tr>
833     <th>Name</th>
834     <th>Format</th>
835     <th>Description</th>
836   </tr>
837 
838   <tr>
839     <td>file_id</td>
840     <td>32 bit integer</td>
841     <td>The ID of the file to load</td>
842   </tr>
843 */
844 class Execute_load_event: public Binary_log_event
845 {
846 protected:
847   Execute_load_event(const uint32_t file_id, const char* db_arg);
get_type_code()848   Log_event_type get_type_code() { return EXEC_LOAD_EVENT;}
849 
850 public:
851   enum Execute_load_offset {
852     /** EL = "Execute Load" */
853     EL_FILE_ID_OFFSET= 0
854   };
855 
856   uint32_t file_id;
857   const char* db; /** see comment in Append_block_event */
858 
859   /**
860     The buffer layout for fixed data part is as follows:
861     <pre>
862     +---------+
863     | file_id |
864     +---------+
865     </pre>
866 
867     @param buf                Contains the serialized event.
868     @param length             Length of the serialized event.
869     @param description_event  An FDE event, used to get the
870                               following information
871                               -binlog_version
872                               -server_version
873                               -post_header_len
874                               -common_header_len
875                               The content of this object
876                               depends on the binlog-version currently in use.
877   */
878   Execute_load_event(const char* buf, unsigned int event_len,
879                      const Format_description_event *description_event);
880 
~Execute_load_event()881   ~Execute_load_event() {}
882 
883 #ifndef HAVE_MYSYS
884   //TODO(WL#7684): Implement the method print_event_info and print_long_info for
885   //            all the events supported  in  MySQL Binlog
print_event_info(std::ostream & info)886   void print_event_info(std::ostream& info) {};
print_long_info(std::ostream & info)887   void print_long_info(std::ostream& info) {};
888 #endif
889 };
890 
891 /**
892   @class Append_block_event
893 
894   This event is created to contain the file data. One LOAD_DATA_INFILE
895   can have 0 or more instances of this event written to the binary log
896   depending on the size of the file. If the file to be loaded is greater
897   than the threshold value, which is roughly 2^17 bytes, the file is
898   divided into blocks of size equal to the threshold, and each block
899   is sent across as a separate event.
900 
901   @section Append_block_event_binary_format Binary Format
902 
903   The post header contains the following:
904 
905   <table>
906   <caption>Post header for Append_block_event</caption>
907 
908   <tr>
909     <th>Name</th>
910     <th>Format</th>
911     <th>Description</th>
912   </tr>
913 
914   <tr>
915     <td>file_id</td>
916     <td>32 bit integer</td>
917     <td>The ID of the file to append the block to</td>
918   </tr>
919   </table>
920 
921   The body of the event contains the raw data to load. The raw data
922   size is the event size minus the size of all the fixed event parts.
923 */
924 class Append_block_event: public Binary_log_event
925 {
926 protected:
927   /**
928     This constructor is used by the MySQL server.
929   */
Append_block_event(const char * db_arg,unsigned char * block_arg,unsigned int block_len_arg,uint32_t file_id_arg)930   Append_block_event(const char* db_arg,
931                      unsigned char* block_arg,
932                      unsigned int block_len_arg,
933                      uint32_t file_id_arg)
934   : Binary_log_event(APPEND_BLOCK_EVENT),
935     block(block_arg), block_len(block_len_arg),
936     file_id(file_id_arg), db(db_arg)
937   {}
938 
939   Append_block_event(Log_event_type type_arg= APPEND_BLOCK_EVENT)
Binary_log_event(type_arg)940     : Binary_log_event(type_arg)
941   {}
942 
943 public:
944   enum Append_block_offset
945   {
946     /** AB = "Append Block" */
947     AB_FILE_ID_OFFSET= 0,
948     AB_DATA_OFFSET=  APPEND_BLOCK_HEADER_LEN
949   };
950 
951   unsigned char* block;
952   unsigned int block_len;
953   uint32_t file_id;
954   /**
955     'db' is filled when the event is created in mysql_load() (the
956     event needs to have a 'db' member to be well filtered by
957     binlog-*-db rules). 'db' is not written to the binlog (it's not
958     used by Append_block_log_event::write()), so it can't be read in
959     the Append_block_event(const char* buf, int event_len)
960     constructor.  In other words, 'db' is used only for filtering by
961     binlog-*-db rules.  Create_file_event is different: it's 'db'
962     (which is inherited from Load_event) is written to the binlog
963     and can be re-read.
964   */
965   const char* db;
966 
967 
968   /**
969     The buffer layout for fixed data part is as follows:
970     <pre>
971     +---------+
972     | file_id |
973     +---------+
974     </pre>
975 
976     The buffer layout for variabl data part is as follows:
977     <pre>
978     +-------------------+
979     | block | block_len |
980     +-------------------+
981     </pre>
982 
983     @param buf                Contains the serialized event.
984     @param length             Length of the serialized event.
985     @param description_event  An FDE event, used to get the
986                               following information
987                               -binlog_version
988                               -server_version
989                               -post_header_len
990                               -common_header_len
991                               The content of this object
992                               depends on the binlog-version currently in use.
993   */
994   Append_block_event(const char* buf, unsigned int event_len,
995                      const Format_description_event *description_event);
~Append_block_event()996   ~Append_block_event() {}
997 
998 #ifndef HAVE_MYSYS
999   //TODO(WL#7684): Implement the method print_event_info and print_long_info for
1000   //            all the events supported  in  MySQL Binlog
print_event_info(std::ostream & info)1001   void print_event_info(std::ostream& info) {};
print_long_info(std::ostream & info)1002   void print_long_info(std::ostream& info) {};
1003 #endif
1004 };
1005 
1006 /**
1007   @class Begin_load_query_event
1008 
1009   Event for the first block of file to be loaded, its only difference from
1010   Append_block event is that this event creates or truncates existing file
1011   before writing data.
1012 
1013   @section Begin_load_query_event_binary_format Binary Format
1014 
1015   The Post-Header and Body for this event type are empty; it only has
1016   the Common-Header.
1017 */
1018 class Begin_load_query_event: public virtual Append_block_event
1019 {
1020 protected:
Begin_load_query_event()1021   Begin_load_query_event()
1022     : Append_block_event(BEGIN_LOAD_QUERY_EVENT)
1023   {}
1024 
1025 public:
1026 
1027   /**
1028     The buffer layout for fixed data part is as follows:
1029     <pre>
1030     +---------+
1031     | file_id |
1032     +---------+
1033     </pre>
1034 
1035     The buffer layout for variabl data part is as follows:
1036     <pre>
1037     +-------------------+
1038     | block | block_len |
1039     +-------------------+
1040     </pre>
1041 
1042     @param buf                Contains the serialized event.
1043     @param length             Length of the serialized event.
1044     @param description_event  An FDE event, used to get the
1045                               following information
1046                               -binlog_version
1047                               -server_version
1048                               -post_header_len
1049                               -common_header_len
1050                               The content of this object
1051                               depends on the binlog-version currently in use.
1052   */
1053   Begin_load_query_event(const char* buf, unsigned int event_len,
1054                          const Format_description_event *description_event);
1055 
~Begin_load_query_event()1056   ~Begin_load_query_event() {}
1057 
1058 #ifndef HAVE_MYSYS
1059   //TODO(WL#7684): Implement the method print_event_info and print_long_info for
1060   //            all the events supported  in  MySQL Binlog
print_event_info(std::ostream & info)1061   void print_event_info(std::ostream& info) {};
print_long_info(std::ostream & info)1062   void print_long_info(std::ostream& info) {};
1063 #endif
1064 };
1065 } // end namespace binary_log
1066 /**
1067   @} (end of group Replication)
1068 */
1069 #endif	/* LOAD_DATA_EVENTS_INCLUDED */
1070