-
Notifications
You must be signed in to change notification settings - Fork 3.9k
/
rows_event.h
1169 lines (1003 loc) · 38.6 KB
/
rows_event.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/* Copyright (c) 2014, 2024, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License, version 2.0,
as published by the Free Software Foundation.
This program is designed to work with certain software (including
but not limited to OpenSSL) that is licensed under separate terms,
as designated in a particular file or component or in included license
documentation. The authors of MySQL hereby grant you an additional
permission to link the program and your derivative works with the
separately licensed software that they have either included with
the program or referenced in the documentation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
/**
@addtogroup Replication
@{
@file rows_event.h
@brief Contains the classes representing events which are used for row based
replication. In row-based replication, the master writes events to the binary
log that indicate how individual table rows are changed.
*/
#ifndef ROWS_EVENT_INCLUDED
#define ROWS_EVENT_INCLUDED
#include <vector>
#include "control_events.h"
#include "table_id.h"
/**
1 byte length, 1 byte format
Length is total length in bytes, including 2 byte header
Length values 0 and 1 are currently invalid and reserved.
*/
#define EXTRA_ROW_INFO_LEN_OFFSET 0
#define EXTRA_ROW_INFO_FORMAT_OFFSET 1
#define EXTRA_ROW_INFO_HEADER_LENGTH 2
#define EXTRA_ROW_INFO_MAX_PAYLOAD (255 - EXTRA_ROW_INFO_HEADER_LENGTH)
#define ROWS_MAPID_OFFSET 0
#define ROWS_FLAGS_OFFSET 6
#define ROWS_VHLEN_OFFSET 8
#define EXTRA_ROW_INFO_TYPECODE_LENGTH 1
#define EXTRA_ROW_PART_INFO_VALUE_LENGTH 2
/**
This is the typecode defined for the different elements present in
the container Extra_row_info, this is different from the format information
stored inside extra_row_ndb_info at EXTRA_ROW_INFO_FORMAT_OFFSET.
*/
enum class enum_extra_row_info_typecode { NDB = 0, PART = 1 };
namespace binary_log {
/**
@class Table_map_event
In row-based mode, every row operation event is preceded by a
Table_map_event which maps a table definition to a number. The
table definition consists of database name, table name, and column
definitions.
@section Table_map_event_binary_format Binary Format
The Post-Header has the following components:
<table>
<caption>Post-Header for Table_map_event</caption>
<tr>
<th>Name</th>
<th>Format</th>
<th>Description</th>
</tr>
<tr>
<td>table_id</td>
<td>6 bytes unsigned integer</td>
<td>The number that identifies the table.</td>
</tr>
<tr>
<td>flags</td>
<td>2 byte bitfield</td>
<td>Reserved for future use; currently always 0.</td>
</tr>
</table>
The Body has the following components:
<table>
<caption>Body for Table_map_event</caption>
<tr>
<th>Name</th>
<th>Format</th>
<th>Description</th>
</tr>
<tr>
<td>database_name</td>
<td>one byte string length, followed by null-terminated string</td>
<td>The name of the database in which the table resides. The name
is represented as a packed variable-length integer representing the
number of bytes in the name, followed by length bytes containing
the database name, followed by a terminating 0 byte. (Note the
redundancy in the representation of the length.) </td>
</tr>
<tr>
<td>table_name</td>
<td> The table name is represented as a packed variable-length integer
representing the number of bytes in the name, followed by null-terminated
string</td>
<td>The name of the table, encoded the same way as the database
name above.</td>
</tr>
<tr>
<td>column_count</td>
<td>@ref packed_integer "Packed Integer"</td>
<td>The number of columns in the table, represented as a packed
variable-length integer.</td>
</tr>
<tr>
<td>column_type</td>
<td>List of column_count 1 byte enumeration values</td>
<td>The type of each column in the table, listed from left to
right. Each byte is mapped to a column type according to the
enumeration type enum_field_types defined in mysql_com.h. The
mapping of types to numbers is listed in the table @ref
Table_table_map_event_column_types "below" (along with
description of the associated metadata field). </td>
</tr>
<tr>
<td>metadata_length</td>
<td>@ref packed_integer "Packed Integer"</td>
<td>The length of the following metadata block</td>
</tr>
<tr>
<td>metadata</td>
<td>list of metadata for each column</td>
<td>For each column from left to right, a chunk of data who's
length and semantics depends on the type of the column. The
length and semantics for the metadata for each column are listed
in the table @ref Table_table_map_event_column_types
"below".</td>
</tr>
<tr>
<td>null_bits</td>
<td>column_count bits, rounded up to nearest byte</td>
<td>For each column, a bit indicating whether data in the column
can be NULL or not. The number of bytes needed for this is
int((column_count + 7) / 8). The flag for the first column from the
left is in the least-significant bit of the first byte, the second
is in the second least significant bit of the first byte, the
ninth is in the least significant bit of the second byte, and so
on. </td>
</tr>
<tr>
<td>optional metadata fields</td>
<td>optional metadata fields are stored in Type, Length, Value(TLV) format.
Type takes 1 byte. Length is a packed integer value. Values takes
Length bytes.
</td>
<td>There are some optional metadata defined. They are listed in the table
@ref Table_table_map_event_optional_metadata. Optional metadata fields
follow null_bits. Whether binlogging an optional metadata is decided by the
server. The order is not defined, so they can be binlogged in any order.
</td>
</tr>
</table>
The table below lists all column types, along with the numerical
identifier for it and the size and interpretation of meta-data used
to describe the type.
@anchor Table_table_map_event_column_types
<table>
<caption>Table_map_event column types: numerical identifier and
metadata</caption>
<tr>
<th>Name</th>
<th>Identifier</th>
<th>Size of metadata in bytes</th>
<th>Description of metadata</th>
</tr>
<tr>
<td>MYSQL_TYPE_DECIMAL</td><td>0</td>
<td>0</td>
<td>No column metadata.</td>
</tr>
<tr>
<td>MYSQL_TYPE_TINY</td><td>1</td>
<td>0</td>
<td>No column metadata.</td>
</tr>
<tr>
<td>MYSQL_TYPE_SHORT</td><td>2</td>
<td>0</td>
<td>No column metadata.</td>
</tr>
<tr>
<td>MYSQL_TYPE_LONG</td><td>3</td>
<td>0</td>
<td>No column metadata.</td>
</tr>
<tr>
<td>MYSQL_TYPE_FLOAT</td><td>4</td>
<td>1 byte</td>
<td>1 byte unsigned integer, representing the "pack_length", which
is equal to sizeof(float) on the server from which the event
originates.</td>
</tr>
<tr>
<td>MYSQL_TYPE_DOUBLE</td><td>5</td>
<td>1 byte</td>
<td>1 byte unsigned integer, representing the "pack_length", which
is equal to sizeof(double) on the server from which the event
originates.</td>
</tr>
<tr>
<td>MYSQL_TYPE_NULL</td><td>6</td>
<td>0</td>
<td>No column metadata.</td>
</tr>
<tr>
<td>MYSQL_TYPE_TIMESTAMP</td><td>7</td>
<td>0</td>
<td>No column metadata.</td>
</tr>
<tr>
<td>MYSQL_TYPE_LONGLONG</td><td>8</td>
<td>0</td>
<td>No column metadata.</td>
</tr>
<tr>
<td>MYSQL_TYPE_INT24</td><td>9</td>
<td>0</td>
<td>No column metadata.</td>
</tr>
<tr>
<td>MYSQL_TYPE_DATE</td><td>10</td>
<td>0</td>
<td>No column metadata.</td>
</tr>
<tr>
<td>MYSQL_TYPE_TIME</td><td>11</td>
<td>0</td>
<td>No column metadata.</td>
</tr>
<tr>
<td>MYSQL_TYPE_DATETIME</td><td>12</td>
<td>0</td>
<td>No column metadata.</td>
</tr>
<tr>
<td>MYSQL_TYPE_YEAR</td><td>13</td>
<td>0</td>
<td>No column metadata.</td>
</tr>
<tr>
<td><i>MYSQL_TYPE_NEWDATE</i></td><td><i>14</i></td>
<td>–</td>
<td><i>This enumeration value is only used internally and cannot
exist in a binlog.</i></td>
</tr>
<tr>
<td>MYSQL_TYPE_VARCHAR</td><td>15</td>
<td>2 bytes</td>
<td>2 byte unsigned integer representing the maximum length of
the string.</td>
</tr>
<tr>
<td>MYSQL_TYPE_BIT</td><td>16</td>
<td>2 bytes</td>
<td>A 1 byte unsigned int representing the length in bits of the
bitfield (0 to 64), followed by a 1 byte unsigned int
representing the number of bytes occupied by the bitfield. The
number of bytes is either int((length + 7) / 8) or int(length / 8).
</td>
</tr>
<tr>
<td>MYSQL_TYPE_NEWDECIMAL</td><td>246</td>
<td>2 bytes</td>
<td>A 1 byte unsigned int representing the precision, followed
by a 1 byte unsigned int representing the number of decimals.</td>
</tr>
<tr>
<td><i>MYSQL_TYPE_ENUM</i></td><td><i>247</i></td>
<td>–</td>
<td><i>This enumeration value is only used internally and cannot
exist in a binlog.</i></td>
</tr>
<tr>
<td><i>MYSQL_TYPE_SET</i></td><td><i>248</i></td>
<td>–</td>
<td><i>This enumeration value is only used internally and cannot
exist in a binlog.</i></td>
</tr>
<tr>
<td>MYSQL_TYPE_TINY_BLOB</td><td>249</td>
<td>–</td>
<td><i>This enumeration value is only used internally and cannot
exist in a binlog.</i></td>
</tr>
<tr>
<td><i>MYSQL_TYPE_MEDIUM_BLOB</i></td><td><i>250</i></td>
<td>–</td>
<td><i>This enumeration value is only used internally and cannot
exist in a binlog.</i></td>
</tr>
<tr>
<td><i>MYSQL_TYPE_LONG_BLOB</i></td><td><i>251</i></td>
<td>–</td>
<td><i>This enumeration value is only used internally and cannot
exist in a binlog.</i></td>
</tr>
<tr>
<td>MYSQL_TYPE_BLOB</td><td>252</td>
<td>1 byte</td>
<td>The pack length, i.e., the number of bytes needed to represent
the length of the blob: 1, 2, 3, or 4.</td>
</tr>
<tr>
<td>MYSQL_TYPE_VAR_STRING</td><td>253</td>
<td>2 bytes</td>
<td>This is used to store both strings and enumeration values.
The first byte is a enumeration value storing the <i>real
type</i>, which may be either MYSQL_TYPE_VAR_STRING or
MYSQL_TYPE_ENUM. The second byte is a 1 byte unsigned integer
representing the field size, i.e., the number of bytes needed to
store the length of the string.</td>
</tr>
<tr>
<td>MYSQL_TYPE_STRING</td><td>254</td>
<td>2 bytes</td>
<td>The first byte is always MYSQL_TYPE_VAR_STRING (i.e., 253).
The second byte is the field size, i.e., the number of bytes in
the representation of size of the string: 3 or 4.</td>
</tr>
<tr>
<td>MYSQL_TYPE_GEOMETRY</td><td>255</td>
<td>1 byte</td>
<td>The pack length, i.e., the number of bytes needed to represent
the length of the geometry: 1, 2, 3, or 4.</td>
</tr>
<tr>
<td>MYSQL_TYPE_TYPED_ARRAY</td><td>15</td>
<td>up to 4 bytes</td>
<td>
- The first byte holds the MySQL type for the elements.
- The following 0, 1, 2, or 3 bytes holds the metadata for the MySQL
type for the elements. The contents of these bytes depends on the
element type, as described in the other rows of this table.
</td>
</tr>
</table>
The table below lists all optional metadata types, along with the numerical
identifier for it and the size and interpretation of meta-data used
to describe the type.
@anchor Table_table_map_event_optional_metadata
<table>
<caption>Table_map_event optional metadata types: numerical identifier and
metadata. Optional metadata fields are stored in TLV fields.
Format of values are described in this table. </caption>
<tr>
<th>Type</th>
<th>Description</th>
<th>Format</th>
</tr>
<tr>
<td>SIGNEDNESS</td>
<td>signedness of numeric columns. This is included for all values of
binlog_row_metadata.</td>
<td>For each numeric column, a bit indicates whether the numeric
colunm has unsigned flag. 1 means it is unsigned. The number of
bytes needed for this is int((column_count + 7) / 8). The order is
the same as the order of column_type field.</td>
</tr>
<tr>
<td>DEFAULT_CHARSET</td>
<td>Charsets of character columns. It has a default charset for
the case that most of character columns have same charset and the
most used charset is binlogged as default charset.Collation
numbers are binlogged for identifying charsets. They are stored in
packed length format. Either DEFAULT_CHARSET or COLUMN_CHARSET is
included for all values of binlog_row_metadata.</td>
<td>Default charset's collation is logged first. The charsets which are not
same to default charset are logged following default charset. They are
logged as column index and charset collation number pair sequence. The
column index is counted only in all character columns. The order is same to
the order of column_type
field. </td>
</tr>
<tr>
<td>COLUMN_CHARSET</td>
<td>Charsets of character columns. For the case that most of columns have
different charsets, this field is logged. It is never logged with
DEFAULT_CHARSET together. Either DEFAULT_CHARSET or COLUMN_CHARSET is
included for all values of binlog_row_metadata.</td>
<td>It is a collation number sequence for all character columns.</td>
</tr>
<tr>
<td>COLUMN_NAME</td>
<td>Names of columns. This is only included if
binlog_row_metadata=FULL.</td>
<td>A sequence of column names. For each column name, 1 byte for
the string length in bytes is followed by a string without null
terminator.</td>
</tr>
<tr>
<td>SET_STR_VALUE</td>
<td>The string values of SET columns. This is only included if
binlog_row_metadata=FULL.</td>
<td>For each SET column, a pack_length representing the value
count is followed by a sequence of length and string pairs. length
is the byte count in pack_length format. The string has no null
terminator.</td>
</tr>
<tr>
<td>ENUM_STR_VALUE</td>
<td>The string values is ENUM columns. This is only included
if binlog_row_metadata=FULL.</td>
<td>The format is the same as SET_STR_VALUE.</td>
</tr>
<tr>
<td>GEOMETRY_TYPE</td>
<td>The real type of geometry columns. This is only included
if binlog_row_metadata=FULL.</td>
<td>A sequence of real type of geometry columns are stored in pack_length
format. </td>
</tr>
<tr>
<td>SIMPLE_PRIMARY_KEY</td>
<td>The primary key without any prefix. This is only included
if binlog_row_metadata=FULL and there is a primary key where every
key part covers an entire column.</td>
<td>A sequence of column indexes. The indexes are stored in pack_length
format.</td>
</tr>
<tr>
<td>PRIMARY_KEY_WITH_PREFIX</td>
<td>The primary key with some prefix. It doesn't appear together with
SIMPLE_PRIMARY_KEY. This is only included if
binlog_row_metadata=FULL and there is a primary key where some key
part covers a prefix of the column.</td>
<td>A sequence of column index and prefix length pairs. Both
column index and prefix length are in pack_length format. Prefix length
0 means that the whole column value is used.</td>
</tr>
<tr>
<td>ENUM_AND_SET_DEFAULT_CHARSET</td>
<td>Charsets of ENUM and SET columns. It has the same layout as
DEFAULT_CHARSET. If there are SET or ENUM columns and
binlog_row_metadata=FULL, exactly one of
ENUM_AND_SET_DEFAULT_CHARSET and ENUM_AND_SET_COLUMN_CHARSET
appears (the encoder chooses the representation that uses the
least amount of space). Otherwise, none of them appears.</td>
<td>The same format as for DEFAULT_CHARSET, except it counts ENUM
and SET columns rather than character columns.</td>
</tr>
<tr>
<td>ENUM_AND_SET_COLUMN_CHARSET</td>
<td>Charsets of ENUM and SET columns. It has the same layout as
COLUMN_CHARSET. If there are SET or ENUM columns and
binlog_row_metadata=FULL, exactly one of
ENUM_AND_SET_DEFAULT_CHARSET and ENUM_AND_SET_COLUMN_CHARSET
appears (the encoder chooses the representation that uses the
least amount of space). Otherwise, none of them appears.</td>
<td>The same format as for COLUMN_CHARSET, except it counts ENUM
and SET columns rather than character columns.</td>
</tr>
</table>
*/
class Table_map_event : public Binary_log_event {
public:
/** Constants representing offsets */
enum Table_map_event_offset {
/** TM = "Table Map" */
TM_MAPID_OFFSET = 0,
TM_FLAGS_OFFSET = 6
};
typedef uint16_t flag_set;
/**
DEFAULT_CHARSET and COLUMN_CHARSET don't appear together, and
ENUM_AND_SET_DEFAULT_CHARSET and ENUM_AND_SET_COLUMN_CHARSET don't
appear together. They are just alternative ways to pack character
set information. When binlogging, it logs character sets in the
way that occupies least storage.
SIMPLE_PRIMARY_KEY and PRIMARY_KEY_WITH_PREFIX don't appear together.
SIMPLE_PRIMARY_KEY is for the primary keys which only use whole values of
pk columns. PRIMARY_KEY_WITH_PREFIX is
for the primary keys which just use part value of pk columns.
*/
enum Optional_metadata_field_type {
SIGNEDNESS = 1, // UNSIGNED flag of numeric columns
DEFAULT_CHARSET, /* Character set of string columns, optimized to
minimize space when many columns have the
same charset. */
COLUMN_CHARSET, /* Character set of string columns, optimized to
minimize space when columns have many
different charsets. */
COLUMN_NAME,
SET_STR_VALUE, // String value of SET columns
ENUM_STR_VALUE, // String value of ENUM columns
GEOMETRY_TYPE, // Real type of geometry columns
SIMPLE_PRIMARY_KEY, // Primary key without prefix
PRIMARY_KEY_WITH_PREFIX, // Primary key with prefix
ENUM_AND_SET_DEFAULT_CHARSET, /* Character set of enum and set
columns, optimized to minimize
space when many columns have the
same charset. */
ENUM_AND_SET_COLUMN_CHARSET, /* Character set of enum and set
columns, optimized to minimize
space when many columns have the
same charset. */
COLUMN_VISIBILITY /* Flag to indicate column visibility
attribute. */
};
/**
Metadata_fields organizes m_optional_metadata into a structured format which
is easy to access.
*/
struct Optional_metadata_fields {
typedef std::pair<unsigned int, unsigned int> uint_pair;
typedef std::vector<std::string> str_vector;
struct Default_charset {
Default_charset() : default_charset(0) {}
bool empty() const { return default_charset == 0; }
// Default charset for the columns which are not in charset_pairs.
unsigned int default_charset;
/* The uint_pair means <column index, column charset number>. */
std::vector<uint_pair> charset_pairs;
};
// Contents of DEFAULT_CHARSET field are converted into Default_charset.
Default_charset m_default_charset;
// Contents of ENUM_AND_SET_DEFAULT_CHARSET are converted into
// Default_charset.
Default_charset m_enum_and_set_default_charset;
std::vector<bool> m_signedness;
// Character set number of every string column
std::vector<unsigned int> m_column_charset;
// Character set number of every ENUM or SET column.
std::vector<unsigned int> m_enum_and_set_column_charset;
std::vector<std::string> m_column_name;
// each str_vector stores values of one enum/set column
std::vector<str_vector> m_enum_str_value;
std::vector<str_vector> m_set_str_value;
std::vector<unsigned int> m_geometry_type;
/*
The uint_pair means <column index, prefix length>. Prefix length is 0 if
whole column value is used.
*/
std::vector<uint_pair> m_primary_key;
std::vector<bool> m_column_visibility;
/*
It parses m_optional_metadata and populates into above variables.
@param[in] optional_metadata points to the begin of optional metadata
fields in table_map_event.
@param[in] optional_metadata_len length of optional_metadata field.
*/
Optional_metadata_fields(unsigned char *optional_metadata,
unsigned int optional_metadata_len);
// It is used to specify the validity of the deserialized structure
bool is_valid;
};
/**
<pre>
The buffer layout for fixed data part is as follows:
+-----------------------------------+
| table_id | Reserved for future use|
+-----------------------------------+
</pre>
<pre>
The buffer layout for variable data part is as follows:
+--------------------------------------------------------------------------+
| db len| db name | table len| table name | no of cols | array of col types|
+--------------------------------------------------------------------------+
+---------------------------------------------+
| metadata len | metadata block | m_null_bits |
+---------------------------------------------+
</pre>
@param buf Contains the serialized event.
@param fde An FDE event (see Rotate_event constructor for more info).
*/
Table_map_event(const char *buf, const Format_description_event *fde);
Table_map_event(const Table_id &tid, unsigned long colcnt, const char *dbnam,
size_t dblen, const char *tblnam, size_t tbllen)
: Binary_log_event(TABLE_MAP_EVENT),
m_table_id(tid),
m_data_size(0),
m_dbnam(""),
m_dblen(dblen),
m_tblnam(""),
m_tbllen(tbllen),
m_colcnt(colcnt),
m_field_metadata_size(0),
m_field_metadata(nullptr),
m_null_bits(nullptr),
m_optional_metadata_len(0),
m_optional_metadata(nullptr) {
if (dbnam) m_dbnam = std::string(dbnam, m_dblen);
if (tblnam) m_tblnam = std::string(tblnam, m_tbllen);
}
~Table_map_event() override;
/** Event post header contents */
Table_id m_table_id;
flag_set m_flags;
size_t m_data_size; /** event data size */
/** Event body contents */
std::string m_dbnam;
unsigned long long int m_dblen;
std::string m_tblnam;
unsigned long long int m_tbllen;
unsigned long m_colcnt;
unsigned char *m_coltype;
/**
The size of field metadata buffer set by calling save_field_metadata()
*/
unsigned long m_field_metadata_size;
unsigned char *m_field_metadata; /** field metadata */
unsigned char *m_null_bits;
unsigned int m_optional_metadata_len;
unsigned char *m_optional_metadata;
Table_map_event()
: Binary_log_event(TABLE_MAP_EVENT),
m_coltype(nullptr),
m_field_metadata_size(0),
m_field_metadata(nullptr),
m_null_bits(nullptr),
m_optional_metadata_len(0),
m_optional_metadata(nullptr) {}
unsigned long long get_table_id() { return m_table_id.id(); }
std::string get_table_name() { return m_tblnam; }
std::string get_db_name() { return m_dbnam; }
#ifndef HAVE_MYSYS
void print_event_info(std::ostream &info) override;
void print_long_info(std::ostream &info) override;
#endif
};
/**
@class Rows_event
Common base class for all row-containing binary log events.
RESPONSIBILITIES
- Provide an interface for adding an individual row to the event.
@section Rows_event_binary_format Binary Format
The Post-Header has the following components:
<table>
<caption>Post-Header for Rows_event</caption>
<tr>
<th>Name</th>
<th>Format</th>
<th>Description</th>
</tr>
<tr>
<td>table_id</td>
<td>6 bytes unsigned integer</td>
<td>The number that identifies the table</td>
</tr>
<tr>
<td>flags</td>
<td>2 byte bitfield</td>
<td>Reserved for future use; currently always 0.</td>
</tr>
</table>
The Body has the following components:
<table>
<caption>Body for Rows_event</caption>
<tr>
<th>Name</th>
<th>Format</th>
<th>Description</th>
</tr>
<tr>
<td>width</td>
<td>packed integer</td>
<td>Represents the number of columns in the table</td>
</tr>
<tr>
<td>cols</td>
<td>Bitfield, variable sized</td>
<td>Indicates whether each column is used, one bit per column.
For this field, the amount of storage required is
INT((width + 7) / 8) bytes. </td>
</tr>
<tr>
<td>extra_row_info</td>
<td>An object of class Extra_row_info</td>
<td>The class Extra_row_info will be storing the information related
to m_extra_row_ndb_info and partition info (partition_id and
source_partition_id). At any given time a Rows_event can have both, one
or none of ndb_info and partition_info present as part of Rows_event.
In case both ndb_info and partition_info are present then below will
be the order in which they will be stored.
@verbatim
+----------+--------------------------------------+
|type_code | extra_row_ndb_info |
+--- ------+--------------------------------------+
| NDB |Len of ndb_info |Format |ndb_data |
| 1 byte |1 byte |1 byte |len - 2 byte |
+----------+----------------+-------+-------------+
In case of INSERT/DELETE
+-----------+----------------+
| type_code | partition_info |
+-----------+----------------+
| PART | partition_id |
| (1 byte) | 2 byte |
+-----------+----------------+
In case of UPDATE
+-----------+------------------------------------+
| type_code | partition_info |
+-----------+--------------+---------------------+
| PART | partition_id | source_partition_id |
| (1 byte) | 2 byte | 2 byte |
+-----------+--------------+---------------------+
source_partition_id is used only in the case of Update_event
to log the partition_id of the source partition.
@endverbatim
This is the format for any information stored as extra_row_info.
type_code is not a part of the class Extra_row_info as it is a constant
values used at the time of serializing and decoding the event.
</td>
</tr>
<tr>
<td>columns_before_image</td>
<td>vector of elements of type uint8_t</td>
<td>For DELETE and UPDATE only.
Bit-field indicating whether each column is used
one bit per column. For this field, the amount of storage
required for N columns is INT((N + 7) / 8) bytes.</td>
</tr>
<tr>
<td>columns_after_image</td>
<td>vector of elements of type uint8_t</td>
<td>For WRITE and UPDATE only.
Bit-field indicating whether each column is used in the
UPDATE_ROWS_EVENT and WRITE_ROWS_EVENT after-image; one bit per column.
For this field, the amount of storage required for N columns
is INT((N + 7) / 8) bytes.
@verbatim
+-------------------------------------------------------+
| Event Type | Cols_before_image | Cols_after_image |
+-------------------------------------------------------+
| DELETE | Deleted row | NULL |
| INSERT | NULL | Inserted row |
| UPDATE | Old row | Updated row |
+-------------------------------------------------------+
@endverbatim
</td>
</tr>
<tr>
<td>row</td>
<td>vector of elements of type uint8_t</td>
<td> A sequence of zero or more rows. The end is determined by the size
of the event. Each row has the following format:
- A Bit-field indicating whether each field in the row is NULL.
Only columns that are "used" according to the second field in
the variable data part are listed here. If the second field in
the variable data part has N one-bits, the amount of storage
required for this field is INT((N + 7) / 8) bytes.
- The row-image, containing values of all table fields. This only
lists table fields that are used (according to the second field
of the variable data part) and non-NULL (according to the
previous field). In other words, the number of values listed here
is equal to the number of zero bits in the previous field.
(not counting padding bits in the last byte).
@verbatim
For example, if a INSERT statement inserts into 4 columns of a
table, N= 4 (in the formula above).
length of bitmask= (4 + 7) / 8 = 1
Number of fields in the row= 4.
+------------------------------------------------+
|Null_bit_mask(4)|field-1|field-2|field-3|field 4|
+------------------------------------------------+
@endverbatim
</td>
</tr>
</table>
*/
class Rows_event : public Binary_log_event {
public:
/**
These definitions allow to combine the flags into an
appropriate flag set using the normal bitwise operators. The
implicit conversion from an enum-constant to an integer is
accepted by the compiler, which is then used to set the real set
of flags.
*/
enum enum_flag {
/** Last event of a statement */
STMT_END_F = (1U << 0),
/** Value of the OPTION_NO_FOREIGN_KEY_CHECKS flag in thd->options */
NO_FOREIGN_KEY_CHECKS_F = (1U << 1),
/** Value of the OPTION_RELAXED_UNIQUE_CHECKS flag in thd->options */
RELAXED_UNIQUE_CHECKS_F = (1U << 2),
/**
Indicates that rows in this event are complete, that is contain
values for all columns of the table.
*/
COMPLETE_ROWS_F = (1U << 3)
};
/**
Constructs an event directly. The members are assigned default values.
@param type_arg Type of ROW_EVENT. Expected types are:
- WRITE_ROWS_EVENT, WRITE_ROWS_EVENT_V1
- UPDATE_ROWS_EVENT, UPDATE_ROWS_EVENT_V1,
PARTIAL_UPDATE_ROWS_EVENT
- DELETE_ROWS_EVENT, DELETE_ROWS_EVENT_V1
*/
explicit Rows_event(Log_event_type type_arg)
: Binary_log_event(type_arg),
m_table_id(0),
m_width(0),
columns_before_image(0),
columns_after_image(0),
row(0) {}
/**
The constructor is responsible for decoding the event contained in
the buffer.
<pre>
The buffer layout for fixed data part is as follows
+------------------------------------+
| table_id | reserved for future use |
+------------------------------------+
</pre>
<pre>
The buffer layout for variable data part is as follows
+------------------------------------------------------------------+
| var_header_len | column_before_image | columns_after_image | row |
+------------------------------------------------------------------+
</pre>
@param buf Contains the serialized event.
@param fde An FDE event (see Rotate_event constructor for more info).
*/
Rows_event(const char *buf, const Format_description_event *fde);
~Rows_event() override;
protected:
Log_event_type m_type; /** Actual event type */
/** Post header content */
Table_id m_table_id;
uint16_t m_flags; /** Flags for row-level events */
/* Body of the event */
unsigned long m_width; /** The width of the columns bitmap */
uint32_t n_bits_len; /** value determined by (m_width + 7) / 8 */
uint16_t var_header_len;
std::vector<uint8_t> columns_before_image;
std::vector<uint8_t> columns_after_image;
std::vector<uint8_t> row;
public:
class Extra_row_info {
private:
/** partition_id for a row in a partitioned table */
int m_partition_id;
/**
It is the partition_id of the source partition in case
of Update_event, the target's partition_id is m_partition_id.
This variable is used only in case of Update_event.
*/
int m_source_partition_id;
/** The extra row info provided by NDB */
unsigned char *m_extra_row_ndb_info;
public:
Extra_row_info()
: m_partition_id(UNDEFINED),
m_source_partition_id(UNDEFINED),
m_extra_row_ndb_info(nullptr) {}
Extra_row_info(const Extra_row_info &) = delete;
int get_partition_id() const { return m_partition_id; }
void set_partition_id(int partition_id) {
BAPI_ASSERT(partition_id <= 65535);
m_partition_id = partition_id;
}
int get_source_partition_id() const { return m_source_partition_id; }
void set_source_partition_id(int source_partition_id) {
BAPI_ASSERT(source_partition_id <= 65535);
m_source_partition_id = source_partition_id;
}
unsigned char *get_ndb_info() const { return m_extra_row_ndb_info; }
void set_ndb_info(const unsigned char *ndb_info, size_t len) {
BAPI_ASSERT(!have_ndb_info());
m_extra_row_ndb_info =
static_cast<unsigned char *>(bapi_malloc(len, 16 /* flags */));
std::copy(ndb_info, ndb_info + len, m_extra_row_ndb_info);
}
/**