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