squonk_ast/ast/replication.rs
1// SPDX-License-Identifier: MIT
2// Copyright (c) 2026 Moderately AI Inc.
3
4//! MySQL replication-administration statement AST nodes.
5//!
6//! The five measured MySQL replication-control families, gated as one cohesive unit by
7//! [`UtilitySyntax::replication_statements`](crate::dialect::UtilitySyntax):
8//!
9//! - `CHANGE REPLICATION SOURCE TO <option-list> [FOR CHANNEL '<ch>']` — configure the
10//! asynchronous-replication source connection (`sql_yacc.yy` `change_replication_stmt`,
11//! `source_defs`).
12//! - `CHANGE REPLICATION FILTER <rule-list> [FOR CHANNEL '<ch>']` — set the replication
13//! filtering rules (`filter_defs`).
14//! - `START REPLICA [<threads>] [UNTIL <cond>] [<connection>] [FOR CHANNEL '<ch>']` and
15//! `STOP REPLICA [<threads>] [FOR CHANNEL '<ch>']` — the replica-thread lifecycle
16//! (`start_replica_stmt` / `stop_replica_stmt`).
17//! - `START GROUP_REPLICATION [<option-list>]` / `STOP GROUP_REPLICATION` — the Group
18//! Replication plugin lifecycle (`group_replication`).
19//!
20//! MySQL 8.4 removed the legacy `MASTER`/`SLAVE` spellings (`CHANGE MASTER TO`, `START
21//! SLAVE`, the `MASTER_*` option names), so only the `REPLICATION`/`REPLICA`/`SOURCE_*`
22//! grammar is modelled here — each is an `ER_PARSE_ERROR` on mysql:8.4.10 and never parsed.
23//! No operand is an expression, so the whole family is non-generic (no extension parameter).
24
25use super::{AccountName, Ident, Literal, ObjectName};
26use crate::vocab::Meta;
27use thin_vec::ThinVec;
28
29/// A MySQL replication-administration statement — the boxed payload of
30/// [`Statement::Replication`](crate::ast::Statement::Replication).
31///
32/// Six verbs across the five measured families ride one enum because they are one dialect
33/// unit reached through the replication-specific leading-keyword sequences. `START`/`STOP
34/// GROUP_REPLICATION` are two variants (the two verbs carry different tails — only `START`
35/// takes options) of the single `GROUP REPLICATION` family.
36#[derive(Clone, Debug, PartialEq, Eq, Hash)]
37#[cfg_attr(feature = "serde-serialize", derive(serde::Serialize))]
38#[cfg_attr(feature = "serde-deserialize", derive(serde::Deserialize))]
39pub enum ReplicationStatement {
40 /// `CHANGE REPLICATION SOURCE TO <option-list> [FOR CHANNEL '<ch>']`.
41 ///
42 /// The option list is non-empty (a bare `CHANGE REPLICATION SOURCE TO` is
43 /// `ER_PARSE_ERROR` on mysql:8.4.10) and comma-separated; each element is a
44 /// [`ChangeReplicationSourceOption`]. `FOR CHANNEL` is a trailing suffix, not a list
45 /// member — an option after the channel (`… FOR CHANNEL 'c', SOURCE_PORT = 1`) rejects.
46 ChangeSource {
47 /// The `<name> = <value>` options in source order; always non-empty.
48 options: ThinVec<ChangeReplicationSourceOption>,
49 /// The optional `FOR CHANNEL '<name>'` replication-channel name.
50 channel: Option<Literal>,
51 /// Source location and node identity.
52 meta: Meta,
53 },
54 /// `CHANGE REPLICATION FILTER <rule-list> [FOR CHANNEL '<ch>']`.
55 ///
56 /// The rule list is non-empty and comma-separated; each element is a
57 /// [`ReplicationFilterRule`].
58 ChangeFilter {
59 /// The filter rules in source order; always non-empty.
60 rules: ThinVec<ReplicationFilterRule>,
61 /// The optional `FOR CHANNEL '<name>'` replication-channel name.
62 channel: Option<Literal>,
63 /// Source location and node identity.
64 meta: Meta,
65 },
66 /// `START REPLICA [<thread-list>] [UNTIL <cond-list>] [USER='u'] [PASSWORD='p']
67 /// [DEFAULT_AUTH='a'] [PLUGIN_DIR='d'] [FOR CHANNEL '<ch>']`.
68 ///
69 /// The connection options are four independent fixed-order optionals (MySQL's
70 /// `opt_user_option` … `opt_plugin_dir_option`, space-separated — *not* a comma list,
71 /// unlike [`StartGroupReplication`](Self::StartGroupReplication)). Each may appear alone
72 /// (`START REPLICA PASSWORD = 'p'` is grammar-valid on mysql:8.4.10).
73 StartReplica {
74 /// The `SQL_THREAD`/`IO_THREAD` thread-type list (`opt_replica_thread_option_list`);
75 /// empty when none was written (start both threads).
76 threads: ThinVec<ReplicaThreadOption>,
77 /// The `UNTIL <cond-list>` stop condition (`opt_replica_until`); empty when no
78 /// `UNTIL` was written. See [`ReplicaUntilCondition`].
79 until: ThinVec<ReplicaUntilCondition>,
80 /// The `USER = '<u>'` connection user; `None` when absent.
81 user: Option<Literal>,
82 /// The `PASSWORD = '<p>'` connection password; `None` when absent.
83 password: Option<Literal>,
84 /// The `DEFAULT_AUTH = '<a>'` authentication plugin; `None` when absent.
85 default_auth: Option<Literal>,
86 /// The `PLUGIN_DIR = '<d>'` plugin directory; `None` when absent.
87 plugin_dir: Option<Literal>,
88 /// The optional `FOR CHANNEL '<name>'` replication-channel name.
89 channel: Option<Literal>,
90 /// Source location and node identity.
91 meta: Meta,
92 },
93 /// `STOP REPLICA [<thread-list>] [FOR CHANNEL '<ch>']`.
94 ///
95 /// Unlike [`StartReplica`](Self::StartReplica), `STOP REPLICA` takes no `UNTIL` or
96 /// connection tail — `STOP REPLICA UNTIL …` / `STOP REPLICA USER = …` is `ER_PARSE_ERROR`
97 /// on mysql:8.4.10.
98 StopReplica {
99 /// The `SQL_THREAD`/`IO_THREAD` thread-type list; empty when none was written.
100 threads: ThinVec<ReplicaThreadOption>,
101 /// The optional `FOR CHANNEL '<name>'` replication-channel name.
102 channel: Option<Literal>,
103 /// Source location and node identity.
104 meta: Meta,
105 },
106 /// `START GROUP_REPLICATION [<option-list>]`.
107 ///
108 /// The options are `USER`/`PASSWORD`/`DEFAULT_AUTH` in any order, *comma-separated*
109 /// (`group_replication_start_options` — the distinguishing difference from
110 /// [`StartReplica`](Self::StartReplica)'s space-separated fixed-order tail), so they ride
111 /// an ordered list. Empty when none was written.
112 StartGroupReplication {
113 /// The connection options in source order; empty when none was written.
114 options: ThinVec<GroupReplicationOption>,
115 /// Source location and node identity.
116 meta: Meta,
117 },
118 /// `STOP GROUP_REPLICATION` — takes no options (`STOP GROUP_REPLICATION USER = …` is
119 /// `ER_PARSE_ERROR` on mysql:8.4.10).
120 StopGroupReplication {
121 /// Source location and node identity.
122 meta: Meta,
123 },
124}
125
126/// One `<name> = <value>` option of `CHANGE REPLICATION SOURCE TO` (`sql_yacc.yy`
127/// `source_def` / `source_file_def`).
128///
129/// The [`name`](Self::name) is a closed, measured keyword set ([`SourceOption`]); the
130/// [`value`](Self::value) carries the option's argument in one of the measured value shapes
131/// ([`ChangeReplicationSourceOptionValue`]). The name→shape correspondence is fixed per
132/// option and enforced by the parser (which reads the value shape the name dictates) rather
133/// than the type — the [`CopyOption`](crate::ast::CopyOption) name/value idiom for a wide
134/// flat option grammar.
135#[derive(Clone, Debug, PartialEq, Eq, Hash)]
136#[cfg_attr(feature = "serde-serialize", derive(serde::Serialize))]
137#[cfg_attr(feature = "serde-deserialize", derive(serde::Deserialize))]
138pub struct ChangeReplicationSourceOption {
139 /// The option name; see [`SourceOption`].
140 pub name: SourceOption,
141 /// The option value; see [`ChangeReplicationSourceOptionValue`].
142 pub value: ChangeReplicationSourceOptionValue,
143 /// Source location and node identity.
144 pub meta: Meta,
145}
146
147/// The closed set of `CHANGE REPLICATION SOURCE TO` option names admitted by mysql:8.4.10.
148///
149/// A surface tag (no `meta`; the span rides the enclosing [`ChangeReplicationSourceOption`]).
150/// The set is the 8.4 grammar's `source_def`/`source_file_def` alternatives, engine-narrowed:
151/// the deprecated `MASTER_*` names were removed (each `ER_PARSE_ERROR`), and the compression
152/// option is the *plural* `SOURCE_COMPRESSION_ALGORITHMS` — the singular
153/// `SOURCE_COMPRESSION_ALGORITHM` (the yacc token's bare name) is `ER_PARSE_ERROR` on
154/// mysql:8.4.10, so only the plural keyword is admitted.
155#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
156#[cfg_attr(feature = "serde-serialize", derive(serde::Serialize))]
157#[cfg_attr(feature = "serde-deserialize", derive(serde::Deserialize))]
158pub enum SourceOption {
159 /// `SOURCE_BIND` — the network interface to bind to.
160 SourceBind,
161 /// `SOURCE_HOST` — the source server host name.
162 SourceHost,
163 /// `SOURCE_USER` — the replication account user name.
164 SourceUser,
165 /// `SOURCE_PASSWORD` — the replication account password.
166 SourcePassword,
167 /// `SOURCE_PORT` — the source server TCP port.
168 SourcePort,
169 /// `SOURCE_CONNECT_RETRY` — seconds between reconnection attempts.
170 SourceConnectRetry,
171 /// `SOURCE_RETRY_COUNT` — the reconnection-attempt cap.
172 SourceRetryCount,
173 /// `SOURCE_DELAY` — the replication delay in seconds.
174 SourceDelay,
175 /// `SOURCE_HEARTBEAT_PERIOD` — the heartbeat interval (a fractional number of seconds).
176 SourceHeartbeatPeriod,
177 /// `SOURCE_LOG_FILE` — the source binary-log file name to read from.
178 SourceLogFile,
179 /// `SOURCE_LOG_POS` — the source binary-log position to read from.
180 SourceLogPos,
181 /// `SOURCE_AUTO_POSITION` — enable GTID auto-positioning (`0`/`1`).
182 SourceAutoPosition,
183 /// `RELAY_LOG_FILE` — the relay-log file name to resume from.
184 RelayLogFile,
185 /// `RELAY_LOG_POS` — the relay-log position to resume from.
186 RelayLogPos,
187 /// `SOURCE_SSL` — enable an encrypted connection (`0`/`1`).
188 SourceSsl,
189 /// `SOURCE_SSL_CA` — the certificate-authority file.
190 SourceSslCa,
191 /// `SOURCE_SSL_CAPATH` — the certificate-authority directory.
192 SourceSslCapath,
193 /// `SOURCE_SSL_CERT` — the client public-key certificate file.
194 SourceSslCert,
195 /// `SOURCE_SSL_CIPHER` — the permitted cipher list.
196 SourceSslCipher,
197 /// `SOURCE_SSL_KEY` — the client private-key file.
198 SourceSslKey,
199 /// `SOURCE_SSL_VERIFY_SERVER_CERT` — verify the source certificate (`0`/`1`).
200 SourceSslVerifyServerCert,
201 /// `SOURCE_SSL_CRL` — the certificate-revocation-list file.
202 SourceSslCrl,
203 /// `SOURCE_SSL_CRLPATH` — the certificate-revocation-list directory.
204 SourceSslCrlpath,
205 /// `SOURCE_TLS_VERSION` — the permitted TLS-protocol list.
206 SourceTlsVersion,
207 /// `SOURCE_TLS_CIPHERSUITES` — the permitted TLSv1.3 ciphersuite list (string, or `NULL`).
208 SourceTlsCiphersuites,
209 /// `SOURCE_PUBLIC_KEY_PATH` — the RSA public-key file for password exchange.
210 SourcePublicKeyPath,
211 /// `GET_SOURCE_PUBLIC_KEY` — request the RSA public key from the source (`0`/`1`).
212 GetSourcePublicKey,
213 /// `NETWORK_NAMESPACE` — the network namespace.
214 NetworkNamespace,
215 /// `IGNORE_SERVER_IDS` — the parenthesized server-id ignore list.
216 IgnoreServerIds,
217 /// `SOURCE_COMPRESSION_ALGORITHMS` — the permitted connection-compression algorithms.
218 SourceCompressionAlgorithms,
219 /// `SOURCE_ZSTD_COMPRESSION_LEVEL` — the zstd compression level.
220 SourceZstdCompressionLevel,
221 /// `PRIVILEGE_CHECKS_USER` — the account whose privileges gate applied transactions (an
222 /// account, or `NULL`).
223 PrivilegeChecksUser,
224 /// `REQUIRE_ROW_FORMAT` — require row-based events (`0`/`1`).
225 RequireRowFormat,
226 /// `REQUIRE_TABLE_PRIMARY_KEY_CHECK` — the primary-key-check policy
227 /// (`ON`/`OFF`/`STREAM`/`GENERATE`).
228 RequireTablePrimaryKeyCheck,
229 /// `SOURCE_CONNECTION_AUTO_FAILOVER` — enable asynchronous connection failover (`0`/`1`).
230 SourceConnectionAutoFailover,
231 /// `ASSIGN_GTIDS_TO_ANONYMOUS_TRANSACTIONS` — the anonymous-transaction GTID policy
232 /// (`OFF`/`LOCAL`/`'<uuid>'`).
233 AssignGtidsToAnonymousTransactions,
234 /// `GTID_ONLY` — replicate using only GTIDs, storing no file/position (`0`/`1`).
235 GtidOnly,
236}
237
238impl SourceOption {
239 /// The exact keyword spelling this option renders as — the single source of truth
240 /// shared by the renderer and the parser's option table.
241 pub fn keyword(self) -> &'static str {
242 match self {
243 Self::SourceBind => "SOURCE_BIND",
244 Self::SourceHost => "SOURCE_HOST",
245 Self::SourceUser => "SOURCE_USER",
246 Self::SourcePassword => "SOURCE_PASSWORD",
247 Self::SourcePort => "SOURCE_PORT",
248 Self::SourceConnectRetry => "SOURCE_CONNECT_RETRY",
249 Self::SourceRetryCount => "SOURCE_RETRY_COUNT",
250 Self::SourceDelay => "SOURCE_DELAY",
251 Self::SourceHeartbeatPeriod => "SOURCE_HEARTBEAT_PERIOD",
252 Self::SourceLogFile => "SOURCE_LOG_FILE",
253 Self::SourceLogPos => "SOURCE_LOG_POS",
254 Self::SourceAutoPosition => "SOURCE_AUTO_POSITION",
255 Self::RelayLogFile => "RELAY_LOG_FILE",
256 Self::RelayLogPos => "RELAY_LOG_POS",
257 Self::SourceSsl => "SOURCE_SSL",
258 Self::SourceSslCa => "SOURCE_SSL_CA",
259 Self::SourceSslCapath => "SOURCE_SSL_CAPATH",
260 Self::SourceSslCert => "SOURCE_SSL_CERT",
261 Self::SourceSslCipher => "SOURCE_SSL_CIPHER",
262 Self::SourceSslKey => "SOURCE_SSL_KEY",
263 Self::SourceSslVerifyServerCert => "SOURCE_SSL_VERIFY_SERVER_CERT",
264 Self::SourceSslCrl => "SOURCE_SSL_CRL",
265 Self::SourceSslCrlpath => "SOURCE_SSL_CRLPATH",
266 Self::SourceTlsVersion => "SOURCE_TLS_VERSION",
267 Self::SourceTlsCiphersuites => "SOURCE_TLS_CIPHERSUITES",
268 Self::SourcePublicKeyPath => "SOURCE_PUBLIC_KEY_PATH",
269 Self::GetSourcePublicKey => "GET_SOURCE_PUBLIC_KEY",
270 Self::NetworkNamespace => "NETWORK_NAMESPACE",
271 Self::IgnoreServerIds => "IGNORE_SERVER_IDS",
272 Self::SourceCompressionAlgorithms => "SOURCE_COMPRESSION_ALGORITHMS",
273 Self::SourceZstdCompressionLevel => "SOURCE_ZSTD_COMPRESSION_LEVEL",
274 Self::PrivilegeChecksUser => "PRIVILEGE_CHECKS_USER",
275 Self::RequireRowFormat => "REQUIRE_ROW_FORMAT",
276 Self::RequireTablePrimaryKeyCheck => "REQUIRE_TABLE_PRIMARY_KEY_CHECK",
277 Self::SourceConnectionAutoFailover => "SOURCE_CONNECTION_AUTO_FAILOVER",
278 Self::AssignGtidsToAnonymousTransactions => "ASSIGN_GTIDS_TO_ANONYMOUS_TRANSACTIONS",
279 Self::GtidOnly => "GTID_ONLY",
280 }
281 }
282}
283
284/// The value of a [`ChangeReplicationSourceOption`] — the measured argument shapes of
285/// mysql:8.4.10's `source_def` grammar.
286///
287/// Most options take a [`String`](Self::String) or [`Number`](Self::Number); the remaining
288/// five carry the exotic shapes the grammar defines for specific options.
289#[derive(Clone, Debug, PartialEq, Eq, Hash)]
290#[cfg_attr(feature = "serde-serialize", derive(serde::Serialize))]
291#[cfg_attr(feature = "serde-deserialize", derive(serde::Deserialize))]
292pub enum ChangeReplicationSourceOptionValue {
293 /// A string-literal value (`SOURCE_HOST = 'h'`, `SOURCE_LOG_FILE = 'f'`). The spelling
294 /// round-trips from the [`Literal`] span.
295 String {
296 /// The string value.
297 value: Literal,
298 /// Source location and node identity.
299 meta: Meta,
300 },
301 /// A numeric-literal value (`SOURCE_PORT = 3306`, `SOURCE_HEARTBEAT_PERIOD = 1.5`,
302 /// the `0`/`1` boolean-ish flags). Integer and fractional spellings ride one shape;
303 /// the [`Literal`] classifies its own kind and round-trips from its span.
304 Number {
305 /// The numeric value.
306 value: Literal,
307 /// Source location and node identity.
308 meta: Meta,
309 },
310 /// `SOURCE_TLS_CIPHERSUITES`'s `<string> | NULL` value: `Some` for a string,
311 /// `None` for the bare `NULL` (`source_tls_ciphersuites_def`).
312 NullableString {
313 /// The string value; `None` for `NULL`.
314 value: Option<Literal>,
315 /// Source location and node identity.
316 meta: Meta,
317 },
318 /// `PRIVILEGE_CHECKS_USER`'s `<user> | NULL` value: `Some` for a named account,
319 /// `None` for the bare `NULL` (`privilege_check_def`).
320 User {
321 /// The account; `None` for `NULL`.
322 account: Option<AccountName>,
323 /// Source location and node identity.
324 meta: Meta,
325 },
326 /// `IGNORE_SERVER_IDS`'s parenthesized server-id list (`ignore_server_id_list`). Empty
327 /// for the `()` reset form.
328 ServerIds {
329 /// The server ids in source order; empty for `()`.
330 ids: ThinVec<Literal>,
331 /// Source location and node identity.
332 meta: Meta,
333 },
334 /// `REQUIRE_TABLE_PRIMARY_KEY_CHECK`'s `ON | OFF | STREAM | GENERATE` keyword value
335 /// (`table_primary_key_check_def`).
336 PrimaryKeyCheck {
337 /// The primary-key-check policy.
338 check: RequirePrimaryKeyCheck,
339 /// Source location and node identity.
340 meta: Meta,
341 },
342 /// `ASSIGN_GTIDS_TO_ANONYMOUS_TRANSACTIONS`'s `OFF | LOCAL | '<uuid>'` value
343 /// (`assign_gtids_to_anonymous_transactions_def`). The `uuid` literal is present only
344 /// when [`kind`](Self::AssignGtids::kind) is [`Uuid`](AssignGtidsKind::Uuid).
345 AssignGtids {
346 /// Which of the three forms was written.
347 kind: AssignGtidsKind,
348 /// The UUID string, present only for [`Uuid`](AssignGtidsKind::Uuid).
349 uuid: Option<Literal>,
350 /// Source location and node identity.
351 meta: Meta,
352 },
353}
354
355/// The `REQUIRE_TABLE_PRIMARY_KEY_CHECK` policy keyword. A surface tag (no `meta`).
356#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
357#[cfg_attr(feature = "serde-serialize", derive(serde::Serialize))]
358#[cfg_attr(feature = "serde-deserialize", derive(serde::Deserialize))]
359pub enum RequirePrimaryKeyCheck {
360 /// `ON` — require a primary key on replicated tables.
361 On,
362 /// `OFF` — do not require a primary key.
363 Off,
364 /// `STREAM` — take the source's setting from the replication stream.
365 Stream,
366 /// `GENERATE` — generate a hidden primary key where the source table lacks one.
367 Generate,
368}
369
370/// Which `ASSIGN_GTIDS_TO_ANONYMOUS_TRANSACTIONS` form was written. A surface tag (no
371/// `meta`); the [`Uuid`](Self::Uuid) form's string rides
372/// [`ChangeReplicationSourceOptionValue::AssignGtids::uuid`].
373#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
374#[cfg_attr(feature = "serde-serialize", derive(serde::Serialize))]
375#[cfg_attr(feature = "serde-deserialize", derive(serde::Deserialize))]
376pub enum AssignGtidsKind {
377 /// `OFF` — do not assign GTIDs to anonymous transactions.
378 Off,
379 /// `LOCAL` — assign GTIDs using the replica's own UUID.
380 Local,
381 /// `'<uuid>'` — assign GTIDs using the given UUID string.
382 Uuid,
383}
384
385/// One rule of `CHANGE REPLICATION FILTER` (`sql_yacc.yy` `filter_def`).
386///
387/// Each rule's parenthesized argument list may be empty (the `()` reset form, engine-valid
388/// on mysql:8.4.10). The table forms require *schema-qualified* names (`db.t` — a bare `t`
389/// is `ER_PARSE_ERROR`), so they carry [`ObjectName`]s; the wild forms take string patterns;
390/// `REPLICATE_REWRITE_DB` takes `(from, to)` database pairs.
391#[derive(Clone, Debug, PartialEq, Eq, Hash)]
392#[cfg_attr(feature = "serde-serialize", derive(serde::Serialize))]
393#[cfg_attr(feature = "serde-deserialize", derive(serde::Deserialize))]
394pub enum ReplicationFilterRule {
395 /// `REPLICATE_DO_DB = (<db>, …)` — replicate only the listed databases.
396 DoDb {
397 /// The database names; empty for the `()` reset form.
398 databases: ThinVec<Ident>,
399 /// Source location and node identity.
400 meta: Meta,
401 },
402 /// `REPLICATE_IGNORE_DB = (<db>, …)` — ignore the listed databases.
403 IgnoreDb {
404 /// The database names; empty for the `()` reset form.
405 databases: ThinVec<Ident>,
406 /// Source location and node identity.
407 meta: Meta,
408 },
409 /// `REPLICATE_DO_TABLE = (<db.t>, …)` — replicate only the listed (schema-qualified)
410 /// tables.
411 DoTable {
412 /// The schema-qualified table names; empty for the `()` reset form.
413 tables: ThinVec<ObjectName>,
414 /// Source location and node identity.
415 meta: Meta,
416 },
417 /// `REPLICATE_IGNORE_TABLE = (<db.t>, …)` — ignore the listed (schema-qualified) tables.
418 IgnoreTable {
419 /// The schema-qualified table names; empty for the `()` reset form.
420 tables: ThinVec<ObjectName>,
421 /// Source location and node identity.
422 meta: Meta,
423 },
424 /// `REPLICATE_WILD_DO_TABLE = ('<pattern>', …)` — replicate tables matching the wildcard
425 /// patterns.
426 WildDoTable {
427 /// The wildcard pattern strings; empty for the `()` reset form.
428 patterns: ThinVec<Literal>,
429 /// Source location and node identity.
430 meta: Meta,
431 },
432 /// `REPLICATE_WILD_IGNORE_TABLE = ('<pattern>', …)` — ignore tables matching the wildcard
433 /// patterns.
434 WildIgnoreTable {
435 /// The wildcard pattern strings; empty for the `()` reset form.
436 patterns: ThinVec<Literal>,
437 /// Source location and node identity.
438 meta: Meta,
439 },
440 /// `REPLICATE_REWRITE_DB = ((<from>, <to>), …)` — rewrite database names. Each pair is
441 /// doubly parenthesized (`filter_db_pair_list`); a single-paren `(a, b)` is
442 /// `ER_PARSE_ERROR`.
443 RewriteDb {
444 /// The `(from, to)` rewrite pairs; empty for the `()` reset form.
445 pairs: ThinVec<RewriteDbPair>,
446 /// Source location and node identity.
447 meta: Meta,
448 },
449}
450
451/// One `(<from>, <to>)` database-rewrite pair of a
452/// [`ReplicationFilterRule::RewriteDb`] rule.
453#[derive(Clone, Debug, PartialEq, Eq, Hash)]
454#[cfg_attr(feature = "serde-serialize", derive(serde::Serialize))]
455#[cfg_attr(feature = "serde-deserialize", derive(serde::Deserialize))]
456pub struct RewriteDbPair {
457 /// The source database name.
458 pub from: Ident,
459 /// The rewritten database name.
460 pub to: Ident,
461 /// Source location and node identity.
462 pub meta: Meta,
463}
464
465/// A replica-thread selector on `START`/`STOP REPLICA` (`sql_yacc.yy`
466/// `replica_thread_option`).
467#[derive(Clone, Debug, PartialEq, Eq, Hash)]
468#[cfg_attr(feature = "serde-serialize", derive(serde::Serialize))]
469#[cfg_attr(feature = "serde-deserialize", derive(serde::Deserialize))]
470pub enum ReplicaThreadOption {
471 /// `SQL_THREAD` — the applier thread.
472 Sql {
473 /// Source location and node identity.
474 meta: Meta,
475 },
476 /// The I/O (receiver) thread. `IO_THREAD` and `RELAY_THREAD` are exact synonyms (both the
477 /// yacc `RELAY_THREAD` token); an [`IoThreadKeyword`] surface tag records which was
478 /// written so it round-trips.
479 Io {
480 /// Which of the `IO_THREAD` / `RELAY_THREAD` spellings was written.
481 keyword: IoThreadKeyword,
482 /// Source location and node identity.
483 meta: Meta,
484 },
485}
486
487/// Which of the interchangeable `IO_THREAD` / `RELAY_THREAD` spellings names the receiver
488/// thread. A surface tag (no `meta`); the two are exact synonyms.
489#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
490#[cfg_attr(feature = "serde-serialize", derive(serde::Serialize))]
491#[cfg_attr(feature = "serde-deserialize", derive(serde::Deserialize))]
492pub enum IoThreadKeyword {
493 /// `IO_THREAD` — the documented spelling.
494 Io,
495 /// `RELAY_THREAD` — the synonym.
496 Relay,
497}
498
499/// One condition of a `START REPLICA … UNTIL <cond-list>` clause (`sql_yacc.yy`
500/// `replica_until`).
501///
502/// The grammar admits any single condition as the head of the list, but only the
503/// file/position coordinates (`SOURCE_LOG_FILE`/`SOURCE_LOG_POS`/`RELAY_LOG_FILE`/
504/// `RELAY_LOG_POS`, the `source_file_def` alternatives) may follow a comma — the parser
505/// enforces that a GTID/gaps condition appears only as the first element. Which combinations
506/// are *coherent* (a file needs its position, GTIDs and coordinates are mutually exclusive)
507/// is a semantic check (`ER_BAD_REPLICA_UNTIL_COND` = 1277, grammar-positive), left to a
508/// binding pass.
509#[derive(Clone, Debug, PartialEq, Eq, Hash)]
510#[cfg_attr(feature = "serde-serialize", derive(serde::Serialize))]
511#[cfg_attr(feature = "serde-deserialize", derive(serde::Deserialize))]
512pub enum ReplicaUntilCondition {
513 /// `SOURCE_LOG_FILE = '<f>'` — stop at the given source binary-log file.
514 SourceLogFile {
515 /// The source binary-log file name.
516 value: Literal,
517 /// Source location and node identity.
518 meta: Meta,
519 },
520 /// `SOURCE_LOG_POS = <n>` — stop at the given source binary-log position.
521 SourceLogPos {
522 /// The source binary-log position.
523 value: Literal,
524 /// Source location and node identity.
525 meta: Meta,
526 },
527 /// `RELAY_LOG_FILE = '<f>'` — stop at the given relay-log file.
528 RelayLogFile {
529 /// The relay-log file name.
530 value: Literal,
531 /// Source location and node identity.
532 meta: Meta,
533 },
534 /// `RELAY_LOG_POS = <n>` — stop at the given relay-log position.
535 RelayLogPos {
536 /// The relay-log position.
537 value: Literal,
538 /// Source location and node identity.
539 meta: Meta,
540 },
541 /// `SQL_BEFORE_GTIDS = '<gtid-set>'` — stop before applying the given GTIDs.
542 SqlBeforeGtids {
543 /// The GTID set.
544 value: Literal,
545 /// Source location and node identity.
546 meta: Meta,
547 },
548 /// `SQL_AFTER_GTIDS = '<gtid-set>'` — stop after applying the given GTIDs.
549 SqlAfterGtids {
550 /// The GTID set.
551 value: Literal,
552 /// Source location and node identity.
553 meta: Meta,
554 },
555 /// `SQL_AFTER_MTS_GAPS` — stop once the multi-threaded applier has filled its gaps.
556 SqlAfterMtsGaps {
557 /// Source location and node identity.
558 meta: Meta,
559 },
560}
561
562/// One option of `START GROUP_REPLICATION` (`sql_yacc.yy`
563/// `group_replication_start_option`). The options are comma-separated and order-preserving.
564#[derive(Clone, Debug, PartialEq, Eq, Hash)]
565#[cfg_attr(feature = "serde-serialize", derive(serde::Serialize))]
566#[cfg_attr(feature = "serde-deserialize", derive(serde::Deserialize))]
567pub enum GroupReplicationOption {
568 /// `USER = '<u>'` — the distributed-recovery account user.
569 User {
570 /// The user name.
571 value: Literal,
572 /// Source location and node identity.
573 meta: Meta,
574 },
575 /// `PASSWORD = '<p>'` — the distributed-recovery account password.
576 Password {
577 /// The password.
578 value: Literal,
579 /// Source location and node identity.
580 meta: Meta,
581 },
582 /// `DEFAULT_AUTH = '<a>'` — the distributed-recovery authentication plugin.
583 DefaultAuth {
584 /// The authentication plugin name.
585 value: Literal,
586 /// Source location and node identity.
587 meta: Meta,
588 },
589}