Skip to main content

mysql_common/binlog/
consts.rs

1// Copyright (c) 2021 Anatoly Ikorsky
2//
3// Licensed under the Apache License, Version 2.0
4// <LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0> or the MIT
5// license <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
6// option. All files in the project carrying such notice may not be copied,
7// modified, or distributed except according to those terms.
8
9use std::convert::{TryFrom, TryInto};
10
11/// Depending on the MySQL Version that created the binlog the format is slightly different.
12#[repr(u16)]
13#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)]
14pub enum BinlogVersion {
15    /// MySQL 3.23 - < 4.0.0
16    Version1 = 1,
17    /// MySQL 4.0.0 - 4.0.1
18    Version2,
19    /// MySQL 4.0.2 - < 5.0.0
20    Version3,
21    /// MySQL 5.0.0+
22    Version4,
23}
24
25impl From<BinlogVersion> for u16 {
26    fn from(x: BinlogVersion) -> Self {
27        x as u16
28    }
29}
30
31#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, thiserror::Error)]
32#[error("Unknown binlog version {0}")]
33#[repr(transparent)]
34pub struct UnknownBinlogVersion(pub u16);
35
36impl From<UnknownBinlogVersion> for u16 {
37    fn from(x: UnknownBinlogVersion) -> Self {
38        x.0
39    }
40}
41
42impl TryFrom<u16> for BinlogVersion {
43    type Error = UnknownBinlogVersion;
44
45    fn try_from(value: u16) -> Result<Self, Self::Error> {
46        match value {
47            1 => Ok(Self::Version1),
48            2 => Ok(Self::Version2),
49            3 => Ok(Self::Version3),
50            4 => Ok(Self::Version4),
51            x => Err(UnknownBinlogVersion(x)),
52        }
53    }
54}
55
56/// Binlog Event Type
57#[allow(non_camel_case_types)]
58#[repr(u8)]
59#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
60pub enum EventType {
61    /// Ignored event.
62    UNKNOWN_EVENT = 0x00,
63    /// A start event is the first event of a binlog for binlog-version 1 to 3.
64    ///
65    /// Superseded by `FORMAT_DESCRIPTION_EVENT` since mysql v5.0.0.
66    START_EVENT_V3 = 0x01,
67    /// A `QUERY_EVENT` is created for each query that modifies the database,
68    /// unless the query is logged row-based.
69    QUERY_EVENT = 0x02,
70    /// A `STOP_EVENT` has no payload or post-header.
71    STOP_EVENT = 0x03,
72    /// The rotate event is added to the binlog as last event
73    /// to tell the reader what binlog to request next.
74    ROTATE_EVENT = 0x04,
75    INTVAR_EVENT = 0x05,
76    LOAD_EVENT = 0x06,
77    /// Ignored event.
78    SLAVE_EVENT = 0x07,
79    CREATE_FILE_EVENT = 0x08,
80    APPEND_BLOCK_EVENT = 0x09,
81    EXEC_LOAD_EVENT = 0x0a,
82    DELETE_FILE_EVENT = 0x0b,
83    NEW_LOAD_EVENT = 0x0c,
84    RAND_EVENT = 0x0d,
85    USER_VAR_EVENT = 0x0e,
86    ///  A format description event is the first event of a binlog for binlog-version 4. It describes how the other events are layed out.
87    ///
88    /// # Note
89    ///
90    /// Added in MySQL 5.0.0 as replacement for START_EVENT_V3
91    FORMAT_DESCRIPTION_EVENT = 0x0f,
92    XID_EVENT = 0x10,
93    BEGIN_LOAD_QUERY_EVENT = 0x11,
94    EXECUTE_LOAD_QUERY_EVENT = 0x12,
95    TABLE_MAP_EVENT = 0x13,
96    PRE_GA_WRITE_ROWS_EVENT = 0x14,
97    PRE_GA_UPDATE_ROWS_EVENT = 0x15,
98    PRE_GA_DELETE_ROWS_EVENT = 0x16,
99    WRITE_ROWS_EVENT_V1 = 0x17,
100    UPDATE_ROWS_EVENT_V1 = 0x18,
101    DELETE_ROWS_EVENT_V1 = 0x19,
102    INCIDENT_EVENT = 0x1a,
103    HEARTBEAT_EVENT = 0x1b,
104    IGNORABLE_EVENT = 0x1c,
105    ROWS_QUERY_EVENT = 0x1d,
106    WRITE_ROWS_EVENT = 0x1e,
107    UPDATE_ROWS_EVENT = 0x1f,
108    DELETE_ROWS_EVENT = 0x20,
109    GTID_EVENT = 0x21,
110    ANONYMOUS_GTID_EVENT = 0x22,
111    PREVIOUS_GTIDS_EVENT = 0x23,
112    TRANSACTION_CONTEXT_EVENT = 0x24,
113    VIEW_CHANGE_EVENT = 0x25,
114    /// Prepared XA transaction terminal event similar to Xid.
115    XA_PREPARE_LOG_EVENT = 0x26,
116    /// Extension of UPDATE_ROWS_EVENT, allowing partial values according
117    /// to binlog_row_value_options.
118    PARTIAL_UPDATE_ROWS_EVENT = 0x27,
119    TRANSACTION_PAYLOAD_EVENT = 0x28,
120    // 0x29 = HEARTBEAT_LOG_EVENT_V2 in MySQL — not yet supported.
121    /// GTID event with tag support (MySQL 8.4+).
122    ///
123    /// This event type is used for GTIDs that include a tag component.
124    /// Tagged GTIDs have the format: `UUID:tag:transaction_id`
125    GTID_TAGGED_LOG_EVENT = 0x2a,
126    /// Total number of known events.
127    ENUM_END_EVENT,
128}
129
130#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, thiserror::Error)]
131#[error("Unknown event type {0}")]
132#[repr(transparent)]
133pub struct UnknownEventType(pub u8);
134
135impl From<UnknownEventType> for u8 {
136    fn from(x: UnknownEventType) -> Self {
137        x.0
138    }
139}
140
141impl TryFrom<u8> for EventType {
142    type Error = UnknownEventType;
143
144    fn try_from(byte: u8) -> Result<Self, UnknownEventType> {
145        match byte {
146            0x00 => Ok(Self::UNKNOWN_EVENT),
147            0x01 => Ok(Self::START_EVENT_V3),
148            0x02 => Ok(Self::QUERY_EVENT),
149            0x03 => Ok(Self::STOP_EVENT),
150            0x04 => Ok(Self::ROTATE_EVENT),
151            0x05 => Ok(Self::INTVAR_EVENT),
152            0x06 => Ok(Self::LOAD_EVENT),
153            0x07 => Ok(Self::SLAVE_EVENT),
154            0x08 => Ok(Self::CREATE_FILE_EVENT),
155            0x09 => Ok(Self::APPEND_BLOCK_EVENT),
156            0x0a => Ok(Self::EXEC_LOAD_EVENT),
157            0x0b => Ok(Self::DELETE_FILE_EVENT),
158            0x0c => Ok(Self::NEW_LOAD_EVENT),
159            0x0d => Ok(Self::RAND_EVENT),
160            0x0e => Ok(Self::USER_VAR_EVENT),
161            0x0f => Ok(Self::FORMAT_DESCRIPTION_EVENT),
162            0x10 => Ok(Self::XID_EVENT),
163            0x11 => Ok(Self::BEGIN_LOAD_QUERY_EVENT),
164            0x12 => Ok(Self::EXECUTE_LOAD_QUERY_EVENT),
165            0x13 => Ok(Self::TABLE_MAP_EVENT),
166            0x14 => Ok(Self::PRE_GA_WRITE_ROWS_EVENT),
167            0x15 => Ok(Self::PRE_GA_UPDATE_ROWS_EVENT),
168            0x16 => Ok(Self::PRE_GA_DELETE_ROWS_EVENT),
169            0x17 => Ok(Self::WRITE_ROWS_EVENT_V1),
170            0x18 => Ok(Self::UPDATE_ROWS_EVENT_V1),
171            0x19 => Ok(Self::DELETE_ROWS_EVENT_V1),
172            0x1a => Ok(Self::INCIDENT_EVENT),
173            0x1b => Ok(Self::HEARTBEAT_EVENT),
174            0x1c => Ok(Self::IGNORABLE_EVENT),
175            0x1d => Ok(Self::ROWS_QUERY_EVENT),
176            0x1e => Ok(Self::WRITE_ROWS_EVENT),
177            0x1f => Ok(Self::UPDATE_ROWS_EVENT),
178            0x20 => Ok(Self::DELETE_ROWS_EVENT),
179            0x21 => Ok(Self::GTID_EVENT),
180            0x22 => Ok(Self::ANONYMOUS_GTID_EVENT),
181            0x23 => Ok(Self::PREVIOUS_GTIDS_EVENT),
182            0x24 => Ok(Self::TRANSACTION_CONTEXT_EVENT),
183            0x25 => Ok(Self::VIEW_CHANGE_EVENT),
184            0x26 => Ok(Self::XA_PREPARE_LOG_EVENT),
185            0x27 => Ok(Self::PARTIAL_UPDATE_ROWS_EVENT),
186            0x28 => Ok(Self::TRANSACTION_PAYLOAD_EVENT),
187            0x2a => Ok(Self::GTID_TAGGED_LOG_EVENT),
188            x => Err(UnknownEventType(x)),
189        }
190    }
191}
192
193my_bitflags! {
194    EventFlags,
195    #[error("Unknown flags in the raw value of EventFlags (raw={0:b})")]
196    UnknownEventFlags,
197    u16,
198
199    /// Binlog Event Flags
200    #[derive(PartialEq, Eq, Hash, Debug, Clone, Copy)]
201    pub struct EventFlags: u16 {
202        /// Gets unset in the `FORMAT_DESCRIPTION_EVENT`
203        /// when the file gets closed to detect broken binlogs.
204        const LOG_EVENT_BINLOG_IN_USE_F = 0x0001;
205
206        /// Unused.
207        const LOG_EVENT_FORCED_ROTATE_F = 0x0002;
208
209        /// event is thread specific (`CREATE TEMPORARY TABLE` ...).
210        const LOG_EVENT_THREAD_SPECIFIC_F = 0x0004;
211
212        /// Event doesn't need default database to be updated (`CREATE DATABASE`, ...).
213        const LOG_EVENT_SUPPRESS_USE_F = 0x0008;
214
215        /// Unused.
216        const LOG_EVENT_UPDATE_TABLE_MAP_VERSION_F = 0x0010;
217
218        /// Event is created by the slaves SQL-thread and shouldn't update the master-log pos.
219        const LOG_EVENT_ARTIFICIAL_F = 0x0020;
220
221        /// Event is created by the slaves IO-thread when written to the relay log.
222        const LOG_EVENT_RELAY_LOG_F = 0x0040;
223
224        /// Setting this flag will mark an event as Ignorable.
225        const LOG_EVENT_IGNORABLE_F = 0x0080;
226
227        /// Events with this flag are not filtered (e.g. on the current
228        /// database) and are always written to the binary log regardless of
229        /// filters.
230        const LOG_EVENT_NO_FILTER_F = 0x0100;
231
232        /// MTS: group of events can be marked to force its execution in isolation from
233        /// any other Workers.
234        const LOG_EVENT_MTS_ISOLATE_F = 0x0200;
235    }
236}
237
238/// Enumeration spcifying checksum algorithm used to encode a binary log event.
239#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
240#[allow(non_camel_case_types)]
241#[repr(u8)]
242pub enum BinlogChecksumAlg {
243    /// Events are without checksum though its generator is checksum-capable New Master (NM).
244    BINLOG_CHECKSUM_ALG_OFF = 0,
245    /// CRC32 of zlib algorithm
246    BINLOG_CHECKSUM_ALG_CRC32 = 1,
247}
248
249#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, thiserror::Error)]
250#[error("Unknown checksum algorithm {0}")]
251#[repr(transparent)]
252pub struct UnknownChecksumAlg(pub u8);
253
254impl From<UnknownChecksumAlg> for u8 {
255    fn from(x: UnknownChecksumAlg) -> Self {
256        x.0
257    }
258}
259
260impl TryFrom<u8> for BinlogChecksumAlg {
261    type Error = UnknownChecksumAlg;
262
263    fn try_from(value: u8) -> Result<Self, Self::Error> {
264        match value {
265            0 => Ok(Self::BINLOG_CHECKSUM_ALG_OFF),
266            1 => Ok(Self::BINLOG_CHECKSUM_ALG_CRC32),
267            x => Err(UnknownChecksumAlg(x)),
268        }
269    }
270}
271
272/// Binlog query event status vars keys.
273#[repr(u8)]
274#[allow(non_camel_case_types)]
275#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
276pub enum StatusVarKey {
277    /// Contains `Flags2` flags.
278    Flags2 = 0,
279    /// Contains `SqlMode` flags.
280    SqlMode,
281    /// Contains values in the following order:
282    ///
283    /// *   1 byte `length`,
284    /// *   `length` bytes catalog,
285    /// *   NULL byte.
286    ///
287    /// `length + 2` bytes in total.
288    Catalog,
289    /// Contains values in the following order:
290    ///
291    /// *   2 bytes unsigned little-endian auto_increment_increment,
292    /// *   2 bytes unsigned little-endian auto_increment_offset.
293    ///
294    /// Four bytes in total.
295    AutoIncrement,
296    /// Contains values in the following order:
297    ///
298    /// *   2 bytes unsigned little-endian character_set_client,
299    /// *   2 bytes unsigned little-endian collation_connection,
300    /// *   2 bytes unsigned little-endian collation_server.
301    ///
302    /// Six bytes in total.
303    Charset,
304    /// Contains values in the following order:
305    ///
306    /// *   1 byte `length`,
307    /// *   `length` bytes timezone.
308    ///
309    /// `length + 1` bytes in total.
310    TimeZone,
311    /// Contains values in the following order:
312    ///
313    /// *   1 byte `length`,
314    /// *   `length` bytes catalog.
315    ///
316    /// `length + 1` bytes in total.
317    CatalogNz,
318    /// Contains 2 bytes code identifying a table of month and day names.
319    ///
320    /// The mapping from codes to languages is defined in sql_locale.cc.
321    LcTimeNames,
322    /// Contains 2 bytes value of the collation_database system variable.
323    CharsetDatabase,
324    /// Contains 8 bytes value of the table map that is to be updated
325    /// by the multi-table update query statement.
326    TableMapForUpdate,
327    /// Contains 4 bytes bitfield.
328    MasterDataWritten,
329    /// Contains values in the following order:
330    ///
331    /// *   1 byte `user_length`,
332    /// *   `user_length` bytes user,
333    /// *   1 byte `host_length`,
334    /// *   `host_length` bytes host.
335    ///
336    /// `user_length + host_length + 2` bytes in total.
337    Invoker,
338    /// Contains values in the following order:
339    ///
340    /// *   1 byte `count`,
341    /// *   `count` times:
342    ///     *   null-terminated db_name.
343    ///
344    /// `1 + db_names_lens.sum()` bytes in total.
345    UpdatedDbNames,
346    /// Contains 3 bytes unsigned little-endian integer.
347    Microseconds,
348    CommitTs,
349    CommitTs2,
350    /// Contains 1 byte boolean.
351    ExplicitDefaultsForTimestamp,
352    /// Contains 8 bytes unsigned little-endian integer carrying xid info of 2pc-aware
353    /// (recoverable) DDL queries.
354    DdlLoggedWithXid,
355    /// Contains 2 bytes unsigned little-endian integer carrying
356    /// the default collation for the utf8mb4 character set.
357    DefaultCollationForUtf8mb4,
358    /// Contains 1 byte value.
359    SqlRequirePrimaryKey,
360    /// Contains 1 byte value.
361    DefaultTableEncryption,
362}
363
364#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, thiserror::Error)]
365#[error("Unknown status var key {0}")]
366#[repr(transparent)]
367pub struct UnknownStatusVarKey(pub u8);
368
369impl TryFrom<u8> for StatusVarKey {
370    type Error = UnknownStatusVarKey;
371    fn try_from(value: u8) -> Result<Self, Self::Error> {
372        match value {
373            0 => Ok(StatusVarKey::Flags2),
374            1 => Ok(StatusVarKey::SqlMode),
375            2 => Ok(StatusVarKey::Catalog),
376            3 => Ok(StatusVarKey::AutoIncrement),
377            4 => Ok(StatusVarKey::Charset),
378            5 => Ok(StatusVarKey::TimeZone),
379            6 => Ok(StatusVarKey::CatalogNz),
380            7 => Ok(StatusVarKey::LcTimeNames),
381            8 => Ok(StatusVarKey::CharsetDatabase),
382            9 => Ok(StatusVarKey::TableMapForUpdate),
383            10 => Ok(StatusVarKey::MasterDataWritten),
384            11 => Ok(StatusVarKey::Invoker),
385            12 => Ok(StatusVarKey::UpdatedDbNames),
386            13 => Ok(StatusVarKey::Microseconds),
387            14 => Ok(StatusVarKey::CommitTs),
388            15 => Ok(StatusVarKey::CommitTs2),
389            16 => Ok(StatusVarKey::ExplicitDefaultsForTimestamp),
390            17 => Ok(StatusVarKey::DdlLoggedWithXid),
391            18 => Ok(StatusVarKey::DefaultCollationForUtf8mb4),
392            19 => Ok(StatusVarKey::SqlRequirePrimaryKey),
393            20 => Ok(StatusVarKey::DefaultTableEncryption),
394            x => Err(UnknownStatusVarKey(x)),
395        }
396    }
397}
398
399my_bitflags! {
400    SemiSyncFlags,
401    #[error("Unknown flags in the raw value of SemiSyncFlags (raw={0:b})")]
402    UnknownSemiSyncFlags,
403    u8,
404
405    /// Semi-sync binlog flags.
406    #[derive(PartialEq, Eq, Hash, Debug, Clone, Copy)]
407    pub struct SemiSyncFlags: u8 {
408        // If the SEMI_SYNC_ACK_REQ flag is set the master waits for a Semi Sync ACK packet
409        // from the slave before it sends the next event.
410        const SEMI_SYNC_ACK_REQ = 0x01;
411    }
412}
413
414/// Variants of this enum describe how LOAD DATA handles duplicates.
415#[repr(u8)]
416#[allow(non_camel_case_types)]
417#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
418pub enum LoadDuplicateHandling {
419    LOAD_DUP_ERROR = 0,
420    LOAD_DUP_IGNORE,
421    LOAD_DUP_REPLACE,
422}
423
424impl From<LoadDuplicateHandling> for u8 {
425    fn from(x: LoadDuplicateHandling) -> Self {
426        x as u8
427    }
428}
429
430#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, thiserror::Error)]
431#[error("Unknown duplicate handling variant {0}")]
432#[repr(transparent)]
433pub struct UnknownDuplicateHandling(pub u8);
434
435impl From<UnknownDuplicateHandling> for u8 {
436    fn from(x: UnknownDuplicateHandling) -> Self {
437        x.0
438    }
439}
440
441impl TryFrom<u8> for LoadDuplicateHandling {
442    type Error = UnknownDuplicateHandling;
443
444    fn try_from(value: u8) -> Result<Self, Self::Error> {
445        match value {
446            0 => Ok(Self::LOAD_DUP_ERROR),
447            1 => Ok(Self::LOAD_DUP_IGNORE),
448            2 => Ok(Self::LOAD_DUP_REPLACE),
449            x => Err(UnknownDuplicateHandling(x)),
450        }
451    }
452}
453
454/// Enumerates types of optional metadata fields.
455#[repr(u8)]
456#[allow(non_camel_case_types)]
457#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
458pub enum OptionalMetadataFieldType {
459    /// UNSIGNED flag of numeric columns.
460    ///
461    /// # Value format
462    ///
463    /// For each numeric column, a bit indicates whether the numeric colunm has unsigned flag.
464    /// `1` means it is unsigned. The number of bytes needed for this
465    /// is `int((column_count + 7) / 8)`.
466    SIGNEDNESS = 1,
467    /// Character set of string columns.
468    ///
469    /// This field should not appear with `COLUMN_CHARSET`.
470    ///
471    /// # Value format
472    ///
473    /// *   default charset as a lenght-encoded integer,
474    /// *   then for every character column which charset isn't default:
475    ///     *   column index as a lenght-encoded integer,
476    ///     *   column charset as a length-encoded integer.
477    ///
478    /// The order is the same as the order of `column_type` field.
479    DEFAULT_CHARSET,
480    /// Character set of string columns.
481    ///
482    /// This field should not appear with `DEFAULT_CHARSET`.
483    ///
484    /// # Value format
485    ///
486    /// *   for every character column:
487    ///     *   column charset as a length-encoded integer.
488    ///
489    /// The order is the same as the order of `column_type` field.
490    COLUMN_CHARSET,
491    /// Collumn name of columns (included if `binlog_row_metadata=FULL`).
492    ///
493    /// # Value format
494    ///
495    /// *   for every column:
496    ///     *   column name as a length-encoded string.
497    ///
498    /// The order is the same as the order of `column_type` field.
499    COLUMN_NAME,
500    /// Name of each variant in a SET columns.
501    ///
502    /// # Value format
503    ///
504    /// *   for every SET column:
505    ///     *   number of variants as a length-encoded integer,
506    ///     *   for each variant:
507    ///         *   name of a variant as a length-encoded string.
508    ///
509    /// The order is the same as the order of `column_type` field.
510    SET_STR_VALUE,
511    /// Name of each variant in an ENUM columns.
512    ///
513    /// # Value format
514    ///
515    /// *   for every ENUM column:
516    ///     *   number of variants as a length-encoded integer,
517    ///     *   for each variant:
518    ///         *   name of a variant as a length-encoded string.
519    ///
520    /// The order is the same as the order of `column_type` field.
521    ENUM_STR_VALUE,
522    /// Real type of geometry columns.
523    ///
524    /// # Value format
525    ///
526    /// *   for every geometry column:
527    ///     *   geometry type as a length-encoded integer.
528    ///
529    /// The order is the same as the order of `column_type` field.
530    GEOMETRY_TYPE,
531    /// Primary key without prefix (included if `binlog_row_metadata=FULL`).
532    ///
533    /// This field should not appear with `PRIMARY_KEY_WITH_PREFIX`.
534    ///
535    /// # Value format
536    ///
537    /// *   for every PK index column:
538    ///     *   column index as a length-encoded integer.
539    ///
540    /// The order is the same as the order of `column_type` field.
541    SIMPLE_PRIMARY_KEY,
542    /// Primary key with prefix (included if `binlog_row_metadata=FULL`).
543    ///
544    /// This field should not appear with `SIMPLE_PRIMARY_KEY`.
545    ///
546    /// # Value format
547    ///
548    /// *   for every PK index column:
549    ///     *   column index as a length-encoded integer,
550    ///     *   prefix length as a length-encoded integer
551    ///
552    /// The order is the same as the order of `column_type` field.
553    ///
554    /// ## Note
555    ///
556    /// *   prefix length is a character length, i.e. prefix byte length divided by the maximum
557    ///     length of a character in the correspoding charset;
558    /// *   prefix length `0` means that the whole column value is used.
559    PRIMARY_KEY_WITH_PREFIX,
560    /// Character set of enum and set columns.
561    ///
562    /// This field should not appear with `ENUM_AND_SET_COLUMN_CHARSET`.
563    ///
564    /// # Value format
565    ///
566    /// *   default charset as a lenght-encoded integer,
567    /// *   then for every SET or ENUM column which charset isn't default:
568    ///     *   column index as a lenght-encoded integer,
569    ///     *   column charset as a length-encoded integer.
570    ///
571    /// The order is the same as the order of `column_type` field.
572    ENUM_AND_SET_DEFAULT_CHARSET,
573    /// Character set of enum and set columns.
574    ///
575    /// This field should not appear with `ENUM_AND_SET_DEFAULT_CHARSET`.
576    ///
577    /// # Value format
578    ///
579    /// *   for every SET or ENUM column:
580    ///     *   column charset as a length-encoded integer.
581    ///
582    /// The order is the same as the order of `column_type` field.
583    ENUM_AND_SET_COLUMN_CHARSET,
584    /// A flag that indicates column visibility attribute.
585    COLUMN_VISIBILITY,
586    /// Vector column dimensionality.
587    VECTOR_DIMENSIONALITY,
588}
589
590#[derive(Debug, Clone, Copy, PartialEq, Eq, thiserror::Error)]
591#[error("Unknown optional metadata field type {0}")]
592pub struct UnknownOptionalMetadataFieldType(pub u8);
593
594impl From<UnknownOptionalMetadataFieldType> for u8 {
595    fn from(x: UnknownOptionalMetadataFieldType) -> Self {
596        x.0
597    }
598}
599
600impl TryFrom<u8> for OptionalMetadataFieldType {
601    type Error = UnknownOptionalMetadataFieldType;
602
603    fn try_from(value: u8) -> Result<Self, Self::Error> {
604        match value {
605            1 => Ok(Self::SIGNEDNESS),
606            2 => Ok(Self::DEFAULT_CHARSET),
607            3 => Ok(Self::COLUMN_CHARSET),
608            4 => Ok(Self::COLUMN_NAME),
609            5 => Ok(Self::SET_STR_VALUE),
610            6 => Ok(Self::ENUM_STR_VALUE),
611            7 => Ok(Self::GEOMETRY_TYPE),
612            8 => Ok(Self::SIMPLE_PRIMARY_KEY),
613            9 => Ok(Self::PRIMARY_KEY_WITH_PREFIX),
614            10 => Ok(Self::ENUM_AND_SET_DEFAULT_CHARSET),
615            11 => Ok(Self::ENUM_AND_SET_COLUMN_CHARSET),
616            12 => Ok(Self::COLUMN_VISIBILITY),
617            13 => Ok(Self::VECTOR_DIMENSIONALITY),
618            x => Err(UnknownOptionalMetadataFieldType(x)),
619        }
620    }
621}
622
623/// Type of an incident event.
624#[repr(u16)]
625#[allow(non_camel_case_types)]
626#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
627pub enum IncidentType {
628    /// No incident.
629    INCIDENT_NONE = 0,
630    /// There are possibly lost events in the replication stream.
631    INCIDENT_LOST_EVENTS = 1,
632}
633
634impl From<IncidentType> for u16 {
635    fn from(x: IncidentType) -> Self {
636        x as u16
637    }
638}
639
640#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, thiserror::Error)]
641#[error("Unknown item incident type {0}")]
642#[repr(transparent)]
643pub struct UnknownIncidentType(pub u16);
644
645impl From<UnknownIncidentType> for u16 {
646    fn from(x: UnknownIncidentType) -> Self {
647        x.0
648    }
649}
650
651impl TryFrom<u16> for IncidentType {
652    type Error = UnknownIncidentType;
653
654    fn try_from(value: u16) -> Result<Self, Self::Error> {
655        match value {
656            0 => Ok(Self::INCIDENT_NONE),
657            1 => Ok(Self::INCIDENT_LOST_EVENTS),
658            x => Err(UnknownIncidentType(x)),
659        }
660    }
661}
662
663/// Type of an `InvarEvent`.
664#[repr(u8)]
665#[allow(non_camel_case_types)]
666#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
667pub enum IntvarEventType {
668    INVALID_INT_EVENT,
669    /// Indicates the value to use for the `LAST_INSERT_ID()` function in the next statement.
670    LAST_INSERT_ID_EVENT,
671    /// Indicates the value to use for an `AUTO_INCREMENT` column in the next statement.
672    INSERT_ID_EVENT,
673}
674
675impl From<IntvarEventType> for u8 {
676    fn from(x: IntvarEventType) -> Self {
677        x as u8
678    }
679}
680
681#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, thiserror::Error)]
682#[error("Unknown intvar event type {0}")]
683#[repr(transparent)]
684pub struct UnknownIntvarEventType(pub u8);
685
686impl From<UnknownIntvarEventType> for u8 {
687    fn from(x: UnknownIntvarEventType) -> Self {
688        x.0
689    }
690}
691
692impl TryFrom<u8> for IntvarEventType {
693    type Error = UnknownIntvarEventType;
694
695    fn try_from(value: u8) -> Result<Self, Self::Error> {
696        match value {
697            0 => Ok(Self::INVALID_INT_EVENT),
698            1 => Ok(Self::LAST_INSERT_ID_EVENT),
699            2 => Ok(Self::INSERT_ID_EVENT),
700            x => Err(UnknownIntvarEventType(x)),
701        }
702    }
703}
704
705my_bitflags! {
706    GtidFlags,
707    #[error("Unknown flags in the raw value of GtidFlags (raw={0:b})")]
708    UnknownGtidFlags,
709    u8,
710
711    /// Gtid event flags.
712    #[derive(PartialEq, Eq, Hash, Debug, Clone, Copy)]
713    pub struct GtidFlags: u8 {
714        /// Transaction may have changes logged with SBR.
715        ///
716        /// In 5.6, 5.7.0-5.7.18, and 8.0.0-8.0.1, this flag is always set.
717        /// Starting in 5.7.19 and 8.0.2, this flag is cleared if the transaction
718        /// only contains row events. It is set if any part of the transaction is
719        /// written in statement format.
720        const MAY_HAVE_SBR = 0x01;
721    }
722}
723
724/// Group number of a Gtid event.
725///
726/// Should be between `MIN_GNO` and `MAX_GNO` for GtidEvent and `0` for AnonymousGtidEvent.
727#[repr(transparent)]
728#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)]
729pub struct Gno(u64);
730
731impl Gno {
732    pub const MIN_GNO: u64 = 1;
733    pub const MAX_GNO: u64 = i64::MAX as u64;
734}
735
736#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, thiserror::Error)]
737#[error("Group number {0} is out of range [{min}, {max}]", min = Gno::MIN_GNO, max = Gno::MAX_GNO)]
738#[repr(transparent)]
739pub struct InvalidGno(pub u64);
740
741impl From<InvalidGno> for u64 {
742    fn from(x: InvalidGno) -> Self {
743        x.0
744    }
745}
746
747impl TryFrom<u64> for Gno {
748    type Error = InvalidGno;
749
750    fn try_from(value: u64) -> Result<Self, Self::Error> {
751        if value == 0 || (Self::MIN_GNO..Self::MAX_GNO).contains(&value) {
752            Ok(Self(value))
753        } else {
754            Err(InvalidGno(value))
755        }
756    }
757}
758
759my_bitflags! {
760    RowsEventFlags,
761    #[error("Unknown flags in the raw value of RowsEventFlags (raw={0:b})")]
762    UnknownRowsEventFlags,
763    u16,
764
765    /// Rows event flags.
766    #[derive(PartialEq, Eq, Hash, Debug, Clone, Copy)]
767    pub struct RowsEventFlags: u16 {
768        /// Last event of a statement.
769        const STMT_END = 0x0001;
770        /// No foreign key checks.
771        const NO_FOREIGN_KEY_CHECKS   = 0x0002;
772        /// No unique key checks.
773        const RELAXED_UNIQUE_CHECKS  = 0x0004;
774        /// Indicates that rows in this event are complete,
775        /// that is contain values for all columns of the table.
776        const COMPLETE_ROWS = 0x0008;
777    }
778}
779
780my_bitflags! {
781    UserVarFlags,
782    #[error("Unknown flags in the raw value of UserVarFlags (raw={0:b})")]
783    UnknownUserVarFlags,
784    u8,
785
786    /// Flags of a user variable.
787    #[derive(PartialEq, Eq, Hash, Debug, Clone, Copy)]
788    pub struct UserVarFlags: u8 {
789        const UNSIGNED = 0x01;
790    }
791}
792
793/// The on-the-wire fields for Transaction_payload
794#[allow(non_camel_case_types)]
795#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
796#[repr(u8)]
797pub enum TransactionPayloadFields {
798    // Marks the end of the payload header.
799    OTW_PAYLOAD_HEADER_END_MARK = 0,
800
801    // The payload field
802    OTW_PAYLOAD_SIZE_FIELD = 1,
803
804    // The compression type field
805    OTW_PAYLOAD_COMPRESSION_TYPE_FIELD = 2,
806
807    // The uncompressed size field
808    OTW_PAYLOAD_UNCOMPRESSED_SIZE_FIELD = 3,
809    // Other fields are appended here.
810}
811
812#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, thiserror::Error)]
813#[error("Unknown TransactionPayloadFields operation {}", _0)]
814#[repr(transparent)]
815pub struct UnknownTransactionPayloadFields(pub u8);
816
817impl TryFrom<u8> for TransactionPayloadFields {
818    type Error = UnknownTransactionPayloadFields;
819
820    fn try_from(value: u8) -> Result<Self, Self::Error> {
821        match value {
822            0 => Ok(Self::OTW_PAYLOAD_HEADER_END_MARK),
823            1 => Ok(Self::OTW_PAYLOAD_SIZE_FIELD),
824            2 => Ok(Self::OTW_PAYLOAD_COMPRESSION_TYPE_FIELD),
825            3 => Ok(Self::OTW_PAYLOAD_UNCOMPRESSED_SIZE_FIELD),
826            x => Err(UnknownTransactionPayloadFields(x)),
827        }
828    }
829}
830
831impl From<TransactionPayloadFields> for u8 {
832    fn from(x: TransactionPayloadFields) -> Self {
833        x as u8
834    }
835}
836
837impl From<TransactionPayloadFields> for u64 {
838    fn from(x: TransactionPayloadFields) -> Self {
839        x as u64
840    }
841}
842
843impl TryFrom<u64> for TransactionPayloadFields {
844    type Error = UnknownTransactionPayloadFields;
845
846    fn try_from(value: u64) -> Result<Self, Self::Error> {
847        match value {
848            0 => Ok(Self::OTW_PAYLOAD_HEADER_END_MARK),
849            1 => Ok(Self::OTW_PAYLOAD_SIZE_FIELD),
850            2 => Ok(Self::OTW_PAYLOAD_COMPRESSION_TYPE_FIELD),
851            3 => Ok(Self::OTW_PAYLOAD_UNCOMPRESSED_SIZE_FIELD),
852            x => Err(UnknownTransactionPayloadFields(x.try_into().unwrap())),
853        }
854    }
855}
856/// The supported compression algorithms for Transaction_payload
857#[allow(non_camel_case_types)]
858#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
859#[repr(u8)]
860pub enum TransactionPayloadCompressionType {
861    // ZSTD compression.
862    ZSTD = 0,
863
864    // No compression.
865    NONE = 255,
866}
867
868#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, thiserror::Error)]
869#[error("Unknown TransactionPayloadCompressionType {}", _0)]
870#[repr(transparent)]
871pub struct UnknownTransactionPayloadCompressionType(pub u8);
872
873impl TryFrom<u8> for TransactionPayloadCompressionType {
874    type Error = UnknownTransactionPayloadCompressionType;
875
876    fn try_from(value: u8) -> Result<Self, Self::Error> {
877        match value {
878            0 => Ok(Self::ZSTD),
879            255 => Ok(Self::NONE),
880            x => Err(UnknownTransactionPayloadCompressionType(x)),
881        }
882    }
883}
884
885impl TryFrom<u64> for TransactionPayloadCompressionType {
886    type Error = UnknownTransactionPayloadCompressionType;
887
888    fn try_from(value: u64) -> Result<Self, Self::Error> {
889        match value {
890            0 => Ok(Self::ZSTD),
891            255 => Ok(Self::NONE),
892            x => Err(UnknownTransactionPayloadCompressionType(
893                x.try_into().unwrap(),
894            )),
895        }
896    }
897}