Skip to main content

mysql_common/
constants.rs

1// Copyright (c) 2017 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;
10
11pub static MAX_PAYLOAD_LEN: usize = 16_777_215;
12pub static DEFAULT_MAX_ALLOWED_PACKET: usize = 4 * 1024 * 1024;
13pub static MIN_COMPRESS_LENGTH: usize = 50;
14
15pub static UTF8_GENERAL_CI: u16 = 33;
16pub static UTF8MB4_GENERAL_CI: u16 = 45;
17
18my_bitflags! {
19    StatusFlags,
20    #[error("Unknown flags in the raw value of StatusFlags (raw={0:b})")]
21    UnknownStatusFlags,
22    u16,
23
24    /// MySql server status flags
25    #[derive(PartialEq, Eq, Hash, Debug, Clone, Copy)]
26    pub struct StatusFlags: u16 {
27        /// Is raised when a multi-statement transaction has been started, either explicitly,
28        /// by means of BEGIN or COMMIT AND CHAIN, or implicitly, by the first transactional
29        /// statement, when autocommit=off.
30        const SERVER_STATUS_IN_TRANS             = 0x0001;
31
32        /// Server in auto_commit mode.
33        const SERVER_STATUS_AUTOCOMMIT           = 0x0002;
34
35        /// Multi query - next query exists.
36        const SERVER_MORE_RESULTS_EXISTS         = 0x0008;
37
38        const SERVER_STATUS_NO_GOOD_INDEX_USED   = 0x0010;
39
40        const SERVER_STATUS_NO_INDEX_USED        = 0x0020;
41
42        /// The server was able to fulfill the clients request and opened a read-only
43        /// non-scrollable cursor for a query. This flag comes in reply to COM_STMT_EXECUTE
44        /// and COM_STMT_FETCH commands. Used by Binary Protocol Resultset to signal that
45        /// COM_STMT_FETCH must be used to fetch the row-data.
46        const SERVER_STATUS_CURSOR_EXISTS        = 0x0040;
47
48        /// This flag is sent when a read-only cursor is exhausted, in reply to
49        /// COM_STMT_FETCH command.
50        const SERVER_STATUS_LAST_ROW_SENT        = 0x0080;
51
52        /// A database was dropped.
53        const SERVER_STATUS_DB_DROPPED           = 0x0100;
54
55        const SERVER_STATUS_NO_BACKSLASH_ESCAPES = 0x0200;
56
57        /// Sent to the client if after a prepared statement reprepare we discovered
58        /// that the new statement returns a different number of result set columns.
59        const SERVER_STATUS_METADATA_CHANGED     = 0x0400;
60
61        const SERVER_QUERY_WAS_SLOW              = 0x0800;
62
63        /// To mark ResultSet containing output parameter values.
64        const SERVER_PS_OUT_PARAMS               = 0x1000;
65
66        /// Set at the same time as SERVER_STATUS_IN_TRANS if the started multi-statement
67        /// transaction is a read-only transaction. Cleared when the transaction commits
68        /// or aborts. Since this flag is sent to clients in OK and EOF packets, the flag
69        /// indicates the transaction status at the end of command execution.
70        const SERVER_STATUS_IN_TRANS_READONLY    = 0x2000;
71
72        /// This status flag, when on, implies that one of the state information has
73        /// changed on the server because of the execution of the last statement.
74        const SERVER_SESSION_STATE_CHANGED       = 0x4000;
75
76        /// Introduced by mariadb. Contain the information about ANSI_QUOTES SQL_MODE.
77        const SERVER_STATUS_ANSI_QUOTES       = 0x8000;
78    }
79}
80
81my_bitflags! {
82    CapabilityFlags,
83    #[error("Unknown flags in the raw value of CapabilityFlags (raw={0:b})")]
84    UnknownCapabilityFlags,
85    u32,
86
87    /// Client capability flags
88    #[derive(PartialEq, Eq, Hash, Debug, Clone, Copy)]
89    pub struct CapabilityFlags: u32 {
90        /// Use the improved version of Old Password Authentication. Assumed to be set since 4.1.1.
91        const CLIENT_LONG_PASSWORD                  = 0x0000_0001;
92
93        /// Send found rows instead of affected rows in EOF_Packet.
94        const CLIENT_FOUND_ROWS                     = 0x0000_0002;
95
96        /// Get all column flags.
97        /// Longer flags in Protocol::ColumnDefinition320.
98        ///
99        /// ### Server
100        /// Supports longer flags.
101        ///
102        /// ### Client
103        /// Expects longer flags.
104        const CLIENT_LONG_FLAG                      = 0x0000_0004;
105
106        /// Database (schema) name can be specified on connect in Handshake Response Packet.
107        /// ### Server
108        /// Supports schema-name in Handshake Response Packet.
109        ///
110        /// ### Client
111        /// Handshake Response Packet contains a schema-name.
112        const CLIENT_CONNECT_WITH_DB                = 0x0000_0008;
113
114        /// Don't allow database.table.column.
115        const CLIENT_NO_SCHEMA                      = 0x0000_0010;
116
117        /// Compression protocol supported.
118        ///
119        /// ### Server
120        /// Supports compression.
121        ///
122        /// ### Client
123        /// Switches to Compression compressed protocol after successful authentication.
124        const CLIENT_COMPRESS                       = 0x0000_0020;
125
126        /// Special handling of ODBC behavior.
127        const CLIENT_ODBC                           = 0x0000_0040;
128
129        /// Can use LOAD DATA LOCAL.
130        ///
131        /// ### Server
132        /// Enables the LOCAL INFILE request of LOAD DATA|XML.
133        ///
134        /// ### Client
135        /// Will handle LOCAL INFILE request.
136        const CLIENT_LOCAL_FILES                    = 0x0000_0080;
137
138        /// Ignore spaces before '('.
139        ///
140        /// ### Server
141        /// Parser can ignore spaces before '('.
142        ///
143        /// ### Client
144        /// Let the parser ignore spaces before '('.
145        const CLIENT_IGNORE_SPACE                   = 0x0000_0100;
146
147        const CLIENT_PROTOCOL_41                    = 0x0000_0200;
148
149        /// This is an interactive client.
150        /// Use System_variables::net_wait_timeout versus System_variables::net_interactive_timeout.
151        ///
152        /// ### Server
153        /// Supports interactive and noninteractive clients.
154        ///
155        /// ### Client
156        /// Client is interactive.
157        const CLIENT_INTERACTIVE                    = 0x0000_0400;
158
159        /// Use SSL encryption for the session.
160        ///
161        /// ### Server
162        /// Supports SSL
163        ///
164        /// ### Client
165        /// Switch to SSL after sending the capability-flags.
166        const CLIENT_SSL                            = 0x0000_0800;
167
168        /// Client only flag. Not used.
169        ///
170        /// ### Client
171        /// Do not issue SIGPIPE if network failures occur (libmysqlclient only).
172        const CLIENT_IGNORE_SIGPIPE                 = 0x0000_1000;
173
174        /// Client knows about transactions.
175        ///
176        /// ### Server
177        /// Can send status flags in OK_Packet / EOF_Packet.
178        ///
179        /// ### Client
180        /// Expects status flags in OK_Packet / EOF_Packet.
181        ///
182        /// ### Note
183        /// This flag is optional in 3.23, but always set by the server since 4.0.
184        const CLIENT_TRANSACTIONS                   = 0x0000_2000;
185
186        const CLIENT_RESERVED                       = 0x0000_4000;
187
188        const CLIENT_SECURE_CONNECTION              = 0x0000_8000;
189
190        /// Enable/disable multi-stmt support.
191        /// Also sets CLIENT_MULTI_RESULTS. Currently not checked anywhere.
192        ///
193        /// ### Server
194        /// Can handle multiple statements per COM_QUERY and COM_STMT_PREPARE.
195        ///
196        /// ### Client
197        /// May send multiple statements per COM_QUERY and COM_STMT_PREPARE.
198        const CLIENT_MULTI_STATEMENTS               = 0x0001_0000;
199
200        /// Enable/disable multi-results.
201        ///
202        /// ### Server
203        /// Can send multiple resultsets for COM_QUERY. Error if the server needs to send
204        /// them and client does not support them.
205        ///
206        /// ### Client
207        /// Can handle multiple resultsets for COM_QUERY.
208        ///
209        /// ### Requires
210        /// `CLIENT_PROTOCOL_41`
211        const CLIENT_MULTI_RESULTS                  = 0x0002_0000;
212
213        /// Multi-results and OUT parameters in PS-protocol.
214        ///
215        /// ### Server
216        /// Can send multiple resultsets for COM_STMT_EXECUTE.
217        ///
218        /// ### Client
219        /// Can handle multiple resultsets for COM_STMT_EXECUTE.
220        ///
221        /// ### Requires
222        /// `CLIENT_PROTOCOL_41`
223        const CLIENT_PS_MULTI_RESULTS               = 0x0004_0000;
224
225        /// Client supports plugin authentication.
226        ///
227        /// ### Server
228        /// Sends extra data in Initial Handshake Packet and supports the pluggable
229        /// authentication protocol.
230        ///
231        /// ### Client
232        /// Supports authentication plugins.
233        ///
234        /// ### Requires
235        /// `CLIENT_PROTOCOL_41`
236        const CLIENT_PLUGIN_AUTH                    = 0x0008_0000;
237
238        /// Client supports connection attributes.
239        ///
240        /// ### Server
241        /// Permits connection attributes in Protocol::HandshakeResponse41.
242        ///
243        /// ### Client
244        /// Sends connection attributes in Protocol::HandshakeResponse41.
245        const CLIENT_CONNECT_ATTRS                  = 0x0010_0000;
246
247        /// Enable authentication response packet to be larger than 255 bytes.
248        /// When the ability to change default plugin require that the initial password
249        /// field in the Protocol::HandshakeResponse41 paclet can be of arbitrary size.
250        /// However, the 4.1 client-server protocol limits the length of the auth-data-field
251        /// sent from client to server to 255 bytes. The solution is to change the type of
252        /// the field to a true length encoded string and indicate the protocol change with
253        /// this client capability flag.
254        ///
255        /// ### Server
256        /// Understands length-encoded integer for auth response data in
257        /// Protocol::HandshakeResponse41.
258        ///
259        /// ### Client
260        /// Length of auth response data in Protocol::HandshakeResponse41 is a
261        /// length-encoded integer.
262        ///
263        /// ### Note
264        /// The flag was introduced in 5.6.6, but had the wrong value.
265        const CLIENT_PLUGIN_AUTH_LENENC_CLIENT_DATA = 0x0020_0000;
266
267        /// Don't close the connection for a user account with expired password.
268        ///
269        /// ### Server
270        /// Announces support for expired password extension.
271        ///
272        /// ### Client
273        /// Can handle expired passwords.
274        const CLIENT_CAN_HANDLE_EXPIRED_PASSWORDS   = 0x0040_0000;
275
276        /// Capable of handling server state change information.
277        /// Its a hint to the server to include the state change information in OK_Packet.
278        ///
279        /// ### Server
280        /// Can set SERVER_SESSION_STATE_CHANGED in the SERVER_STATUS_flags_enum and send
281        /// Session State Information in a OK_Packet.
282        ///
283        /// ### Client
284        /// Expects the server to send Session State Information in a OK_Packet.
285        const CLIENT_SESSION_TRACK                  = 0x0080_0000;
286
287        /// Client no longer needs EOF_Packet and will use OK_Packet instead.
288        ///
289        /// ### Server
290        /// Can send OK after a Text Resultset.
291        ///
292        /// ### Client
293        /// Expects an OK_Packet (instead of EOF_Packet) after the resultset
294        /// rows of a Text Resultset.
295        ///
296        /// ### Background
297        /// To support CLIENT_SESSION_TRACK, additional information must be sent after all
298        /// successful commands. Although the OK_Packet is extensible, the EOF_Packet is
299        /// not due to the overlap of its bytes with the content of the Text Resultset Row.
300        ///
301        /// Therefore, the EOF_Packet in the Text Resultset is replaced with an OK_Packet.
302        /// EOF_Packet is deprecated as of MySQL 5.7.5.
303        const CLIENT_DEPRECATE_EOF                  = 0x0100_0000;
304
305        /// The client can handle optional metadata information in the resultset.
306        const CLIENT_OPTIONAL_RESULTSET_METADATA    = 0x0200_0000;
307
308        /// Compression protocol extended to support zstd compression method.
309        ///
310        /// This capability flag is used to send zstd compression level between client and server
311        /// provided both client and server are enabled with this flag.
312        ///
313        /// # Server
314        ///
315        /// Server sets this flag when global variable protocol-compression-algorithms has zstd
316        /// in its list of supported values.
317        ///
318        /// # Client
319        ///
320        /// Client sets this flag when it is configured to use zstd compression method.
321        const CLIENT_ZSTD_COMPRESSION_ALGORITHM     = 0x0400_0000;
322
323        /// Support optional extension for query parameters into the COM_QUERY
324        /// and COM_STMT_EXECUTE packets.
325        ///
326        /// # Server
327        ///
328        /// Expects an optional part containing the query parameter set(s).
329        /// Executes the query for each set of parameters or returns an error if more than 1 set
330        /// of parameters is sent and the server can't execute it.
331        ///
332        /// # Client
333        ///
334        /// Can send the optional part containing the query parameter set(s).
335        const CLIENT_QUERY_ATTRIBUTES               = 0x0800_0000;
336
337        /// Support Multi factor authentication.
338        ///
339        /// # Server
340        ///
341        /// Server sends AuthNextFactor packet after every nth factor
342        /// authentication method succeeds, except the last factor authentication.
343        ///
344        /// # Client
345        ///
346        /// Client reads AuthNextFactor packet sent by server
347        /// and initiates next factor authentication method.
348        const MULTI_FACTOR_AUTHENTICATION           = 0x1000_0000;
349
350        /// Client or server supports progress reports within error packet.
351        const CLIENT_PROGRESS_OBSOLETE              = 0x2000_0000;
352
353        /// Verify server certificate. Client only flag.
354        ///
355        /// Deprecated in favor of –ssl-mode.
356        const CLIENT_SSL_VERIFY_SERVER_CERT         = 0x4000_0000;
357
358        /// Don't reset the options after an unsuccessful connect. Client only flag.
359        const CLIENT_REMEMBER_OPTIONS               = 0x8000_0000;
360    }
361}
362
363my_bitflags! {
364    MariadbCapabilities,
365    #[error("Unknown flags in the raw value of MariadbCapabilities (raw={0:b})")]
366    UnknownMariadbCapabilityFlags,
367    u32,
368
369    /// MariaDB client capability flags
370    #[derive(PartialEq, Eq, Hash, Debug, Clone, Copy)]
371    pub struct MariadbCapabilities: u32 {
372        /// Permits feedback during long-running operations
373        const MARIADB_CLIENT_PROGRESS               = 0x0000_0001;
374
375        /// Former COM_MULTI, don't use
376        const MARIADB_CLIENT_RESERVED_1             = 0x0000_0002;
377
378        /// Support of parameter arrays in COM_STMT_EXECUTE, since 10.2.0
379        const MARIADB_CLIENT_STMT_BULK_OPERATIONS   = 0x0000_0004;
380
381        /// Support of extended data type/format information, since 10.5.0
382        const MARIADB_CLIENT_EXTENDED_METADATA      = 0x0000_0008;
383
384        /// Do not resend metadata for prepared statements, since 10.6.0
385        const MARIADB_CLIENT_CACHE_METADATA         = 0x0000_0010;
386
387        /// Permits sending unit result-set for BULK commands
388        const MARIADB_CLIENT_BULK_UNIT_RESULTS      = 0x0000_0020;
389  }
390}
391
392my_bitflags! {
393    CursorType,
394    #[error("Unknown flags in the raw value of CursorType (raw={0:b})")]
395    UnknownCursorType,
396    u8,
397
398    /// Mysql cursor type.
399    #[derive(PartialEq, Eq, Hash, Debug, Clone, Copy)]
400    pub struct CursorType: u8 {
401        const CURSOR_TYPE_NO_CURSOR  = 0_u8;
402        const CURSOR_TYPE_READ_ONLY  = 1_u8;
403        const CURSOR_TYPE_FOR_UPDATE = 2_u8;
404        const CURSOR_TYPE_SCROLLABLE = 4_u8;
405    }
406}
407
408my_bitflags! {
409    StmtExecuteParamsFlags,
410    #[error("Unknown flags in the raw value of StmtExecuteParamsFlags (raw={0:b})")]
411    UnknownStmtExecuteParamsFlags,
412    u8,
413
414    /// MySql stmt execute params flags.
415    #[derive(PartialEq, Eq, Hash, Debug, Clone, Copy)]
416    pub struct StmtExecuteParamsFlags: u8 {
417        const NEW_PARAMS_BOUND  = 1_u8;
418    }
419}
420
421my_bitflags! {
422    StmtExecuteParamFlags,
423    #[error("Unknown flags in the raw value of StmtExecuteParamFlags (raw={0:b})")]
424    UnknownStmtExecuteParamFlags,
425    u8,
426
427    /// MySql stmt execute params flags.
428    #[derive(PartialEq, Eq, Hash, Debug, Clone, Copy)]
429    pub struct StmtExecuteParamFlags: u8 {
430        const UNSIGNED  = 128_u8;
431    }
432}
433
434my_bitflags! {
435    StmtBulkExecuteFlags,
436    #[error("Unknown flags in the raw value of StmtBulkExecuteParamsFlags (raw={0:b})")]
437    UnknownStmtBulkExecuteParamsFlags,
438    u16,
439
440    /// MySql stmt execute params flags.
441    #[derive(PartialEq, Eq, Hash, Debug, Clone, Copy)]
442    pub struct StmtBulkExecuteFlags: u16 {
443        const SEND_UNIT_RESULTS  = 64_u16;
444        const SEND_TYPES_TO_SERVER = 128_u16;
445    }
446}
447
448my_bitflags! {
449    ColumnFlags,
450    #[error("Unknown flags in the raw value of ColumnFlags (raw={0:b})")]
451    UnknownColumnFlags,
452    u16,
453
454    /// MySql column flags
455    #[derive(PartialEq, Eq, Hash, Debug, Clone, Copy)]
456    pub struct ColumnFlags: u16 {
457        /// Field can't be NULL.
458        const NOT_NULL_FLAG         = 1u16;
459
460        /// Field is part of a primary key.
461        const PRI_KEY_FLAG          = 2u16;
462
463        /// Field is part of a unique key.
464        const UNIQUE_KEY_FLAG       = 4u16;
465
466        /// Field is part of a key.
467        const MULTIPLE_KEY_FLAG     = 8u16;
468
469        /// Field is a blob.
470        const BLOB_FLAG             = 16u16;
471
472        /// Field is unsigned.
473        const UNSIGNED_FLAG         = 32u16;
474
475        /// Field is zerofill.
476        const ZEROFILL_FLAG         = 64u16;
477
478        /// Field is binary.
479        const BINARY_FLAG           = 128u16;
480
481        /// Field is an enum.
482        const ENUM_FLAG             = 256u16;
483
484        /// Field is a autoincrement field.
485        const AUTO_INCREMENT_FLAG   = 512u16;
486
487        /// Field is a timestamp.
488        const TIMESTAMP_FLAG        = 1024u16;
489
490        /// Field is a set.
491        const SET_FLAG              = 2048u16;
492
493        /// Field doesn't have default value.
494        const NO_DEFAULT_VALUE_FLAG = 4096u16;
495
496        /// Field is set to NOW on UPDATE.
497        const ON_UPDATE_NOW_FLAG    = 8192u16;
498
499        /// Intern; Part of some key.
500        const PART_KEY_FLAG         = 16384u16;
501
502        /// Field is num (for clients).
503        const NUM_FLAG              = 32768u16;
504    }
505}
506
507/// MySql server commands
508#[allow(non_camel_case_types)]
509#[derive(Clone, Copy, Eq, PartialEq, Debug)]
510#[repr(u8)]
511pub enum Command {
512    COM_SLEEP = 0,
513    COM_QUIT,
514    COM_INIT_DB,
515    COM_QUERY,
516    COM_FIELD_LIST,
517    COM_CREATE_DB,
518    COM_DROP_DB,
519    COM_REFRESH,
520    COM_DEPRECATED_1,
521    COM_STATISTICS,
522    COM_PROCESS_INFO,
523    COM_CONNECT,
524    COM_PROCESS_KILL,
525    COM_DEBUG,
526    COM_PING,
527    COM_TIME,
528    COM_DELAYED_INSERT,
529    COM_CHANGE_USER,
530    COM_BINLOG_DUMP,
531    COM_TABLE_DUMP,
532    COM_CONNECT_OUT,
533    COM_REGISTER_SLAVE,
534    COM_STMT_PREPARE,
535    COM_STMT_EXECUTE,
536    COM_STMT_SEND_LONG_DATA,
537    COM_STMT_CLOSE,
538    COM_STMT_RESET,
539    COM_SET_OPTION,
540    COM_STMT_FETCH,
541    COM_DAEMON,
542    COM_BINLOG_DUMP_GTID,
543    COM_RESET_CONNECTION,
544    COM_END,
545    COM_STMT_BULK_EXECUTE = 0xfa_u8,
546}
547
548#[derive(Debug, Clone, Copy, PartialEq, Eq, thiserror::Error)]
549#[error("Unknown MariaDB bulk execute parameter value indicator {}", _0)]
550pub struct UnknownMariadbBulkIndicator(pub u8);
551
552/// MariaDB bulk execute parameter value indicators
553#[allow(non_camel_case_types)]
554#[derive(Clone, Copy, Eq, PartialEq, Debug)]
555#[repr(u8)]
556pub enum MariadbBulkIndicator {
557    /// No special indicator, normal value
558    BULK_INDICATOR_NONE = 0x00_u8,
559    /// NULL value
560    BULK_INDICATOR_NULL = 0x01_u8,
561    /// For INSERT/UPDATE, value is default. Not used
562    BULK_INDICATOR_DEFAULT = 0x02_u8,
563    /// Value is default for insert, Is ignored for update. Not used.
564    BULK_INDICATOR_IGNORE = 0x03_u8,
565}
566
567impl From<MariadbBulkIndicator> for u8 {
568    fn from(x: MariadbBulkIndicator) -> u8 {
569        x as u8
570    }
571}
572
573impl TryFrom<u8> for MariadbBulkIndicator {
574    type Error = UnknownMariadbBulkIndicator;
575
576    fn try_from(value: u8) -> Result<Self, Self::Error> {
577        match value {
578            0x00 => Ok(Self::BULK_INDICATOR_NONE),
579            0x01 => Ok(Self::BULK_INDICATOR_NULL),
580            0x02 => Ok(Self::BULK_INDICATOR_DEFAULT),
581            0x03 => Ok(Self::BULK_INDICATOR_IGNORE),
582            x => Err(UnknownMariadbBulkIndicator(x)),
583        }
584    }
585}
586
587/// Type of state change information (part of MySql's Ok packet).
588#[allow(non_camel_case_types)]
589#[derive(Clone, Copy, Eq, PartialEq, Debug)]
590#[repr(u8)]
591pub enum SessionStateType {
592    /// Session system variables.
593    SESSION_TRACK_SYSTEM_VARIABLES,
594    /// Current schema.
595    SESSION_TRACK_SCHEMA,
596    /// track session state changes
597    SESSION_TRACK_STATE_CHANGE,
598    /// See also: session_track_gtids.
599    SESSION_TRACK_GTIDS,
600    /// Transaction characteristics.
601    SESSION_TRACK_TRANSACTION_CHARACTERISTICS,
602    /// Transaction state.
603    SESSION_TRACK_TRANSACTION_STATE,
604}
605
606impl From<SessionStateType> for u8 {
607    fn from(x: SessionStateType) -> u8 {
608        x as u8
609    }
610}
611
612impl TryFrom<u8> for SessionStateType {
613    type Error = UnknownSessionStateType;
614
615    fn try_from(value: u8) -> Result<Self, Self::Error> {
616        match value {
617            0x00 => Ok(SessionStateType::SESSION_TRACK_SYSTEM_VARIABLES),
618            0x01 => Ok(SessionStateType::SESSION_TRACK_SCHEMA),
619            0x02 => Ok(SessionStateType::SESSION_TRACK_STATE_CHANGE),
620            0x03 => Ok(SessionStateType::SESSION_TRACK_GTIDS),
621            0x04 => Ok(SessionStateType::SESSION_TRACK_TRANSACTION_CHARACTERISTICS),
622            0x05 => Ok(SessionStateType::SESSION_TRACK_TRANSACTION_STATE),
623            x => Err(UnknownSessionStateType(x)),
624        }
625    }
626}
627
628#[derive(Debug, Clone, Copy, PartialEq, Eq, thiserror::Error)]
629#[error("Unknown session state type {}", _0)]
630pub struct UnknownSessionStateType(pub u8);
631
632/// Geometry type.
633#[derive(Clone, Copy, Eq, PartialEq, Debug, Hash)]
634#[allow(non_camel_case_types)]
635#[repr(u8)]
636pub enum GeometryType {
637    GEOM_GEOMETRY,
638    GEOM_POINT,
639    GEOM_LINESTRING,
640    GEOM_POLYGON,
641    GEOM_MULTIPOINT,
642    GEOM_MULTILINESTRING,
643    GEOM_MULTIPOLYGON,
644    GEOM_GEOMETRYCOLLECTION,
645}
646
647#[derive(Debug, Clone, Copy, PartialEq, Eq, thiserror::Error)]
648#[error("Unknown geometry type {}", _0)]
649#[repr(transparent)]
650pub struct UnknownGeometryType(pub u8);
651
652impl From<UnknownGeometryType> for u8 {
653    fn from(x: UnknownGeometryType) -> Self {
654        x.0
655    }
656}
657
658impl TryFrom<u8> for GeometryType {
659    type Error = UnknownGeometryType;
660    fn try_from(value: u8) -> Result<Self, Self::Error> {
661        match value {
662            0 => Ok(GeometryType::GEOM_GEOMETRY),
663            1 => Ok(GeometryType::GEOM_POINT),
664            2 => Ok(GeometryType::GEOM_LINESTRING),
665            3 => Ok(GeometryType::GEOM_POLYGON),
666            4 => Ok(GeometryType::GEOM_MULTIPOINT),
667            5 => Ok(GeometryType::GEOM_MULTILINESTRING),
668            6 => Ok(GeometryType::GEOM_MULTIPOLYGON),
669            7 => Ok(GeometryType::GEOM_GEOMETRYCOLLECTION),
670            x => Err(UnknownGeometryType(x)),
671        }
672    }
673}
674
675/// Type of MySql column field
676#[allow(non_camel_case_types)]
677#[derive(Clone, Copy, Eq, PartialEq, Debug, Hash)]
678#[repr(u8)]
679pub enum ColumnType {
680    MYSQL_TYPE_DECIMAL = 0,
681    MYSQL_TYPE_TINY,
682    MYSQL_TYPE_SHORT,
683    MYSQL_TYPE_LONG,
684    MYSQL_TYPE_FLOAT,
685    MYSQL_TYPE_DOUBLE,
686    MYSQL_TYPE_NULL,
687    MYSQL_TYPE_TIMESTAMP,
688    MYSQL_TYPE_LONGLONG,
689    MYSQL_TYPE_INT24,
690    MYSQL_TYPE_DATE,
691    MYSQL_TYPE_TIME,
692    MYSQL_TYPE_DATETIME,
693    MYSQL_TYPE_YEAR,
694    MYSQL_TYPE_NEWDATE, // Internal to MySql
695    MYSQL_TYPE_VARCHAR,
696    MYSQL_TYPE_BIT,
697    MYSQL_TYPE_TIMESTAMP2,
698    MYSQL_TYPE_DATETIME2,
699    MYSQL_TYPE_TIME2,
700    MYSQL_TYPE_TYPED_ARRAY, // Used for replication only
701    MYSQL_TYPE_VECTOR = 242,
702    MYSQL_TYPE_UNKNOWN = 243,
703    MYSQL_TYPE_JSON = 245,
704    MYSQL_TYPE_NEWDECIMAL = 246,
705    MYSQL_TYPE_ENUM = 247,
706    MYSQL_TYPE_SET = 248,
707    MYSQL_TYPE_TINY_BLOB = 249,
708    MYSQL_TYPE_MEDIUM_BLOB = 250,
709    MYSQL_TYPE_LONG_BLOB = 251,
710    MYSQL_TYPE_BLOB = 252,
711    MYSQL_TYPE_VAR_STRING = 253,
712    MYSQL_TYPE_STRING = 254,
713    MYSQL_TYPE_GEOMETRY = 255,
714}
715
716impl ColumnType {
717    pub fn is_numeric_type(&self) -> bool {
718        use ColumnType::*;
719        matches!(
720            self,
721            MYSQL_TYPE_TINY
722                | MYSQL_TYPE_SHORT
723                | MYSQL_TYPE_INT24
724                | MYSQL_TYPE_LONG
725                | MYSQL_TYPE_LONGLONG
726                | MYSQL_TYPE_DECIMAL
727                | MYSQL_TYPE_NEWDECIMAL
728                | MYSQL_TYPE_FLOAT
729                | MYSQL_TYPE_DOUBLE
730                | MYSQL_TYPE_YEAR // Yes, this is also included
731        )
732    }
733
734    pub fn is_character_type(&self) -> bool {
735        use ColumnType::*;
736        matches!(
737            self,
738            MYSQL_TYPE_STRING | MYSQL_TYPE_VAR_STRING | MYSQL_TYPE_VARCHAR | MYSQL_TYPE_BLOB
739        )
740    }
741
742    pub fn is_enum_or_set_type(&self) -> bool {
743        use ColumnType::*;
744        matches!(self, MYSQL_TYPE_ENUM | MYSQL_TYPE_SET)
745    }
746
747    pub fn is_enum_type(&self) -> bool {
748        matches!(self, ColumnType::MYSQL_TYPE_ENUM)
749    }
750
751    pub fn is_set_type(&self) -> bool {
752        matches!(self, ColumnType::MYSQL_TYPE_SET)
753    }
754
755    pub fn is_geometry_type(&self) -> bool {
756        matches!(self, ColumnType::MYSQL_TYPE_GEOMETRY)
757    }
758
759    pub fn is_vector_type(&self) -> bool {
760        matches!(self, ColumnType::MYSQL_TYPE_VECTOR)
761    }
762}
763
764impl TryFrom<u8> for ColumnType {
765    type Error = UnknownColumnType;
766
767    fn try_from(value: u8) -> Result<Self, Self::Error> {
768        match value {
769            0x00_u8 => Ok(ColumnType::MYSQL_TYPE_DECIMAL),
770            0x01_u8 => Ok(ColumnType::MYSQL_TYPE_TINY),
771            0x02_u8 => Ok(ColumnType::MYSQL_TYPE_SHORT),
772            0x03_u8 => Ok(ColumnType::MYSQL_TYPE_LONG),
773            0x04_u8 => Ok(ColumnType::MYSQL_TYPE_FLOAT),
774            0x05_u8 => Ok(ColumnType::MYSQL_TYPE_DOUBLE),
775            0x06_u8 => Ok(ColumnType::MYSQL_TYPE_NULL),
776            0x07_u8 => Ok(ColumnType::MYSQL_TYPE_TIMESTAMP),
777            0x08_u8 => Ok(ColumnType::MYSQL_TYPE_LONGLONG),
778            0x09_u8 => Ok(ColumnType::MYSQL_TYPE_INT24),
779            0x0a_u8 => Ok(ColumnType::MYSQL_TYPE_DATE),
780            0x0b_u8 => Ok(ColumnType::MYSQL_TYPE_TIME),
781            0x0c_u8 => Ok(ColumnType::MYSQL_TYPE_DATETIME),
782            0x0d_u8 => Ok(ColumnType::MYSQL_TYPE_YEAR),
783            0x0e_u8 => Ok(ColumnType::MYSQL_TYPE_NEWDATE),
784            0x0f_u8 => Ok(ColumnType::MYSQL_TYPE_VARCHAR),
785            0x10_u8 => Ok(ColumnType::MYSQL_TYPE_BIT),
786            0x11_u8 => Ok(ColumnType::MYSQL_TYPE_TIMESTAMP2),
787            0x12_u8 => Ok(ColumnType::MYSQL_TYPE_DATETIME2),
788            0x13_u8 => Ok(ColumnType::MYSQL_TYPE_TIME2),
789            0x14_u8 => Ok(ColumnType::MYSQL_TYPE_TYPED_ARRAY),
790            0xf2_u8 => Ok(ColumnType::MYSQL_TYPE_VECTOR),
791            0xf3_u8 => Ok(ColumnType::MYSQL_TYPE_UNKNOWN),
792            0xf5_u8 => Ok(ColumnType::MYSQL_TYPE_JSON),
793            0xf6_u8 => Ok(ColumnType::MYSQL_TYPE_NEWDECIMAL),
794            0xf7_u8 => Ok(ColumnType::MYSQL_TYPE_ENUM),
795            0xf8_u8 => Ok(ColumnType::MYSQL_TYPE_SET),
796            0xf9_u8 => Ok(ColumnType::MYSQL_TYPE_TINY_BLOB),
797            0xfa_u8 => Ok(ColumnType::MYSQL_TYPE_MEDIUM_BLOB),
798            0xfb_u8 => Ok(ColumnType::MYSQL_TYPE_LONG_BLOB),
799            0xfc_u8 => Ok(ColumnType::MYSQL_TYPE_BLOB),
800            0xfd_u8 => Ok(ColumnType::MYSQL_TYPE_VAR_STRING),
801            0xfe_u8 => Ok(ColumnType::MYSQL_TYPE_STRING),
802            0xff_u8 => Ok(ColumnType::MYSQL_TYPE_GEOMETRY),
803            x => Err(UnknownColumnType(x)),
804        }
805    }
806}
807
808impl From<ColumnType> for u8 {
809    fn from(val: ColumnType) -> u8 {
810        val as u8
811    }
812}
813
814my_bitflags! {
815    Flags2,
816    #[error("Unknown flags in the raw value of Flags2 (raw={0:b})")]
817    UnknownFlags2,
818    u32,
819
820    /// Bitmask of flags that are usually set with `SET`.
821    #[derive(PartialEq, Eq, Hash, Debug, Clone, Copy)]
822    pub struct Flags2: u32 {
823        const OPTION_AUTO_IS_NULL          = 0x00004000;
824        const OPTION_NOT_AUTOCOMMIT        = 0x00080000;
825        const OPTION_NO_FOREIGN_KEY_CHECKS = 0x04000000;
826        const OPTION_RELAXED_UNIQUE_CHECKS = 0x08000000;
827    }
828}
829
830my_bitflags! {
831    SqlMode,
832    #[error("Unknown flags in the raw value of SqlMode (raw={0:b})")]
833    UnknownSqlMode,
834    u64,
835
836    /// Bitmask of flags that are usually set with `SET sql_mode`.
837    #[derive(PartialEq, Eq, Hash, Debug, Clone, Copy)]
838    pub struct SqlMode: u64 {
839        const MODE_REAL_AS_FLOAT              = 0x00000001;
840        const MODE_PIPES_AS_CONCAT            = 0x00000002;
841        const MODE_ANSI_QUOTES                = 0x00000004;
842        const MODE_IGNORE_SPACE               = 0x00000008;
843        const MODE_NOT_USED                   = 0x00000010;
844        const MODE_ONLY_FULL_GROUP_BY         = 0x00000020;
845        const MODE_NO_UNSIGNED_SUBTRACTION    = 0x00000040;
846        const MODE_NO_DIR_IN_CREATE           = 0x00000080;
847        const MODE_POSTGRESQL                 = 0x00000100;
848        const MODE_ORACLE                     = 0x00000200;
849        const MODE_MSSQL                      = 0x00000400;
850        const MODE_DB2                        = 0x00000800;
851        const MODE_MAXDB                      = 0x00001000;
852        const MODE_NO_KEY_OPTIONS             = 0x00002000;
853        const MODE_NO_FIELD_OPTIONS           = 0x00008000;
854        const MODE_NO_TABLE_OPTIONS           = 0x00004000;
855        const MODE_MYSQL40                    = 0x00020000;
856        const MODE_MYSQL323                   = 0x00010000;
857        const MODE_ANSI                       = 0x00040000;
858        const MODE_NO_AUTO_VALUE_ON_ZERO      = 0x00080000;
859        const MODE_NO_BACKSLASH_ESCAPES       = 0x00100000;
860        const MODE_STRICT_TRANS_TABLES        = 0x00200000;
861        const MODE_STRICT_ALL_TABLES          = 0x00400000;
862        const MODE_NO_ZERO_IN_DATE            = 0x00800000;
863        const MODE_NO_ZERO_DATE               = 0x01000000;
864        const MODE_INVALID_DATES              = 0x02000000;
865        const MODE_ERROR_FOR_DIVISION_BY_ZERO = 0x04000000;
866        const MODE_TRADITIONAL                = 0x08000000;
867        const MODE_NO_AUTO_CREATE_USER        = 0x10000000;
868        const MODE_HIGH_NOT_PRECEDENCE        = 0x20000000;
869        const MODE_NO_ENGINE_SUBSTITUTION     = 0x40000000;
870        const MODE_PAD_CHAR_TO_FULL_LENGTH    = 0x80000000;
871        const MODE_TIME_TRUNCATE_FRACTIONAL   = 0x100000000;
872        const MODE_LAST                       = 0x200000000;
873    }
874}
875
876/// Type of the user defined function return slot and arguments.
877#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
878#[allow(non_camel_case_types)]
879#[repr(i8)]
880pub enum ItemResult {
881    /// not valid for UDFs
882    INVALID_RESULT = -1,
883    /// char *
884    STRING_RESULT = 0,
885    REAL_RESULT,
886    /// double
887    /// long long
888    INT_RESULT,
889    /// not valid for UDFs
890    ROW_RESULT,
891    /// char *, to be converted to/from a decimal
892    DECIMAL_RESULT,
893}
894
895#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, thiserror::Error)]
896#[error("Unknown item result type {}", _0)]
897pub struct UnknownItemResultType(pub i8);
898
899impl From<UnknownItemResultType> for i8 {
900    fn from(x: UnknownItemResultType) -> Self {
901        x.0
902    }
903}
904
905impl TryFrom<i8> for ItemResult {
906    type Error = UnknownItemResultType;
907
908    fn try_from(value: i8) -> Result<Self, Self::Error> {
909        match value {
910            -1 => Ok(ItemResult::INVALID_RESULT),
911            0 => Ok(ItemResult::STRING_RESULT),
912            1 => Ok(ItemResult::REAL_RESULT),
913            2 => Ok(ItemResult::INT_RESULT),
914            3 => Ok(ItemResult::ROW_RESULT),
915            4 => Ok(ItemResult::DECIMAL_RESULT),
916            x => Err(UnknownItemResultType(x)),
917        }
918    }
919}
920
921#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, thiserror::Error)]
922#[error("Unknown column type {}", _0)]
923pub struct UnknownColumnType(pub u8);
924
925impl From<UnknownColumnType> for u8 {
926    fn from(x: UnknownColumnType) -> Self {
927        x.0
928    }
929}