Skip to main content

sqruff_lib_dialects/
mysql.rs

1use sqruff_lib_core::dialects::Dialect;
2use sqruff_lib_core::dialects::init::DialectKind;
3use sqruff_lib_core::dialects::syntax::SyntaxKind;
4use sqruff_lib_core::helpers::{Config, ToMatchable};
5use sqruff_lib_core::parser::grammar::Ref;
6use sqruff_lib_core::parser::grammar::anyof::{AnyNumberOf, any_set_of, one_of};
7use sqruff_lib_core::parser::grammar::delimited::Delimited;
8use sqruff_lib_core::parser::grammar::sequence::{Bracketed, Sequence};
9use sqruff_lib_core::parser::lexer::Matcher;
10use sqruff_lib_core::parser::matchable::MatchableTrait;
11use sqruff_lib_core::parser::node_matcher::NodeMatcher;
12use sqruff_lib_core::parser::parsers::{RegexParser, StringParser, TypedParser};
13use sqruff_lib_core::parser::segments::meta::MetaSegment;
14use sqruff_lib_core::parser::types::ParseMode;
15
16use super::ansi;
17use crate::mysql_keywords::{
18    MYSQL_RESERVED_KEYWORDS, MYSQL_RESERVED_KEYWORDS_REMOVE, MYSQL_UNRESERVED_KEYWORDS,
19};
20use sqruff_lib_core::dialects::init::DialectConfig;
21use sqruff_lib_core::value::Value;
22
23sqruff_lib_core::dialect_config!(MySQLDialectConfig {});
24
25pub fn dialect(config: Option<&Value>) -> Dialect {
26    let _dialect_config: MySQLDialectConfig = config
27        .map(MySQLDialectConfig::from_value)
28        .unwrap_or_default();
29
30    raw_dialect().config(|dialect| dialect.expand())
31}
32
33pub fn raw_dialect() -> Dialect {
34    let mut mysql = ansi::raw_dialect();
35    mysql.name = DialectKind::Mysql;
36
37    // ============================================================
38    // Lexer matchers
39    // ============================================================
40
41    // Patch inline comments to support # syntax, and single/double quotes for MySQL escaping.
42    mysql.patch_lexer_matchers(vec![
43        Matcher::regex("inline_comment", r"(--|#)[^\n]*", SyntaxKind::InlineComment),
44        Matcher::regex(
45            "single_quote",
46            r"'([^'\\]|\\.|'')*'",
47            SyntaxKind::SingleQuote,
48        ),
49        Matcher::regex(
50            "double_quote",
51            r#""([^"\\]|\\.)*""#,
52            SyntaxKind::DoubleQuote,
53        ),
54    ]);
55
56    // Hexadecimal and bit value literals before numeric_literal.
57    mysql.insert_lexer_matchers(
58        vec![
59            Matcher::regex(
60                "hexadecimal_literal",
61                r"([xX]'([\da-fA-F][\da-fA-F])+'|0x[\da-fA-F]+)",
62                SyntaxKind::NumericLiteral,
63            ),
64            Matcher::regex(
65                "bit_value_literal",
66                r"([bB]'[01]+'|0b[01]+)",
67                SyntaxKind::NumericLiteral,
68            ),
69        ],
70        "numeric_literal",
71    );
72
73    // @ sign variables (session and system variables).
74    mysql.insert_lexer_matchers(
75        vec![Matcher::regex(
76            "at_sign",
77            r"@@?[a-zA-Z0-9_$]*(\.[a-zA-Z0-9_$]+)?",
78            SyntaxKind::AtSignLiteral,
79        )],
80        "word",
81    );
82
83    // && operator before &.
84    mysql.insert_lexer_matchers(
85        vec![Matcher::string(
86            "double_ampersand",
87            "&&",
88            SyntaxKind::DoubleAmpersand,
89        )],
90        "ampersand",
91    );
92
93    // || operator before |.
94    mysql.insert_lexer_matchers(
95        vec![Matcher::string(
96            "double_vertical_bar",
97            "||",
98            SyntaxKind::DoubleVerticalBar,
99        )],
100        "vertical_bar",
101    );
102
103    // := walrus operator before =.
104    mysql.insert_lexer_matchers(
105        vec![Matcher::string(
106            "walrus_operator",
107            ":=",
108            SyntaxKind::WalrusOperator,
109        )],
110        "equals",
111    );
112
113    // JSON path operators ->> and -> before >.
114    mysql.insert_lexer_matchers(
115        vec![
116            Matcher::string(
117                "inline_path_operator",
118                "->>",
119                SyntaxKind::InlinePathOperator,
120            ),
121            Matcher::string("column_path_operator", "->", SyntaxKind::ColumnPathOperator),
122        ],
123        "greater_than",
124    );
125
126    // ============================================================
127    // Keywords
128    // ============================================================
129
130    // Add MySQL unreserved keywords (don't clear inherited ANSI unreserved keywords).
131    for kw in MYSQL_UNRESERVED_KEYWORDS.lines() {
132        let kw = kw.trim();
133        if !kw.is_empty() {
134            mysql.sets_mut("unreserved_keywords").insert(
135                // SAFETY: We're leaking static strings from our keywords module.
136                // This is the same pattern used by other dialects.
137                kw,
138            );
139        }
140    }
141
142    // Replace reserved keywords entirely.
143    mysql.sets_mut("reserved_keywords").clear();
144    for kw in MYSQL_RESERVED_KEYWORDS.lines() {
145        let kw = kw.trim();
146        if !kw.is_empty() {
147            mysql.sets_mut("reserved_keywords").insert(kw);
148        }
149    }
150
151    // Remove some reserved keywords to avoid parsing issues.
152    for kw in MYSQL_RESERVED_KEYWORDS_REMOVE {
153        mysql.sets_mut("reserved_keywords").remove(kw);
154    }
155
156    // ============================================================
157    // Grammar replacements (overriding ANSI)
158    // ============================================================
159
160    // Double-quoted literal segment.
161    mysql.add([(
162        "DoubleQuotedLiteralSegment".into(),
163        TypedParser::new(SyntaxKind::DoubleQuote, SyntaxKind::QuotedLiteral)
164            .to_matchable()
165            .into(),
166    )]);
167
168    // AtSignLiteralSegment.
169    mysql.add([(
170        "AtSignLiteralSegment".into(),
171        TypedParser::new(SyntaxKind::AtSignLiteral, SyntaxKind::AtSignLiteral)
172            .to_matchable()
173            .into(),
174    )]);
175
176    // SystemVariableSegment - @@session.var or @@global.var.
177    mysql.add([(
178        "SystemVariableSegment".into(),
179        RegexParser::new(
180            r"@@(session|global)\.[A-Za-z0-9_]+",
181            SyntaxKind::SystemVariable,
182        )
183        .to_matchable()
184        .into(),
185    )]);
186
187    // DoubleQuotedJSONPath.
188    mysql.add([(
189        "DoubleQuotedJSONPath".into(),
190        TypedParser::new(SyntaxKind::DoubleQuote, SyntaxKind::JsonPath)
191            .to_matchable()
192            .into(),
193    )]);
194
195    // SingleQuotedJSONPath.
196    mysql.add([(
197        "SingleQuotedJSONPath".into(),
198        TypedParser::new(SyntaxKind::SingleQuote, SyntaxKind::JsonPath)
199            .to_matchable()
200            .into(),
201    )]);
202
203    // Parameter direction segments.
204    mysql.add([
205        (
206            "OutputParameterSegment".into(),
207            StringParser::new("OUT", SyntaxKind::ParameterDirection)
208                .to_matchable()
209                .into(),
210        ),
211        (
212            "InputParameterSegment".into(),
213            StringParser::new("IN", SyntaxKind::ParameterDirection)
214                .to_matchable()
215                .into(),
216        ),
217        (
218            "InputOutputParameterSegment".into(),
219            StringParser::new("INOUT", SyntaxKind::ParameterDirection)
220                .to_matchable()
221                .into(),
222        ),
223    ]);
224
225    // ProcedureParameterGrammar.
226    mysql.add([(
227        "ProcedureParameterGrammar".into(),
228        one_of(vec![
229            Sequence::new(vec![
230                one_of(vec![
231                    Ref::new("OutputParameterSegment").to_matchable(),
232                    Ref::new("InputParameterSegment").to_matchable(),
233                    Ref::new("InputOutputParameterSegment").to_matchable(),
234                ])
235                .config(|this| this.optional())
236                .to_matchable(),
237                Ref::new("ParameterNameSegment").optional().to_matchable(),
238                Ref::new("DatatypeSegment").to_matchable(),
239            ])
240            .to_matchable(),
241            Ref::new("DatatypeSegment").to_matchable(),
242        ])
243        .to_matchable()
244        .into(),
245    )]);
246
247    // LocalVariableNameSegment.
248    mysql.add([(
249        "LocalVariableNameSegment".into(),
250        RegexParser::new(r"`?[a-zA-Z0-9_$]*`?", SyntaxKind::Variable)
251            .to_matchable()
252            .into(),
253    )]);
254
255    // SessionVariableNameSegment - @name.
256    mysql.add([(
257        "SessionVariableNameSegment".into(),
258        RegexParser::new(r"[@][a-zA-Z0-9_$]*", SyntaxKind::Variable)
259            .to_matchable()
260            .into(),
261    )]);
262
263    // WalrusOperatorSegment - :=.
264    mysql.add([(
265        "WalrusOperatorSegment".into(),
266        StringParser::new(":=", SyntaxKind::AssignmentOperator)
267            .to_matchable()
268            .into(),
269    )]);
270
271    // VariableAssignmentSegment.
272    mysql.add([(
273        "VariableAssignmentSegment".into(),
274        Sequence::new(vec![
275            Ref::new("SessionVariableNameSegment").to_matchable(),
276            Ref::new("WalrusOperatorSegment").to_matchable(),
277            Ref::new("BaseExpressionElementGrammar").to_matchable(),
278        ])
279        .to_matchable()
280        .into(),
281    )]);
282
283    // JSON column path operators.
284    mysql.add([
285        (
286            "ColumnPathOperatorSegment".into(),
287            StringParser::new("->", SyntaxKind::ColumnPathOperator)
288                .to_matchable()
289                .into(),
290        ),
291        (
292            "InlinePathOperatorSegment".into(),
293            StringParser::new("->>", SyntaxKind::InlinePathOperator)
294                .to_matchable()
295                .into(),
296        ),
297    ]);
298
299    // BooleanDynamicSystemVariablesGrammar.
300    mysql.add([(
301        "BooleanDynamicSystemVariablesGrammar".into(),
302        one_of(vec![
303            one_of(vec![
304                Ref::keyword("ON").to_matchable(),
305                Ref::keyword("OFF").to_matchable(),
306            ])
307            .to_matchable(),
308            one_of(vec![
309                Ref::keyword("TRUE").to_matchable(),
310                Ref::keyword("FALSE").to_matchable(),
311            ])
312            .to_matchable(),
313        ])
314        .to_matchable()
315        .into(),
316    )]);
317
318    // BracketedKeyPartListGrammar - (key_part, ...).
319    mysql.add([(
320        "BracketedKeyPartListGrammar".into(),
321        Bracketed::new(vec![
322            Delimited::new(vec![
323                Sequence::new(vec![
324                    one_of(vec![
325                        Ref::new("ColumnReferenceSegment").to_matchable(),
326                        Sequence::new(vec![
327                            Ref::new("ColumnReferenceSegment").to_matchable(),
328                            Bracketed::new(vec![Ref::new("NumericLiteralSegment").to_matchable()])
329                                .to_matchable(),
330                        ])
331                        .to_matchable(),
332                        Bracketed::new(vec![Ref::new("ExpressionSegment").to_matchable()])
333                            .to_matchable(),
334                    ])
335                    .to_matchable(),
336                    one_of(vec![
337                        Ref::keyword("ASC").to_matchable(),
338                        Ref::keyword("DESC").to_matchable(),
339                    ])
340                    .config(|this| this.optional())
341                    .to_matchable(),
342                ])
343                .to_matchable(),
344            ])
345            .to_matchable(),
346        ])
347        .to_matchable()
348        .into(),
349    )]);
350
351    // TildeSegment for delimiter grammar.
352    mysql.add([(
353        "TildeSegment".into(),
354        StringParser::new("~", SyntaxKind::StatementTerminator)
355            .to_matchable()
356            .into(),
357    )]);
358
359    // ============================================================
360    // Grammar replacements
361    // ============================================================
362
363    // QuotedIdentifierSegment - MySQL uses backticks.
364    mysql.replace_grammar(
365        "QuotedIdentifierSegment",
366        TypedParser::new(SyntaxKind::BackQuote, SyntaxKind::QuotedIdentifier).to_matchable(),
367    );
368
369    // LiteralGrammar - add double-quoted literals and system variables.
370    let literal_grammar = mysql.grammar("LiteralGrammar");
371    mysql.replace_grammar(
372        "LiteralGrammar",
373        literal_grammar.copy(
374            Some(vec![
375                Ref::new("DoubleQuotedLiteralSegment").to_matchable(),
376                Ref::new("SystemVariableSegment").to_matchable(),
377            ]),
378            None,
379            None,
380            None,
381            vec![],
382            false,
383        ),
384    );
385
386    // FromClauseTerminatorGrammar - add index hints, partition, FOR, INTO.
387    let from_clause_terminator = mysql.grammar("FromClauseTerminatorGrammar");
388    mysql.replace_grammar(
389        "FromClauseTerminatorGrammar",
390        from_clause_terminator.copy(
391            Some(vec![
392                Ref::new("IndexHintClauseSegment").to_matchable(),
393                Ref::new("SelectPartitionClauseSegment").to_matchable(),
394                Ref::new("ForClauseSegment").to_matchable(),
395                Ref::new("SetOperatorSegment").to_matchable(),
396                Ref::new("WithNoSchemaBindingClauseSegment").to_matchable(),
397                Ref::new("IntoClauseSegment").to_matchable(),
398            ]),
399            None,
400            None,
401            None,
402            vec![],
403            false,
404        ),
405    );
406
407    // WhereClauseTerminatorGrammar - add INTO clause.
408    let where_clause_terminator = mysql.grammar("WhereClauseTerminatorGrammar");
409    mysql.replace_grammar(
410        "WhereClauseTerminatorGrammar",
411        where_clause_terminator.copy(
412            Some(vec![Ref::new("IntoClauseSegment").to_matchable()]),
413            None,
414            None,
415            None,
416            vec![],
417            false,
418        ),
419    );
420
421    // BaseExpressionElementGrammar - add session and local variables.
422    let base_expr = mysql.grammar("BaseExpressionElementGrammar");
423    mysql.replace_grammar(
424        "BaseExpressionElementGrammar",
425        base_expr.copy(
426            Some(vec![
427                Ref::new("SessionVariableNameSegment").to_matchable(),
428                Ref::new("LocalVariableNameSegment").to_matchable(),
429                Ref::new("VariableAssignmentSegment").to_matchable(),
430            ]),
431            None,
432            None,
433            None,
434            vec![],
435            false,
436        ),
437    );
438
439    // DateTimeLiteralGrammar - MySQL allows optional keyword.
440    mysql.replace_grammar(
441        "DateTimeLiteralGrammar",
442        Sequence::new(vec![
443            one_of(vec![
444                Ref::keyword("DATE").to_matchable(),
445                Ref::keyword("TIME").to_matchable(),
446                Ref::keyword("TIMESTAMP").to_matchable(),
447                Ref::keyword("DATETIME").to_matchable(),
448                Ref::keyword("INTERVAL").to_matchable(),
449            ])
450            .config(|this| this.optional())
451            .to_matchable(),
452            one_of(vec![
453                TypedParser::new(SyntaxKind::SingleQuote, SyntaxKind::DateConstructorLiteral)
454                    .to_matchable(),
455                Ref::new("NumericLiteralSegment").to_matchable(),
456            ])
457            .to_matchable(),
458        ])
459        .to_matchable(),
460    );
461
462    // QuotedLiteralSegment - MySQL allows whitespace-concatenated string literals.
463    mysql.replace_grammar(
464        "QuotedLiteralSegment",
465        AnyNumberOf::new(vec![
466            TypedParser::new(SyntaxKind::SingleQuote, SyntaxKind::QuotedLiteral).to_matchable(),
467            Ref::new("DoubleQuotedLiteralSegment").to_matchable(),
468        ])
469        .config(|this| this.min_times = 1)
470        .to_matchable(),
471    );
472
473    // UniqueKeyGrammar.
474    mysql.replace_grammar(
475        "UniqueKeyGrammar",
476        Sequence::new(vec![
477            Ref::keyword("UNIQUE").to_matchable(),
478            Ref::keyword("KEY").optional().to_matchable(),
479        ])
480        .to_matchable(),
481    );
482
483    // CharCharacterSetGrammar.
484    mysql.replace_grammar(
485        "CharCharacterSetGrammar",
486        Ref::keyword("BINARY").to_matchable(),
487    );
488
489    // DelimiterGrammar - semicolon or tilde.
490    mysql.replace_grammar(
491        "DelimiterGrammar",
492        one_of(vec![
493            Ref::new("SemicolonSegment").to_matchable(),
494            Ref::new("TildeSegment").to_matchable(),
495        ])
496        .to_matchable(),
497    );
498
499    // ParameterNameSegment.
500    mysql.replace_grammar(
501        "ParameterNameSegment",
502        RegexParser::new(r"`?[A-Za-z0-9_]*`?", SyntaxKind::Parameter).to_matchable(),
503    );
504
505    // SingleIdentifierGrammar - add session variables.
506    let single_id_grammar = mysql.grammar("SingleIdentifierGrammar");
507    mysql.replace_grammar(
508        "SingleIdentifierGrammar",
509        single_id_grammar.copy(
510            Some(vec![Ref::new("SessionVariableNameSegment").to_matchable()]),
511            None,
512            None,
513            None,
514            vec![],
515            false,
516        ),
517    );
518
519    // AndOperatorGrammar - AND and &&.
520    mysql.replace_grammar(
521        "AndOperatorGrammar",
522        one_of(vec![
523            StringParser::new("AND", SyntaxKind::BinaryOperator).to_matchable(),
524            StringParser::new("&&", SyntaxKind::BinaryOperator).to_matchable(),
525        ])
526        .to_matchable(),
527    );
528
529    // OrOperatorGrammar - OR, ||, and XOR.
530    mysql.replace_grammar(
531        "OrOperatorGrammar",
532        one_of(vec![
533            StringParser::new("OR", SyntaxKind::BinaryOperator).to_matchable(),
534            StringParser::new("||", SyntaxKind::BinaryOperator).to_matchable(),
535            StringParser::new("XOR", SyntaxKind::BinaryOperator).to_matchable(),
536        ])
537        .to_matchable(),
538    );
539
540    // NotOperatorGrammar - NOT and !.
541    mysql.replace_grammar(
542        "NotOperatorGrammar",
543        one_of(vec![
544            StringParser::new("NOT", SyntaxKind::Keyword).to_matchable(),
545            StringParser::new("!", SyntaxKind::NotOperator).to_matchable(),
546        ])
547        .to_matchable(),
548    );
549
550    // Expression_C_Grammar - add optional session variable assignment.
551    let expr_c = mysql.grammar("Expression_C_Grammar");
552    mysql.replace_grammar(
553        "Expression_C_Grammar",
554        Sequence::new(vec![
555            Sequence::new(vec![
556                Ref::new("SessionVariableNameSegment").to_matchable(),
557                Ref::new("WalrusOperatorSegment").to_matchable(),
558            ])
559            .config(|this| this.optional())
560            .to_matchable(),
561            expr_c,
562        ])
563        .to_matchable(),
564    );
565
566    // ============================================================
567    // MySQL-specific arithmetic operators (DIV, bitwise ops)
568    // ============================================================
569
570    mysql.add([(
571        "DivBinaryOperatorSegment".into(),
572        NodeMatcher::new(SyntaxKind::BinaryOperator, |_| {
573            Ref::keyword("DIV").to_matchable()
574        })
575        .to_matchable()
576        .into(),
577    )]);
578
579    mysql.replace_grammar(
580        "ArithmeticBinaryOperatorGrammar",
581        one_of(vec![
582            Ref::new("PlusSegment").to_matchable(),
583            Ref::new("MinusSegment").to_matchable(),
584            Ref::new("DivideSegment").to_matchable(),
585            Ref::new("MultiplySegment").to_matchable(),
586            Ref::new("ModuloSegment").to_matchable(),
587            Ref::new("BitwiseAndSegment").to_matchable(),
588            Ref::new("BitwiseOrSegment").to_matchable(),
589            Ref::new("BitwiseXorSegment").to_matchable(),
590            Ref::new("BitwiseLShiftSegment").to_matchable(),
591            Ref::new("BitwiseRShiftSegment").to_matchable(),
592            Ref::new("DivBinaryOperatorSegment").to_matchable(),
593        ])
594        .to_matchable(),
595    );
596
597    // MySQL 8.0+ supports CTEs with DML statements.
598    mysql.replace_grammar(
599        "NonWithSelectableGrammar",
600        one_of(vec![
601            Ref::new("SetExpressionSegment").to_matchable(),
602            Ref::new("SelectStatementSegment").to_matchable(),
603            Ref::new("NonSetSelectableGrammar").to_matchable(),
604            Ref::new("UpdateStatementSegment").to_matchable(),
605            Ref::new("InsertStatementSegment").to_matchable(),
606            Ref::new("DeleteStatementSegment").to_matchable(),
607        ])
608        .to_matchable(),
609    );
610
611    // ============================================================
612    // Segment definitions
613    // ============================================================
614
615    // ColumnDefinitionSegment.
616    mysql.replace_grammar(
617        "ColumnDefinitionSegment",
618        Sequence::new(vec![
619            Ref::new("SingleIdentifierGrammar").to_matchable(),
620            one_of(vec![
621                Ref::new("DatatypeSegment")
622                    .exclude(one_of(vec![
623                        Ref::keyword("DATETIME").to_matchable(),
624                        Ref::keyword("TIMESTAMP").to_matchable(),
625                    ]))
626                    .to_matchable(),
627                Sequence::new(vec![
628                    one_of(vec![
629                        Ref::keyword("DATETIME").to_matchable(),
630                        Ref::keyword("TIMESTAMP").to_matchable(),
631                    ])
632                    .to_matchable(),
633                    Sequence::new(vec![
634                        Bracketed::new(vec![Ref::new("NumericLiteralSegment").to_matchable()])
635                            .config(|this| this.optional())
636                            .to_matchable(),
637                    ])
638                    .config(|this| this.optional())
639                    .to_matchable(),
640                    Sequence::new(vec![
641                        Sequence::new(vec![Ref::keyword("NOT").to_matchable()])
642                            .config(|this| this.optional())
643                            .to_matchable(),
644                        Ref::keyword("NULL").to_matchable(),
645                    ])
646                    .config(|this| this.optional())
647                    .to_matchable(),
648                    Sequence::new(vec![
649                        Ref::keyword("DEFAULT").to_matchable(),
650                        one_of(vec![
651                            Sequence::new(vec![
652                                one_of(vec![
653                                    Ref::keyword("CURRENT_TIMESTAMP").to_matchable(),
654                                    Ref::keyword("NOW").to_matchable(),
655                                ])
656                                .to_matchable(),
657                                Bracketed::new(vec![
658                                    Ref::new("NumericLiteralSegment").optional().to_matchable(),
659                                ])
660                                .config(|this| this.optional())
661                                .to_matchable(),
662                            ])
663                            .to_matchable(),
664                            Ref::new("NumericLiteralSegment").to_matchable(),
665                            Ref::new("QuotedLiteralSegment").to_matchable(),
666                        ])
667                        .config(|this| this.optional())
668                        .to_matchable(),
669                    ])
670                    .config(|this| this.optional())
671                    .to_matchable(),
672                    Sequence::new(vec![
673                        Sequence::new(vec![
674                            Ref::keyword("ON").to_matchable(),
675                            Ref::keyword("UPDATE").to_matchable(),
676                        ])
677                        .config(|this| this.optional())
678                        .to_matchable(),
679                        Ref::keyword("CURRENT_TIMESTAMP").to_matchable(),
680                        Sequence::new(vec![
681                            Bracketed::new(vec![Ref::new("NumericLiteralSegment").to_matchable()])
682                                .to_matchable(),
683                        ])
684                        .config(|this| this.optional())
685                        .to_matchable(),
686                    ])
687                    .config(|this| this.optional())
688                    .to_matchable(),
689                ])
690                .to_matchable(),
691            ])
692            .to_matchable(),
693            Bracketed::new(vec![
694                Ref::new("ExpressionSegment").optional().to_matchable(),
695            ])
696            .config(|this| this.optional())
697            .to_matchable(),
698            AnyNumberOf::new(vec![
699                Ref::new("ColumnConstraintSegment")
700                    .optional()
701                    .to_matchable(),
702            ])
703            .to_matchable(),
704        ])
705        .to_matchable(),
706    );
707
708    // CreateTableStatementSegment - ANSI grammar plus MySQL table options.
709    mysql.replace_grammar(
710        "CreateTableStatementSegment",
711        Sequence::new(vec![
712            Ref::keyword("CREATE").to_matchable(),
713            Ref::new("OrReplaceGrammar").optional().to_matchable(),
714            Ref::new("TemporaryTransientGrammar")
715                .optional()
716                .to_matchable(),
717            Ref::keyword("TABLE").to_matchable(),
718            Ref::new("IfNotExistsGrammar").optional().to_matchable(),
719            Ref::new("TableReferenceSegment").to_matchable(),
720            one_of(vec![
721                Sequence::new(vec![
722                    Bracketed::new(vec![
723                        Delimited::new(vec![
724                            one_of(vec![
725                                Ref::new("TableConstraintSegment").to_matchable(),
726                                Ref::new("ColumnDefinitionSegment").to_matchable(),
727                            ])
728                            .to_matchable(),
729                        ])
730                        .to_matchable(),
731                    ])
732                    .to_matchable(),
733                    Ref::new("CommentClauseSegment").optional().to_matchable(),
734                ])
735                .to_matchable(),
736                Sequence::new(vec![
737                    Ref::keyword("AS").to_matchable(),
738                    Ref::new("SelectableGrammar").to_matchable(),
739                ])
740                .to_matchable(),
741                Sequence::new(vec![
742                    Ref::keyword("LIKE").to_matchable(),
743                    Ref::new("TableReferenceSegment").to_matchable(),
744                ])
745                .to_matchable(),
746            ])
747            .to_matchable(),
748            Ref::new("TableEndClauseSegment").optional().to_matchable(),
749            // MySQL table options
750            AnyNumberOf::new(vec![
751                Sequence::new(vec![
752                    Ref::keyword("DEFAULT").optional().to_matchable(),
753                    Ref::new("ParameterNameSegment").to_matchable(),
754                    Ref::new("EqualsSegment").optional().to_matchable(),
755                    one_of(vec![
756                        Ref::new("LiteralGrammar").to_matchable(),
757                        Ref::new("ParameterNameSegment").to_matchable(),
758                    ])
759                    .to_matchable(),
760                ])
761                .to_matchable(),
762            ])
763            .to_matchable(),
764        ])
765        .to_matchable(),
766    );
767
768    // CreateUserStatementSegment.
769    mysql.replace_grammar(
770        "CreateUserStatementSegment",
771        Sequence::new(vec![
772            Ref::keyword("CREATE").to_matchable(),
773            Ref::keyword("USER").to_matchable(),
774            Ref::new("IfNotExistsGrammar").optional().to_matchable(),
775            Delimited::new(vec![
776                Sequence::new(vec![
777                    Ref::new("RoleReferenceSegment").to_matchable(),
778                    Sequence::new(vec![
779                        Delimited::new(vec![
780                            Sequence::new(vec![
781                                Ref::keyword("IDENTIFIED").to_matchable(),
782                                one_of(vec![
783                                    Sequence::new(vec![
784                                        Ref::keyword("BY").to_matchable(),
785                                        one_of(vec![
786                                            Sequence::new(vec![
787                                                Ref::keyword("RANDOM").to_matchable(),
788                                                Ref::keyword("PASSWORD").to_matchable(),
789                                            ])
790                                            .to_matchable(),
791                                            Ref::new("QuotedLiteralSegment").to_matchable(),
792                                        ])
793                                        .to_matchable(),
794                                    ])
795                                    .to_matchable(),
796                                    Sequence::new(vec![
797                                        Ref::keyword("WITH").to_matchable(),
798                                        Ref::new("ObjectReferenceSegment").to_matchable(),
799                                        Sequence::new(vec![
800                                            one_of(vec![
801                                                Sequence::new(vec![
802                                                    Ref::keyword("BY").to_matchable(),
803                                                    one_of(vec![
804                                                        Sequence::new(vec![
805                                                            Ref::keyword("RANDOM").to_matchable(),
806                                                            Ref::keyword("PASSWORD").to_matchable(),
807                                                        ])
808                                                        .to_matchable(),
809                                                        Ref::new("QuotedLiteralSegment")
810                                                            .to_matchable(),
811                                                    ])
812                                                    .to_matchable(),
813                                                ])
814                                                .to_matchable(),
815                                                Sequence::new(vec![
816                                                    Ref::keyword("AS").to_matchable(),
817                                                    Ref::new("QuotedLiteralSegment").to_matchable(),
818                                                ])
819                                                .to_matchable(),
820                                                Sequence::new(vec![
821                                                    Ref::keyword("INITIAL").to_matchable(),
822                                                    Ref::keyword("AUTHENTICATION").to_matchable(),
823                                                    Ref::keyword("IDENTIFIED").to_matchable(),
824                                                    one_of(vec![
825                                                        Sequence::new(vec![
826                                                            Ref::keyword("BY").to_matchable(),
827                                                            one_of(vec![
828                                                                Sequence::new(vec![
829                                                                    Ref::keyword("RANDOM")
830                                                                        .to_matchable(),
831                                                                    Ref::keyword("PASSWORD")
832                                                                        .to_matchable(),
833                                                                ])
834                                                                .to_matchable(),
835                                                                Ref::new("QuotedLiteralSegment")
836                                                                    .to_matchable(),
837                                                            ])
838                                                            .to_matchable(),
839                                                        ])
840                                                        .to_matchable(),
841                                                        Sequence::new(vec![
842                                                            Ref::keyword("WITH").to_matchable(),
843                                                            Ref::new("ObjectReferenceSegment")
844                                                                .to_matchable(),
845                                                            Ref::keyword("AS").to_matchable(),
846                                                            Ref::new("QuotedLiteralSegment")
847                                                                .to_matchable(),
848                                                        ])
849                                                        .to_matchable(),
850                                                    ])
851                                                    .to_matchable(),
852                                                ])
853                                                .to_matchable(),
854                                            ])
855                                            .to_matchable(),
856                                        ])
857                                        .config(|this| this.optional())
858                                        .to_matchable(),
859                                    ])
860                                    .to_matchable(),
861                                ])
862                                .to_matchable(),
863                            ])
864                            .to_matchable(),
865                        ])
866                        .config(|this| this.delimiter(Ref::keyword("AND")))
867                        .to_matchable(),
868                    ])
869                    .config(|this| this.optional())
870                    .to_matchable(),
871                ])
872                .to_matchable(),
873            ])
874            .to_matchable(),
875            Sequence::new(vec![
876                Ref::keyword("DEFAULT").to_matchable(),
877                Ref::keyword("ROLE").to_matchable(),
878                Delimited::new(vec![Ref::new("RoleReferenceSegment").to_matchable()])
879                    .to_matchable(),
880            ])
881            .config(|this| this.optional())
882            .to_matchable(),
883            Sequence::new(vec![
884                Ref::keyword("REQUIRE").to_matchable(),
885                one_of(vec![
886                    Ref::keyword("NONE").to_matchable(),
887                    Delimited::new(vec![
888                        one_of(vec![
889                            Ref::keyword("SSL").to_matchable(),
890                            Ref::keyword("X509").to_matchable(),
891                            Sequence::new(vec![
892                                Ref::keyword("CIPHER").to_matchable(),
893                                Ref::new("QuotedLiteralSegment").to_matchable(),
894                            ])
895                            .to_matchable(),
896                            Sequence::new(vec![
897                                Ref::keyword("ISSUER").to_matchable(),
898                                Ref::new("QuotedLiteralSegment").to_matchable(),
899                            ])
900                            .to_matchable(),
901                            Sequence::new(vec![
902                                Ref::keyword("SUBJECT").to_matchable(),
903                                Ref::new("QuotedLiteralSegment").to_matchable(),
904                            ])
905                            .to_matchable(),
906                        ])
907                        .to_matchable(),
908                    ])
909                    .config(|this| this.delimiter(Ref::keyword("AND")))
910                    .to_matchable(),
911                ])
912                .to_matchable(),
913            ])
914            .config(|this| this.optional())
915            .to_matchable(),
916            Sequence::new(vec![
917                Ref::keyword("WITH").to_matchable(),
918                AnyNumberOf::new(vec![
919                    Sequence::new(vec![
920                        one_of(vec![
921                            Ref::keyword("MAX_QUERIES_PER_HOUR").to_matchable(),
922                            Ref::keyword("MAX_UPDATES_PER_HOUR").to_matchable(),
923                            Ref::keyword("MAX_CONNECTIONS_PER_HOUR").to_matchable(),
924                            Ref::keyword("MAX_USER_CONNECTIONS").to_matchable(),
925                        ])
926                        .to_matchable(),
927                        Ref::new("NumericLiteralSegment").to_matchable(),
928                    ])
929                    .to_matchable(),
930                ])
931                .to_matchable(),
932            ])
933            .config(|this| this.optional())
934            .to_matchable(),
935            AnyNumberOf::new(vec![
936                Sequence::new(vec![
937                    Ref::keyword("PASSWORD").to_matchable(),
938                    Ref::keyword("EXPIRE").to_matchable(),
939                    one_of(vec![
940                        Ref::keyword("DEFAULT").to_matchable(),
941                        Ref::keyword("NEVER").to_matchable(),
942                        Sequence::new(vec![
943                            Ref::keyword("INTERVAL").to_matchable(),
944                            Ref::new("NumericLiteralSegment").to_matchable(),
945                            Ref::keyword("DAY").to_matchable(),
946                        ])
947                        .to_matchable(),
948                    ])
949                    .config(|this| this.optional())
950                    .to_matchable(),
951                ])
952                .to_matchable(),
953                Sequence::new(vec![
954                    Ref::keyword("PASSWORD").to_matchable(),
955                    Ref::keyword("HISTORY").to_matchable(),
956                    one_of(vec![
957                        Ref::keyword("DEFAULT").to_matchable(),
958                        Ref::new("NumericLiteralSegment").to_matchable(),
959                    ])
960                    .to_matchable(),
961                ])
962                .to_matchable(),
963                Sequence::new(vec![
964                    Ref::keyword("PASSWORD").to_matchable(),
965                    Ref::keyword("REUSE").to_matchable(),
966                    Ref::keyword("INTERVAL").to_matchable(),
967                    one_of(vec![
968                        Ref::keyword("DEFAULT").to_matchable(),
969                        Sequence::new(vec![
970                            Ref::new("NumericLiteralSegment").to_matchable(),
971                            Ref::keyword("DAY").to_matchable(),
972                        ])
973                        .to_matchable(),
974                    ])
975                    .to_matchable(),
976                ])
977                .to_matchable(),
978                Sequence::new(vec![
979                    Ref::keyword("PASSWORD").to_matchable(),
980                    Ref::keyword("REQUIRE").to_matchable(),
981                    Ref::keyword("CURRENT").to_matchable(),
982                    one_of(vec![
983                        Ref::keyword("DEFAULT").to_matchable(),
984                        Ref::keyword("OPTIONAL").to_matchable(),
985                    ])
986                    .config(|this| this.optional())
987                    .to_matchable(),
988                ])
989                .to_matchable(),
990                Sequence::new(vec![
991                    Ref::keyword("FAILED_LOGIN_ATTEMPTS").to_matchable(),
992                    Ref::new("NumericLiteralSegment").to_matchable(),
993                ])
994                .to_matchable(),
995                Sequence::new(vec![
996                    Ref::keyword("PASSWORD_LOCK_TIME").to_matchable(),
997                    one_of(vec![
998                        Ref::new("NumericLiteralSegment").to_matchable(),
999                        Ref::keyword("UNBOUNDED").to_matchable(),
1000                    ])
1001                    .to_matchable(),
1002                ])
1003                .to_matchable(),
1004            ])
1005            .config(|this| this.optional())
1006            .to_matchable(),
1007            Sequence::new(vec![
1008                Ref::keyword("ACCOUNT").to_matchable(),
1009                one_of(vec![
1010                    Ref::keyword("UNLOCK").to_matchable(),
1011                    Ref::keyword("LOCK").to_matchable(),
1012                ])
1013                .to_matchable(),
1014            ])
1015            .config(|this| this.optional())
1016            .to_matchable(),
1017            Sequence::new(vec![
1018                one_of(vec![
1019                    Ref::keyword("COMMENT").to_matchable(),
1020                    Ref::keyword("ATTRIBUTE").to_matchable(),
1021                ])
1022                .to_matchable(),
1023                Ref::new("QuotedLiteralSegment").to_matchable(),
1024            ])
1025            .config(|this| this.optional())
1026            .to_matchable(),
1027        ])
1028        .to_matchable(),
1029    );
1030
1031    // ColumnConstraintSegment - add CHARACTER SET and COLLATE.
1032    // We inline the ANSI grammar here rather than using mysql.grammar() which would
1033    // embed a NodeMatcher directly (NodeMatcher doesn't support cache_key).
1034    mysql.replace_grammar(
1035        "ColumnConstraintSegment",
1036        Sequence::new(vec![
1037            Sequence::new(vec![
1038                Ref::keyword("CONSTRAINT").to_matchable(),
1039                Ref::new("ObjectReferenceSegment").to_matchable(),
1040            ])
1041            .config(|this| this.optional())
1042            .to_matchable(),
1043            one_of(vec![
1044                Sequence::new(vec![
1045                    Ref::keyword("NOT").optional().to_matchable(),
1046                    Ref::keyword("NULL").to_matchable(),
1047                ])
1048                .to_matchable(),
1049                Sequence::new(vec![
1050                    Ref::keyword("CHECK").to_matchable(),
1051                    Bracketed::new(vec![Ref::new("ExpressionSegment").to_matchable()])
1052                        .to_matchable(),
1053                ])
1054                .to_matchable(),
1055                Sequence::new(vec![
1056                    Ref::keyword("DEFAULT").to_matchable(),
1057                    Ref::new("ColumnConstraintDefaultGrammar").to_matchable(),
1058                ])
1059                .to_matchable(),
1060                Ref::new("PrimaryKeyGrammar").to_matchable(),
1061                Ref::new("UniqueKeyGrammar").to_matchable(),
1062                Ref::new("AutoIncrementGrammar").to_matchable(),
1063                Ref::new("ReferenceDefinitionGrammar").to_matchable(),
1064                Ref::new("CommentClauseSegment").to_matchable(),
1065                Sequence::new(vec![
1066                    Ref::keyword("COLLATE").to_matchable(),
1067                    Ref::new("CollationReferenceSegment").to_matchable(),
1068                ])
1069                .to_matchable(),
1070                // MySQL-specific: CHARACTER SET and COLLATE with NakedIdentifier
1071                Sequence::new(vec![
1072                    Ref::keyword("CHARACTER").to_matchable(),
1073                    Ref::keyword("SET").to_matchable(),
1074                    Ref::new("NakedIdentifierSegment").to_matchable(),
1075                ])
1076                .to_matchable(),
1077                Sequence::new(vec![
1078                    Ref::keyword("COLLATE").to_matchable(),
1079                    Ref::new("NakedIdentifierSegment").to_matchable(),
1080                ])
1081                .to_matchable(),
1082            ])
1083            .to_matchable(),
1084        ])
1085        .to_matchable(),
1086    );
1087
1088    // IndexTypeGrammar.
1089    mysql.add([(
1090        "IndexTypeGrammar".into(),
1091        Sequence::new(vec![
1092            Ref::keyword("USING").to_matchable(),
1093            one_of(vec![
1094                Ref::keyword("BTREE").to_matchable(),
1095                Ref::keyword("HASH").to_matchable(),
1096            ])
1097            .to_matchable(),
1098        ])
1099        .to_matchable()
1100        .into(),
1101    )]);
1102
1103    // IndexOptionsSegment.
1104    mysql.add([(
1105        "IndexOptionsSegment".into(),
1106        any_set_of(vec![
1107            Sequence::new(vec![
1108                Ref::keyword("KEY_BLOCK_SIZE").to_matchable(),
1109                Ref::new("EqualsSegment").optional().to_matchable(),
1110                Ref::new("NumericLiteralSegment").to_matchable(),
1111            ])
1112            .to_matchable(),
1113            Ref::new("IndexTypeGrammar").to_matchable(),
1114            Sequence::new(vec![
1115                Ref::keyword("WITH").to_matchable(),
1116                Ref::keyword("PARSER").to_matchable(),
1117                Ref::new("ObjectReferenceSegment").to_matchable(),
1118            ])
1119            .to_matchable(),
1120            Ref::new("CommentClauseSegment").to_matchable(),
1121            one_of(vec![
1122                Ref::keyword("VISIBLE").to_matchable(),
1123                Ref::keyword("INVISIBLE").to_matchable(),
1124            ])
1125            .to_matchable(),
1126            Sequence::new(vec![
1127                Ref::keyword("ENGINE_ATTRIBUTE").to_matchable(),
1128                Ref::new("EqualsSegment").optional().to_matchable(),
1129                Ref::new("QuotedLiteralSegment").to_matchable(),
1130            ])
1131            .to_matchable(),
1132            Sequence::new(vec![
1133                Ref::keyword("SECONDARY_ENGINE_ATTRIBUTE").to_matchable(),
1134                Ref::new("EqualsSegment").optional().to_matchable(),
1135                Ref::new("QuotedLiteralSegment").to_matchable(),
1136            ])
1137            .to_matchable(),
1138        ])
1139        .to_matchable()
1140        .into(),
1141    )]);
1142
1143    // TableConstraintSegment.
1144    mysql.replace_grammar(
1145        "TableConstraintSegment",
1146        one_of(vec![
1147            Sequence::new(vec![
1148                Sequence::new(vec![
1149                    Ref::keyword("CONSTRAINT").to_matchable(),
1150                    Ref::new("ObjectReferenceSegment").to_matchable(),
1151                ])
1152                .config(|this| this.optional())
1153                .to_matchable(),
1154                one_of(vec![
1155                    // UNIQUE [INDEX | KEY]
1156                    Sequence::new(vec![
1157                        Ref::keyword("UNIQUE").to_matchable(),
1158                        one_of(vec![
1159                            Ref::keyword("INDEX").to_matchable(),
1160                            Ref::keyword("KEY").to_matchable(),
1161                        ])
1162                        .config(|this| this.optional())
1163                        .to_matchable(),
1164                        Ref::new("IndexReferenceSegment").optional().to_matchable(),
1165                        Ref::new("IndexTypeGrammar").optional().to_matchable(),
1166                        Ref::new("BracketedKeyPartListGrammar").to_matchable(),
1167                        Ref::new("IndexOptionsSegment").optional().to_matchable(),
1168                    ])
1169                    .to_matchable(),
1170                    // PRIMARY KEY
1171                    Sequence::new(vec![
1172                        Ref::new("PrimaryKeyGrammar").to_matchable(),
1173                        Ref::new("IndexTypeGrammar").optional().to_matchable(),
1174                        Ref::new("BracketedKeyPartListGrammar").to_matchable(),
1175                        Ref::new("IndexOptionsSegment").optional().to_matchable(),
1176                    ])
1177                    .to_matchable(),
1178                    // FOREIGN KEY
1179                    Sequence::new(vec![
1180                        Ref::new("ForeignKeyGrammar").to_matchable(),
1181                        Ref::new("IndexReferenceSegment").optional().to_matchable(),
1182                        Ref::new("BracketedColumnReferenceListGrammar").to_matchable(),
1183                        Ref::keyword("REFERENCES").to_matchable(),
1184                        Ref::new("ColumnReferenceSegment").to_matchable(),
1185                        Ref::new("BracketedColumnReferenceListGrammar").to_matchable(),
1186                        AnyNumberOf::new(vec![
1187                            Sequence::new(vec![
1188                                Ref::keyword("ON").to_matchable(),
1189                                one_of(vec![
1190                                    Ref::keyword("DELETE").to_matchable(),
1191                                    Ref::keyword("UPDATE").to_matchable(),
1192                                ])
1193                                .to_matchable(),
1194                                one_of(vec![
1195                                    Ref::keyword("RESTRICT").to_matchable(),
1196                                    Ref::keyword("CASCADE").to_matchable(),
1197                                    Sequence::new(vec![
1198                                        Ref::keyword("SET").to_matchable(),
1199                                        Ref::keyword("NULL").to_matchable(),
1200                                    ])
1201                                    .to_matchable(),
1202                                    Sequence::new(vec![
1203                                        Ref::keyword("NO").to_matchable(),
1204                                        Ref::keyword("ACTION").to_matchable(),
1205                                    ])
1206                                    .to_matchable(),
1207                                    Sequence::new(vec![
1208                                        Ref::keyword("SET").to_matchable(),
1209                                        Ref::keyword("DEFAULT").to_matchable(),
1210                                    ])
1211                                    .to_matchable(),
1212                                ])
1213                                .to_matchable(),
1214                            ])
1215                            .config(|this| this.optional())
1216                            .to_matchable(),
1217                        ])
1218                        .to_matchable(),
1219                    ])
1220                    .to_matchable(),
1221                    // CHECK
1222                    Sequence::new(vec![
1223                        Ref::keyword("CHECK").to_matchable(),
1224                        Bracketed::new(vec![Ref::new("ExpressionSegment").to_matchable()])
1225                            .to_matchable(),
1226                        one_of(vec![
1227                            Ref::keyword("ENFORCED").to_matchable(),
1228                            Sequence::new(vec![
1229                                Ref::keyword("NOT").to_matchable(),
1230                                Ref::keyword("ENFORCED").to_matchable(),
1231                            ])
1232                            .to_matchable(),
1233                        ])
1234                        .config(|this| this.optional())
1235                        .to_matchable(),
1236                    ])
1237                    .to_matchable(),
1238                ])
1239                .to_matchable(),
1240            ])
1241            .to_matchable(),
1242            // {INDEX | KEY}
1243            Sequence::new(vec![
1244                one_of(vec![
1245                    Ref::keyword("INDEX").to_matchable(),
1246                    Ref::keyword("KEY").to_matchable(),
1247                ])
1248                .to_matchable(),
1249                Ref::new("IndexReferenceSegment").optional().to_matchable(),
1250                Ref::new("IndexTypeGrammar").optional().to_matchable(),
1251                Ref::new("BracketedKeyPartListGrammar").to_matchable(),
1252                Ref::new("IndexOptionsSegment").optional().to_matchable(),
1253            ])
1254            .to_matchable(),
1255            // {FULLTEXT | SPATIAL}
1256            Sequence::new(vec![
1257                one_of(vec![
1258                    Ref::keyword("FULLTEXT").to_matchable(),
1259                    Ref::keyword("SPATIAL").to_matchable(),
1260                ])
1261                .to_matchable(),
1262                one_of(vec![
1263                    Ref::keyword("INDEX").to_matchable(),
1264                    Ref::keyword("KEY").to_matchable(),
1265                ])
1266                .config(|this| this.optional())
1267                .to_matchable(),
1268                Ref::new("IndexReferenceSegment").optional().to_matchable(),
1269                Ref::new("BracketedKeyPartListGrammar").to_matchable(),
1270                Ref::new("IndexOptionsSegment").optional().to_matchable(),
1271            ])
1272            .to_matchable(),
1273        ])
1274        .to_matchable(),
1275    );
1276
1277    // CreateIndexStatementSegment.
1278    mysql.replace_grammar(
1279        "CreateIndexStatementSegment",
1280        Sequence::new(vec![
1281            Ref::keyword("CREATE").to_matchable(),
1282            one_of(vec![
1283                Ref::keyword("UNIQUE").to_matchable(),
1284                Ref::keyword("FULLTEXT").to_matchable(),
1285                Ref::keyword("SPATIAL").to_matchable(),
1286            ])
1287            .config(|this| this.optional())
1288            .to_matchable(),
1289            Ref::keyword("INDEX").to_matchable(),
1290            Ref::new("IndexReferenceSegment").to_matchable(),
1291            Ref::new("IndexTypeGrammar").optional().to_matchable(),
1292            Ref::keyword("ON").to_matchable(),
1293            Ref::new("TableReferenceSegment").to_matchable(),
1294            Ref::new("BracketedKeyPartListGrammar").to_matchable(),
1295            Ref::new("IndexOptionsSegment").optional().to_matchable(),
1296            any_set_of(vec![
1297                Sequence::new(vec![
1298                    Ref::keyword("ALGORITHM").to_matchable(),
1299                    Ref::new("EqualsSegment").optional().to_matchable(),
1300                    one_of(vec![
1301                        Ref::keyword("DEFAULT").to_matchable(),
1302                        Ref::keyword("INPLACE").to_matchable(),
1303                        Ref::keyword("COPY").to_matchable(),
1304                    ])
1305                    .to_matchable(),
1306                ])
1307                .to_matchable(),
1308                Sequence::new(vec![
1309                    Ref::keyword("LOCK").to_matchable(),
1310                    Ref::new("EqualsSegment").optional().to_matchable(),
1311                    one_of(vec![
1312                        Ref::keyword("DEFAULT").to_matchable(),
1313                        Ref::keyword("NONE").to_matchable(),
1314                        Ref::keyword("SHARED").to_matchable(),
1315                        Ref::keyword("EXCLUSIVE").to_matchable(),
1316                    ])
1317                    .to_matchable(),
1318                ])
1319                .to_matchable(),
1320            ])
1321            .to_matchable(),
1322        ])
1323        .to_matchable(),
1324    );
1325
1326    // IntervalExpressionSegment.
1327    mysql.replace_grammar(
1328        "IntervalExpressionSegment",
1329        Sequence::new(vec![
1330            Ref::keyword("INTERVAL").to_matchable(),
1331            one_of(vec![
1332                Sequence::new(vec![
1333                    Ref::new("ExpressionSegment").to_matchable(),
1334                    one_of(vec![
1335                        Ref::new("QuotedLiteralSegment").to_matchable(),
1336                        Ref::new("DatetimeUnitSegment").to_matchable(),
1337                    ])
1338                    .to_matchable(),
1339                ])
1340                .to_matchable(),
1341                Ref::new("QuotedLiteralSegment").to_matchable(),
1342            ])
1343            .to_matchable(),
1344        ])
1345        .to_matchable(),
1346    );
1347
1348    // RoleReferenceSegment.
1349    mysql.replace_grammar(
1350        "RoleReferenceSegment",
1351        one_of(vec![
1352            Sequence::new(vec![
1353                one_of(vec![
1354                    Ref::new("NakedIdentifierSegment").to_matchable(),
1355                    Ref::new("QuotedIdentifierSegment").to_matchable(),
1356                    Ref::new("SingleQuotedIdentifierSegment").to_matchable(),
1357                    Ref::new("DoubleQuotedLiteralSegment").to_matchable(),
1358                ])
1359                .to_matchable(),
1360                Sequence::new(vec![
1361                    Ref::new("AtSignLiteralSegment").to_matchable(),
1362                    one_of(vec![
1363                        Ref::new("NakedIdentifierSegment").to_matchable(),
1364                        Ref::new("QuotedIdentifierSegment").to_matchable(),
1365                        Ref::new("SingleQuotedIdentifierSegment").to_matchable(),
1366                        Ref::new("DoubleQuotedLiteralSegment").to_matchable(),
1367                    ])
1368                    .to_matchable(),
1369                ])
1370                .config(|this| this.optional())
1371                .to_matchable(),
1372            ])
1373            .to_matchable(),
1374            Ref::keyword("CURRENT_USER").to_matchable(),
1375        ])
1376        .to_matchable(),
1377    );
1378
1379    // UpsertClauseListSegment - ON DUPLICATE KEY UPDATE.
1380    mysql.add([(
1381        "UpsertClauseListSegment".into(),
1382        NodeMatcher::new(SyntaxKind::UpsertClauseList, |_| {
1383            Sequence::new(vec![
1384                Ref::keyword("ON").to_matchable(),
1385                Ref::keyword("DUPLICATE").to_matchable(),
1386                Ref::keyword("KEY").to_matchable(),
1387                Ref::keyword("UPDATE").to_matchable(),
1388                Delimited::new(vec![Ref::new("SetClauseSegment").to_matchable()]).to_matchable(),
1389            ])
1390            .to_matchable()
1391        })
1392        .to_matchable()
1393        .into(),
1394    )]);
1395
1396    // InsertRowAliasSegment.
1397    mysql.add([(
1398        "InsertRowAliasSegment".into(),
1399        NodeMatcher::new(SyntaxKind::InsertRowAlias, |_| {
1400            Sequence::new(vec![
1401                Ref::keyword("AS").to_matchable(),
1402                Ref::new("SingleIdentifierGrammar").to_matchable(),
1403                Bracketed::new(vec![Ref::new("SingleIdentifierListSegment").to_matchable()])
1404                    .config(|this| this.optional())
1405                    .to_matchable(),
1406            ])
1407            .to_matchable()
1408        })
1409        .to_matchable()
1410        .into(),
1411    )]);
1412
1413    // InsertStatementSegment.
1414    mysql.replace_grammar(
1415        "InsertStatementSegment",
1416        Sequence::new(vec![
1417            Ref::keyword("INSERT").to_matchable(),
1418            one_of(vec![
1419                Ref::keyword("LOW_PRIORITY").to_matchable(),
1420                Ref::keyword("DELAYED").to_matchable(),
1421                Ref::keyword("HIGH_PRIORITY").to_matchable(),
1422            ])
1423            .config(|this| this.optional())
1424            .to_matchable(),
1425            Ref::keyword("IGNORE").optional().to_matchable(),
1426            Ref::keyword("INTO").optional().to_matchable(),
1427            Ref::new("TableReferenceSegment").to_matchable(),
1428            Sequence::new(vec![
1429                Ref::keyword("PARTITION").to_matchable(),
1430                Bracketed::new(vec![Ref::new("SingleIdentifierListSegment").to_matchable()])
1431                    .to_matchable(),
1432            ])
1433            .config(|this| this.optional())
1434            .to_matchable(),
1435            Ref::new("BracketedColumnReferenceListGrammar")
1436                .optional()
1437                .to_matchable(),
1438            any_set_of(vec![
1439                one_of(vec![
1440                    Ref::new("ValuesClauseSegment").to_matchable(),
1441                    Ref::new("SetClauseListSegment").to_matchable(),
1442                    Sequence::new(vec![
1443                        one_of(vec![
1444                            Ref::new("SelectableGrammar").to_matchable(),
1445                            Sequence::new(vec![
1446                                Ref::keyword("TABLE").to_matchable(),
1447                                Ref::new("TableReferenceSegment").to_matchable(),
1448                            ])
1449                            .to_matchable(),
1450                        ])
1451                        .to_matchable(),
1452                    ])
1453                    .to_matchable(),
1454                ])
1455                .to_matchable(),
1456                Ref::new("InsertRowAliasSegment").optional().to_matchable(),
1457                Ref::new("UpsertClauseListSegment")
1458                    .optional()
1459                    .to_matchable(),
1460            ])
1461            .to_matchable(),
1462        ])
1463        .to_matchable(),
1464    );
1465
1466    // DeleteStatementSegment.
1467    mysql.replace_grammar(
1468        "DeleteStatementSegment",
1469        Sequence::new(vec![
1470            Ref::keyword("DELETE").to_matchable(),
1471            Ref::keyword("LOW_PRIORITY").optional().to_matchable(),
1472            Ref::keyword("QUICK").optional().to_matchable(),
1473            Ref::keyword("IGNORE").optional().to_matchable(),
1474            one_of(vec![
1475                // DELETE FROM ... USING ...
1476                Sequence::new(vec![
1477                    Ref::keyword("FROM").to_matchable(),
1478                    Delimited::new(vec![Ref::new("TableReferenceSegment").to_matchable()])
1479                        .config(|this| {
1480                            this.base.terminators = vec![Ref::keyword("USING").to_matchable()]
1481                        })
1482                        .to_matchable(),
1483                    Sequence::new(vec![
1484                        Ref::keyword("USING").to_matchable(),
1485                        Delimited::new(vec![Ref::new("FromExpressionSegment").to_matchable()])
1486                            .to_matchable(),
1487                    ])
1488                    .to_matchable(),
1489                    Ref::new("WhereClauseSegment").optional().to_matchable(),
1490                ])
1491                .to_matchable(),
1492                // DELETE ... FROM ...
1493                Sequence::new(vec![
1494                    Delimited::new(vec![Ref::new("TableReferenceSegment").to_matchable()])
1495                        .config(|this| {
1496                            this.base.terminators = vec![Ref::keyword("FROM").to_matchable()]
1497                        })
1498                        .to_matchable(),
1499                    Ref::new("FromClauseSegment").to_matchable(),
1500                    Ref::new("WhereClauseSegment").optional().to_matchable(),
1501                ])
1502                .to_matchable(),
1503                // Simple DELETE FROM ...
1504                Sequence::new(vec![
1505                    Ref::new("FromClauseSegment").to_matchable(),
1506                    Ref::new("SelectPartitionClauseSegment")
1507                        .optional()
1508                        .to_matchable(),
1509                    Ref::new("WhereClauseSegment").optional().to_matchable(),
1510                    Ref::new("OrderByClauseSegment").optional().to_matchable(),
1511                    Ref::new("LimitClauseSegment").optional().to_matchable(),
1512                ])
1513                .to_matchable(),
1514            ])
1515            .to_matchable(),
1516        ])
1517        .to_matchable(),
1518    );
1519
1520    // DeclareStatement.
1521    mysql.add([(
1522        "DeclareStatement".into(),
1523        NodeMatcher::new(SyntaxKind::DeclareStatement, |_| {
1524            one_of(vec![
1525                // DECLARE cursor
1526                Sequence::new(vec![
1527                    Ref::keyword("DECLARE").to_matchable(),
1528                    Ref::new("NakedIdentifierSegment").to_matchable(),
1529                    Ref::keyword("CURSOR").to_matchable(),
1530                    Ref::keyword("FOR").to_matchable(),
1531                    Ref::new("StatementSegment").to_matchable(),
1532                ])
1533                .to_matchable(),
1534                // DECLARE handler
1535                Sequence::new(vec![
1536                    Ref::keyword("DECLARE").to_matchable(),
1537                    one_of(vec![
1538                        Ref::keyword("CONTINUE").to_matchable(),
1539                        Ref::keyword("EXIT").to_matchable(),
1540                        Ref::keyword("UNDO").to_matchable(),
1541                    ])
1542                    .to_matchable(),
1543                    Ref::keyword("HANDLER").to_matchable(),
1544                    Ref::keyword("FOR").to_matchable(),
1545                    one_of(vec![
1546                        Ref::keyword("SQLEXCEPTION").to_matchable(),
1547                        Ref::keyword("SQLWARNING").to_matchable(),
1548                        Sequence::new(vec![
1549                            Ref::keyword("NOT").to_matchable(),
1550                            Ref::keyword("FOUND").to_matchable(),
1551                        ])
1552                        .to_matchable(),
1553                        Sequence::new(vec![
1554                            Ref::keyword("SQLSTATE").to_matchable(),
1555                            Ref::keyword("VALUE").optional().to_matchable(),
1556                            Ref::new("QuotedLiteralSegment").to_matchable(),
1557                        ])
1558                        .to_matchable(),
1559                        one_of(vec![
1560                            Ref::new("QuotedLiteralSegment").to_matchable(),
1561                            Ref::new("NumericLiteralSegment").to_matchable(),
1562                            Ref::new("NakedIdentifierSegment").to_matchable(),
1563                        ])
1564                        .to_matchable(),
1565                    ])
1566                    .to_matchable(),
1567                    Ref::new("StatementSegment").to_matchable(),
1568                ])
1569                .to_matchable(),
1570                // DECLARE condition
1571                Sequence::new(vec![
1572                    Ref::keyword("DECLARE").to_matchable(),
1573                    Ref::new("NakedIdentifierSegment").to_matchable(),
1574                    Ref::keyword("CONDITION").to_matchable(),
1575                    Ref::keyword("FOR").to_matchable(),
1576                    one_of(vec![
1577                        Ref::new("QuotedLiteralSegment").to_matchable(),
1578                        Ref::new("NumericLiteralSegment").to_matchable(),
1579                    ])
1580                    .to_matchable(),
1581                ])
1582                .to_matchable(),
1583                // DECLARE local variable
1584                Sequence::new(vec![
1585                    Ref::keyword("DECLARE").to_matchable(),
1586                    Ref::new("LocalVariableNameSegment").to_matchable(),
1587                    Ref::new("DatatypeSegment").to_matchable(),
1588                    Sequence::new(vec![
1589                        Ref::keyword("DEFAULT").to_matchable(),
1590                        one_of(vec![
1591                            Ref::new("QuotedLiteralSegment").to_matchable(),
1592                            Ref::new("NumericLiteralSegment").to_matchable(),
1593                            Ref::new("FunctionSegment").to_matchable(),
1594                        ])
1595                        .to_matchable(),
1596                    ])
1597                    .config(|this| this.optional())
1598                    .to_matchable(),
1599                ])
1600                .to_matchable(),
1601            ])
1602            .to_matchable()
1603        })
1604        .to_matchable()
1605        .into(),
1606    )]);
1607
1608    // DelimiterStatement.
1609    mysql.add([(
1610        "DelimiterStatement".into(),
1611        NodeMatcher::new(SyntaxKind::DelimiterStatement, |_| {
1612            Ref::keyword("DELIMITER").to_matchable()
1613        })
1614        .to_matchable()
1615        .into(),
1616    )]);
1617
1618    // DefinerSegment.
1619    mysql.add([(
1620        "DefinerSegment".into(),
1621        NodeMatcher::new(SyntaxKind::DefinerSegment, |_| {
1622            Sequence::new(vec![
1623                Ref::keyword("DEFINER").to_matchable(),
1624                Ref::new("EqualsSegment").to_matchable(),
1625                Ref::new("RoleReferenceSegment").to_matchable(),
1626            ])
1627            .to_matchable()
1628        })
1629        .to_matchable()
1630        .into(),
1631    )]);
1632
1633    // CharacteristicStatement.
1634    mysql.add([(
1635        "CharacteristicStatement".into(),
1636        NodeMatcher::new(SyntaxKind::CharacteristicStatement, |_| {
1637            Sequence::new(vec![
1638                one_of(vec![
1639                    Ref::keyword("DETERMINISTIC").to_matchable(),
1640                    Sequence::new(vec![
1641                        Ref::keyword("NOT").to_matchable(),
1642                        Ref::keyword("DETERMINISTIC").to_matchable(),
1643                    ])
1644                    .to_matchable(),
1645                ])
1646                .to_matchable(),
1647                Sequence::new(vec![
1648                    Ref::keyword("LANGUAGE").to_matchable(),
1649                    Ref::keyword("SQL").to_matchable(),
1650                ])
1651                .config(|this| this.optional())
1652                .to_matchable(),
1653                one_of(vec![
1654                    Sequence::new(vec![
1655                        Ref::keyword("CONTAINS").to_matchable(),
1656                        Ref::keyword("SQL").to_matchable(),
1657                    ])
1658                    .to_matchable(),
1659                    Sequence::new(vec![
1660                        Ref::keyword("NO").to_matchable(),
1661                        Ref::keyword("SQL").to_matchable(),
1662                    ])
1663                    .to_matchable(),
1664                    Sequence::new(vec![
1665                        Ref::keyword("READS").to_matchable(),
1666                        Ref::keyword("SQL").to_matchable(),
1667                        Ref::keyword("DATA").to_matchable(),
1668                    ])
1669                    .to_matchable(),
1670                    Sequence::new(vec![
1671                        Ref::keyword("MODIFIES").to_matchable(),
1672                        Ref::keyword("SQL").to_matchable(),
1673                        Ref::keyword("DATA").to_matchable(),
1674                    ])
1675                    .to_matchable(),
1676                ])
1677                .config(|this| this.optional())
1678                .to_matchable(),
1679                Sequence::new(vec![
1680                    Ref::keyword("SQL").to_matchable(),
1681                    Ref::keyword("SECURITY").to_matchable(),
1682                    one_of(vec![
1683                        Ref::keyword("DEFINER").to_matchable(),
1684                        Ref::keyword("INVOKER").to_matchable(),
1685                    ])
1686                    .to_matchable(),
1687                ])
1688                .config(|this| this.optional())
1689                .to_matchable(),
1690            ])
1691            .to_matchable()
1692        })
1693        .to_matchable()
1694        .into(),
1695    )]);
1696
1697    // FunctionDefinitionGrammar (body of CREATE FUNCTION/PROCEDURE).
1698    mysql.add([(
1699        "FunctionDefinitionGrammar".into(),
1700        NodeMatcher::new(SyntaxKind::FunctionDefinition, |_| {
1701            Ref::new("TransactionStatementSegment").to_matchable()
1702        })
1703        .to_matchable()
1704        .into(),
1705    )]);
1706
1707    // CreateProcedureStatementSegment.
1708    mysql.add([(
1709        "CreateProcedureStatementSegment".into(),
1710        NodeMatcher::new(SyntaxKind::CreateProcedureStatement, |_| {
1711            Sequence::new(vec![
1712                Ref::keyword("CREATE").to_matchable(),
1713                Ref::new("DefinerSegment").optional().to_matchable(),
1714                Ref::keyword("PROCEDURE").to_matchable(),
1715                Ref::new("FunctionNameSegment").to_matchable(),
1716                Ref::new("ProcedureParameterListGrammar")
1717                    .optional()
1718                    .to_matchable(),
1719                Ref::new("CommentClauseSegment").optional().to_matchable(),
1720                Ref::new("CharacteristicStatement")
1721                    .optional()
1722                    .to_matchable(),
1723                Ref::new("FunctionDefinitionGrammar").to_matchable(),
1724            ])
1725            .to_matchable()
1726        })
1727        .to_matchable()
1728        .into(),
1729    )]);
1730
1731    // CreateFunctionStatementSegment.
1732    mysql.replace_grammar(
1733        "CreateFunctionStatementSegment",
1734        Sequence::new(vec![
1735            Ref::keyword("CREATE").to_matchable(),
1736            Ref::new("DefinerSegment").optional().to_matchable(),
1737            Ref::keyword("FUNCTION").to_matchable(),
1738            Ref::new("FunctionNameSegment").to_matchable(),
1739            Ref::new("FunctionParameterListGrammar")
1740                .optional()
1741                .to_matchable(),
1742            Sequence::new(vec![
1743                Ref::keyword("RETURNS").to_matchable(),
1744                Ref::new("DatatypeSegment").to_matchable(),
1745            ])
1746            .to_matchable(),
1747            Ref::new("CommentClauseSegment").optional().to_matchable(),
1748            Ref::new("CharacteristicStatement").to_matchable(),
1749            Ref::new("FunctionDefinitionGrammar").to_matchable(),
1750        ])
1751        .to_matchable(),
1752    );
1753
1754    // ProcedureParameterListGrammar.
1755    mysql.add([(
1756        "ProcedureParameterListGrammar".into(),
1757        NodeMatcher::new(SyntaxKind::ProcedureParameterList, |_| {
1758            Bracketed::new(vec![
1759                Delimited::new(vec![Ref::new("ProcedureParameterGrammar").to_matchable()])
1760                    .config(|this| this.optional())
1761                    .to_matchable(),
1762            ])
1763            .to_matchable()
1764        })
1765        .to_matchable()
1766        .into(),
1767    )]);
1768
1769    // TransactionStatementSegment.
1770    mysql.replace_grammar(
1771        "TransactionStatementSegment",
1772        one_of(vec![
1773            Sequence::new(vec![
1774                Ref::keyword("START").to_matchable(),
1775                Ref::keyword("TRANSACTION").to_matchable(),
1776            ])
1777            .to_matchable(),
1778            Sequence::new(vec![
1779                Sequence::new(vec![
1780                    Ref::new("SingleIdentifierGrammar").to_matchable(),
1781                    Ref::new("ColonSegment").to_matchable(),
1782                ])
1783                .config(|this| this.optional())
1784                .to_matchable(),
1785                Sequence::new(vec![
1786                    Ref::keyword("BEGIN").to_matchable(),
1787                    Ref::keyword("WORK").optional().to_matchable(),
1788                    Ref::new("StatementSegment").to_matchable(),
1789                ])
1790                .to_matchable(),
1791            ])
1792            .to_matchable(),
1793            Sequence::new(vec![
1794                Ref::keyword("LEAVE").to_matchable(),
1795                Ref::new("SingleIdentifierGrammar")
1796                    .optional()
1797                    .to_matchable(),
1798            ])
1799            .to_matchable(),
1800            Sequence::new(vec![
1801                Ref::keyword("COMMIT").to_matchable(),
1802                Ref::keyword("WORK").optional().to_matchable(),
1803                Sequence::new(vec![
1804                    Ref::keyword("AND").to_matchable(),
1805                    Ref::keyword("NO").optional().to_matchable(),
1806                    Ref::keyword("CHAIN").to_matchable(),
1807                ])
1808                .config(|this| this.optional())
1809                .to_matchable(),
1810            ])
1811            .to_matchable(),
1812            Sequence::new(vec![
1813                Ref::keyword("ROLLBACK").to_matchable(),
1814                Ref::keyword("WORK").optional().to_matchable(),
1815            ])
1816            .to_matchable(),
1817            Sequence::new(vec![
1818                Ref::keyword("END").to_matchable(),
1819                Ref::new("SingleIdentifierGrammar")
1820                    .optional()
1821                    .to_matchable(),
1822            ])
1823            .to_matchable(),
1824        ])
1825        .to_matchable(),
1826    );
1827
1828    // SetAssignmentStatementSegment.
1829    mysql.add([(
1830        "SetAssignmentStatementSegment".into(),
1831        NodeMatcher::new(SyntaxKind::SetStatement, |_| {
1832            Sequence::new(vec![
1833                Ref::keyword("SET").to_matchable(),
1834                Delimited::new(vec![
1835                    Sequence::new(vec![
1836                        one_of(vec![
1837                            Ref::new("SessionVariableNameSegment").to_matchable(),
1838                            Ref::new("LocalVariableNameSegment").to_matchable(),
1839                        ])
1840                        .to_matchable(),
1841                        one_of(vec![
1842                            Ref::new("EqualsSegment").to_matchable(),
1843                            Ref::new("WalrusOperatorSegment").to_matchable(),
1844                        ])
1845                        .to_matchable(),
1846                        AnyNumberOf::new(vec![
1847                            Ref::new("QuotedLiteralSegment").to_matchable(),
1848                            Ref::new("DoubleQuotedLiteralSegment").to_matchable(),
1849                            Ref::new("SessionVariableNameSegment").to_matchable(),
1850                            Ref::new("BooleanDynamicSystemVariablesGrammar").to_matchable(),
1851                            Ref::new("LocalVariableNameSegment").to_matchable(),
1852                            Ref::new("FunctionSegment").to_matchable(),
1853                            Ref::new("ArithmeticBinaryOperatorGrammar").to_matchable(),
1854                            Ref::new("ExpressionSegment").to_matchable(),
1855                        ])
1856                        .to_matchable(),
1857                    ])
1858                    .to_matchable(),
1859                ])
1860                .to_matchable(),
1861            ])
1862            .to_matchable()
1863        })
1864        .to_matchable()
1865        .into(),
1866    )]);
1867
1868    // IfExpressionStatement.
1869    mysql.add([(
1870        "IfExpressionStatement".into(),
1871        NodeMatcher::new(SyntaxKind::IfThenStatement, |_| {
1872            AnyNumberOf::new(vec![
1873                Sequence::new(vec![
1874                    Ref::keyword("IF").to_matchable(),
1875                    Ref::new("ExpressionSegment").to_matchable(),
1876                    Ref::keyword("THEN").to_matchable(),
1877                    Ref::new("StatementSegment").to_matchable(),
1878                ])
1879                .to_matchable(),
1880                Sequence::new(vec![
1881                    Ref::keyword("ELSEIF").to_matchable(),
1882                    Ref::new("ExpressionSegment").to_matchable(),
1883                    Ref::keyword("THEN").to_matchable(),
1884                    Ref::new("StatementSegment").to_matchable(),
1885                ])
1886                .to_matchable(),
1887                Sequence::new(vec![
1888                    Ref::keyword("ELSE").to_matchable(),
1889                    Ref::new("StatementSegment").to_matchable(),
1890                ])
1891                .config(|this| this.optional())
1892                .to_matchable(),
1893                Sequence::new(vec![
1894                    Ref::keyword("END").to_matchable(),
1895                    Ref::keyword("IF").to_matchable(),
1896                ])
1897                .to_matchable(),
1898            ])
1899            .to_matchable()
1900        })
1901        .to_matchable()
1902        .into(),
1903    )]);
1904
1905    // SelectClauseModifierSegment.
1906    mysql.replace_grammar(
1907        "SelectClauseModifierSegment",
1908        Sequence::new(vec![
1909            one_of(vec![
1910                Ref::keyword("DISTINCT").to_matchable(),
1911                Ref::keyword("ALL").to_matchable(),
1912                Ref::keyword("DISTINCTROW").to_matchable(),
1913            ])
1914            .config(|this| this.optional())
1915            .to_matchable(),
1916            Ref::keyword("HIGH_PRIORITY").optional().to_matchable(),
1917            Ref::keyword("STRAIGHT_JOIN").optional().to_matchable(),
1918            Ref::keyword("SQL_SMALL_RESULT").optional().to_matchable(),
1919            Ref::keyword("SQL_BIG_RESULT").optional().to_matchable(),
1920            Ref::keyword("SQL_BUFFER_RESULT").optional().to_matchable(),
1921            Ref::keyword("SQL_CACHE").optional().to_matchable(),
1922            Ref::keyword("SQL_NO_CACHE").optional().to_matchable(),
1923            Ref::keyword("SQL_CALC_FOUND_ROWS")
1924                .optional()
1925                .to_matchable(),
1926        ])
1927        .config(|this| this.optional())
1928        .to_matchable(),
1929    );
1930
1931    // IntoClauseSegment.
1932    mysql.add([(
1933        "IntoClauseSegment".into(),
1934        NodeMatcher::new(SyntaxKind::IntoClause, |_| {
1935            Sequence::new(vec![
1936                Ref::keyword("INTO").to_matchable(),
1937                one_of(vec![
1938                    Delimited::new(vec![
1939                        one_of(vec![
1940                            Ref::new("SessionVariableNameSegment").to_matchable(),
1941                            Ref::new("NakedIdentifierSegment").to_matchable(),
1942                        ])
1943                        .to_matchable(),
1944                    ])
1945                    .to_matchable(),
1946                    Sequence::new(vec![
1947                        Ref::keyword("DUMPFILE").to_matchable(),
1948                        Ref::new("QuotedLiteralSegment").to_matchable(),
1949                    ])
1950                    .to_matchable(),
1951                    Sequence::new(vec![
1952                        Ref::keyword("OUTFILE").to_matchable(),
1953                        Ref::new("QuotedLiteralSegment").to_matchable(),
1954                        Sequence::new(vec![
1955                            Ref::keyword("CHARACTER").to_matchable(),
1956                            Ref::keyword("SET").to_matchable(),
1957                            Ref::new("NakedIdentifierSegment").to_matchable(),
1958                        ])
1959                        .config(|this| this.optional())
1960                        .to_matchable(),
1961                        Sequence::new(vec![
1962                            one_of(vec![
1963                                Ref::keyword("FIELDS").to_matchable(),
1964                                Ref::keyword("COLUMNS").to_matchable(),
1965                            ])
1966                            .to_matchable(),
1967                            Sequence::new(vec![
1968                                Ref::keyword("TERMINATED").to_matchable(),
1969                                Ref::keyword("BY").to_matchable(),
1970                                Ref::new("QuotedLiteralSegment").to_matchable(),
1971                            ])
1972                            .config(|this| this.optional())
1973                            .to_matchable(),
1974                            Sequence::new(vec![
1975                                Ref::keyword("OPTIONALLY").optional().to_matchable(),
1976                                Ref::keyword("ENCLOSED").to_matchable(),
1977                                Ref::keyword("BY").to_matchable(),
1978                                Ref::new("QuotedLiteralSegment").to_matchable(),
1979                            ])
1980                            .config(|this| this.optional())
1981                            .to_matchable(),
1982                            Sequence::new(vec![
1983                                Ref::keyword("ESCAPED").to_matchable(),
1984                                Ref::keyword("BY").to_matchable(),
1985                                Ref::new("QuotedLiteralSegment").to_matchable(),
1986                            ])
1987                            .config(|this| this.optional())
1988                            .to_matchable(),
1989                        ])
1990                        .config(|this| this.optional())
1991                        .to_matchable(),
1992                        Sequence::new(vec![
1993                            Ref::keyword("LINES").to_matchable(),
1994                            Sequence::new(vec![
1995                                Ref::keyword("STARTING").to_matchable(),
1996                                Ref::keyword("BY").to_matchable(),
1997                                Ref::new("QuotedLiteralSegment").to_matchable(),
1998                            ])
1999                            .config(|this| this.optional())
2000                            .to_matchable(),
2001                            Sequence::new(vec![
2002                                Ref::keyword("TERMINATED").to_matchable(),
2003                                Ref::keyword("BY").to_matchable(),
2004                                Ref::new("QuotedLiteralSegment").to_matchable(),
2005                            ])
2006                            .config(|this| this.optional())
2007                            .to_matchable(),
2008                        ])
2009                        .config(|this| this.optional())
2010                        .to_matchable(),
2011                    ])
2012                    .to_matchable(),
2013                ])
2014                .to_matchable(),
2015            ])
2016            .to_matchable()
2017        })
2018        .to_matchable()
2019        .into(),
2020    )]);
2021
2022    // ForClauseSegment.
2023    mysql.add([(
2024        "ForClauseSegment".into(),
2025        NodeMatcher::new(SyntaxKind::ForClause, |_| {
2026            one_of(vec![
2027                Sequence::new(vec![
2028                    Sequence::new(vec![
2029                        Ref::keyword("FOR").to_matchable(),
2030                        one_of(vec![
2031                            Ref::keyword("UPDATE").to_matchable(),
2032                            Ref::keyword("SHARE").to_matchable(),
2033                        ])
2034                        .to_matchable(),
2035                    ])
2036                    .to_matchable(),
2037                    Sequence::new(vec![
2038                        Ref::keyword("OF").to_matchable(),
2039                        Delimited::new(vec![Ref::new("NakedIdentifierSegment").to_matchable()])
2040                            .to_matchable(),
2041                    ])
2042                    .config(|this| this.optional())
2043                    .to_matchable(),
2044                    one_of(vec![
2045                        Ref::keyword("NOWAIT").to_matchable(),
2046                        Sequence::new(vec![
2047                            Ref::keyword("SKIP").to_matchable(),
2048                            Ref::keyword("LOCKED").to_matchable(),
2049                        ])
2050                        .to_matchable(),
2051                    ])
2052                    .config(|this| this.optional())
2053                    .to_matchable(),
2054                ])
2055                .to_matchable(),
2056                Sequence::new(vec![
2057                    Ref::keyword("LOCK").to_matchable(),
2058                    Ref::keyword("IN").to_matchable(),
2059                    Ref::keyword("SHARE").to_matchable(),
2060                    Ref::keyword("MODE").to_matchable(),
2061                ])
2062                .to_matchable(),
2063            ])
2064            .config(|this| this.optional())
2065            .to_matchable()
2066        })
2067        .to_matchable()
2068        .into(),
2069    )]);
2070
2071    // IndexHintClauseSegment.
2072    mysql.add([(
2073        "IndexHintClauseSegment".into(),
2074        NodeMatcher::new(SyntaxKind::IndexHintClause, |_| {
2075            Sequence::new(vec![
2076                one_of(vec![
2077                    Ref::keyword("USE").to_matchable(),
2078                    Ref::keyword("IGNORE").to_matchable(),
2079                    Ref::keyword("FORCE").to_matchable(),
2080                ])
2081                .to_matchable(),
2082                one_of(vec![
2083                    Ref::keyword("INDEX").to_matchable(),
2084                    Ref::keyword("KEY").to_matchable(),
2085                ])
2086                .to_matchable(),
2087                Sequence::new(vec![
2088                    Ref::keyword("FOR").to_matchable(),
2089                    one_of(vec![
2090                        Ref::keyword("JOIN").to_matchable(),
2091                        Sequence::new(vec![
2092                            Ref::keyword("ORDER").to_matchable(),
2093                            Ref::keyword("BY").to_matchable(),
2094                        ])
2095                        .to_matchable(),
2096                        Sequence::new(vec![
2097                            Ref::keyword("GROUP").to_matchable(),
2098                            Ref::keyword("BY").to_matchable(),
2099                        ])
2100                        .to_matchable(),
2101                    ])
2102                    .config(|this| this.optional())
2103                    .to_matchable(),
2104                ])
2105                .config(|this| this.optional())
2106                .to_matchable(),
2107                Bracketed::new(vec![Ref::new("ObjectReferenceSegment").to_matchable()])
2108                    .to_matchable(),
2109                Ref::new("JoinOnConditionSegment").optional().to_matchable(),
2110            ])
2111            .to_matchable()
2112        })
2113        .to_matchable()
2114        .into(),
2115    )]);
2116
2117    // CallStoredProcedureSegment.
2118    mysql.add([(
2119        "CallStoredProcedureSegment".into(),
2120        NodeMatcher::new(SyntaxKind::CallSegment, |_| {
2121            Sequence::new(vec![
2122                Ref::keyword("CALL").to_matchable(),
2123                one_of(vec![
2124                    Ref::new("SingleIdentifierGrammar").to_matchable(),
2125                    Ref::new("QuotedIdentifierSegment").to_matchable(),
2126                ])
2127                .to_matchable(),
2128                Bracketed::new(vec![
2129                    AnyNumberOf::new(vec![
2130                        Delimited::new(vec![
2131                            Ref::new("QuotedLiteralSegment").to_matchable(),
2132                            Ref::new("NumericLiteralSegment").to_matchable(),
2133                            Ref::new("DoubleQuotedLiteralSegment").to_matchable(),
2134                            Ref::new("SessionVariableNameSegment").to_matchable(),
2135                            Ref::new("LocalVariableNameSegment").to_matchable(),
2136                            Ref::new("FunctionSegment").to_matchable(),
2137                        ])
2138                        .to_matchable(),
2139                    ])
2140                    .to_matchable(),
2141                ])
2142                .to_matchable(),
2143            ])
2144            .to_matchable()
2145        })
2146        .to_matchable()
2147        .into(),
2148    )]);
2149
2150    // SelectPartitionClauseSegment.
2151    mysql.add([(
2152        "SelectPartitionClauseSegment".into(),
2153        NodeMatcher::new(SyntaxKind::PartitionClause, |_| {
2154            Sequence::new(vec![
2155                Ref::keyword("PARTITION").to_matchable(),
2156                Bracketed::new(vec![
2157                    Delimited::new(vec![Ref::new("ObjectReferenceSegment").to_matchable()])
2158                        .to_matchable(),
2159                ])
2160                .to_matchable(),
2161            ])
2162            .to_matchable()
2163        })
2164        .to_matchable()
2165        .into(),
2166    )]);
2167
2168    // WhileStatementSegment.
2169    mysql.add([(
2170        "WhileStatementSegment".into(),
2171        NodeMatcher::new(SyntaxKind::WhileStatement, |_| {
2172            one_of(vec![
2173                Sequence::new(vec![
2174                    Sequence::new(vec![
2175                        Ref::new("SingleIdentifierGrammar").to_matchable(),
2176                        Ref::new("ColonSegment").to_matchable(),
2177                    ])
2178                    .config(|this| this.optional())
2179                    .to_matchable(),
2180                    Sequence::new(vec![
2181                        Ref::keyword("WHILE").to_matchable(),
2182                        Ref::new("ExpressionSegment").to_matchable(),
2183                        Ref::keyword("DO").to_matchable(),
2184                        AnyNumberOf::new(vec![Ref::new("StatementSegment").to_matchable()])
2185                            .to_matchable(),
2186                    ])
2187                    .to_matchable(),
2188                ])
2189                .to_matchable(),
2190                Sequence::new(vec![
2191                    Ref::keyword("END").to_matchable(),
2192                    Ref::keyword("WHILE").to_matchable(),
2193                    Ref::new("SingleIdentifierGrammar")
2194                        .optional()
2195                        .to_matchable(),
2196                ])
2197                .to_matchable(),
2198            ])
2199            .to_matchable()
2200        })
2201        .to_matchable()
2202        .into(),
2203    )]);
2204
2205    // PrepareSegment.
2206    mysql.add([(
2207        "PrepareSegment".into(),
2208        NodeMatcher::new(SyntaxKind::PrepareSegment, |_| {
2209            Sequence::new(vec![
2210                Ref::keyword("PREPARE").to_matchable(),
2211                Ref::new("NakedIdentifierSegment").to_matchable(),
2212                Ref::keyword("FROM").to_matchable(),
2213                one_of(vec![
2214                    Ref::new("QuotedLiteralSegment").to_matchable(),
2215                    Ref::new("SessionVariableNameSegment").to_matchable(),
2216                    Ref::new("LocalVariableNameSegment").to_matchable(),
2217                ])
2218                .to_matchable(),
2219            ])
2220            .to_matchable()
2221        })
2222        .to_matchable()
2223        .into(),
2224    )]);
2225
2226    // GetDiagnosticsSegment.
2227    mysql.add([(
2228        "GetDiagnosticsSegment".into(),
2229        NodeMatcher::new(SyntaxKind::GetDiagnosticsSegment, |_| {
2230            Sequence::new(vec![
2231                Ref::keyword("GET").to_matchable(),
2232                Sequence::new(vec![
2233                    Ref::keyword("CURRENT").to_matchable(),
2234                    Ref::keyword("STACKED").to_matchable(),
2235                ])
2236                .config(|this| this.optional())
2237                .to_matchable(),
2238                Ref::keyword("DIAGNOSTICS").to_matchable(),
2239                Delimited::new(vec![
2240                    Sequence::new(vec![
2241                        one_of(vec![
2242                            Ref::new("SessionVariableNameSegment").to_matchable(),
2243                            Ref::new("LocalVariableNameSegment").to_matchable(),
2244                        ])
2245                        .to_matchable(),
2246                        Ref::new("EqualsSegment").to_matchable(),
2247                        one_of(vec![
2248                            Ref::keyword("NUMBER").to_matchable(),
2249                            Ref::keyword("ROW_COUNT").to_matchable(),
2250                        ])
2251                        .to_matchable(),
2252                    ])
2253                    .to_matchable(),
2254                ])
2255                .config(|this| this.optional())
2256                .to_matchable(),
2257                Ref::keyword("CONDITION").to_matchable(),
2258                one_of(vec![
2259                    Ref::new("SessionVariableNameSegment").to_matchable(),
2260                    Ref::new("LocalVariableNameSegment").to_matchable(),
2261                    Ref::new("NumericLiteralSegment").to_matchable(),
2262                ])
2263                .to_matchable(),
2264                Delimited::new(vec![
2265                    Sequence::new(vec![
2266                        one_of(vec![
2267                            Ref::new("SessionVariableNameSegment").to_matchable(),
2268                            Ref::new("LocalVariableNameSegment").to_matchable(),
2269                        ])
2270                        .to_matchable(),
2271                        Ref::new("EqualsSegment").to_matchable(),
2272                        one_of(vec![
2273                            Ref::keyword("CLASS_ORIGIN").to_matchable(),
2274                            Ref::keyword("SUBCLASS_ORIGIN").to_matchable(),
2275                            Ref::keyword("RETURNED_SQLSTATE").to_matchable(),
2276                            Ref::keyword("MESSAGE_TEXT").to_matchable(),
2277                            Ref::keyword("MYSQL_ERRNO").to_matchable(),
2278                            Ref::keyword("CONSTRAINT_CATALOG").to_matchable(),
2279                            Ref::keyword("CONSTRAINT_SCHEMA").to_matchable(),
2280                            Ref::keyword("CONSTRAINT_NAME").to_matchable(),
2281                            Ref::keyword("CATALOG_NAME").to_matchable(),
2282                            Ref::keyword("SCHEMA_NAME").to_matchable(),
2283                            Ref::keyword("TABLE_NAME").to_matchable(),
2284                            Ref::keyword("COLUMN_NAME").to_matchable(),
2285                            Ref::keyword("CURSOR_NAME").to_matchable(),
2286                        ])
2287                        .to_matchable(),
2288                    ])
2289                    .to_matchable(),
2290                ])
2291                .config(|this| this.optional())
2292                .to_matchable(),
2293            ])
2294            .to_matchable()
2295        })
2296        .to_matchable()
2297        .into(),
2298    )]);
2299
2300    // LoopStatementSegment.
2301    mysql.add([(
2302        "LoopStatementSegment".into(),
2303        NodeMatcher::new(SyntaxKind::LoopStatement, |_| {
2304            one_of(vec![
2305                Sequence::new(vec![
2306                    Sequence::new(vec![
2307                        Ref::new("SingleIdentifierGrammar").to_matchable(),
2308                        Ref::new("ColonSegment").to_matchable(),
2309                    ])
2310                    .config(|this| this.optional())
2311                    .to_matchable(),
2312                    Ref::keyword("LOOP").to_matchable(),
2313                    Delimited::new(vec![Ref::new("StatementSegment").to_matchable()])
2314                        .to_matchable(),
2315                ])
2316                .to_matchable(),
2317                Sequence::new(vec![
2318                    Ref::keyword("END").to_matchable(),
2319                    Ref::keyword("LOOP").to_matchable(),
2320                    Ref::new("SingleIdentifierGrammar")
2321                        .optional()
2322                        .to_matchable(),
2323                ])
2324                .to_matchable(),
2325            ])
2326            .to_matchable()
2327        })
2328        .to_matchable()
2329        .into(),
2330    )]);
2331
2332    // CursorOpenCloseSegment.
2333    mysql.add([(
2334        "CursorOpenCloseSegment".into(),
2335        NodeMatcher::new(SyntaxKind::CursorOpenCloseSegment, |_| {
2336            Sequence::new(vec![
2337                one_of(vec![
2338                    Ref::keyword("CLOSE").to_matchable(),
2339                    Ref::keyword("OPEN").to_matchable(),
2340                ])
2341                .to_matchable(),
2342                one_of(vec![
2343                    Ref::new("SingleIdentifierGrammar").to_matchable(),
2344                    Ref::new("QuotedIdentifierSegment").to_matchable(),
2345                ])
2346                .to_matchable(),
2347            ])
2348            .to_matchable()
2349        })
2350        .to_matchable()
2351        .into(),
2352    )]);
2353
2354    // IterateStatementSegment.
2355    mysql.add([(
2356        "IterateStatementSegment".into(),
2357        NodeMatcher::new(SyntaxKind::IterateStatement, |_| {
2358            Sequence::new(vec![
2359                Ref::keyword("ITERATE").to_matchable(),
2360                Ref::new("SingleIdentifierGrammar").to_matchable(),
2361            ])
2362            .to_matchable()
2363        })
2364        .to_matchable()
2365        .into(),
2366    )]);
2367
2368    // ExecuteSegment.
2369    mysql.add([(
2370        "ExecuteSegment".into(),
2371        NodeMatcher::new(SyntaxKind::ExecuteSegment, |_| {
2372            Sequence::new(vec![
2373                Ref::keyword("EXECUTE").to_matchable(),
2374                Ref::new("NakedIdentifierSegment").to_matchable(),
2375                Sequence::new(vec![
2376                    Ref::keyword("USING").to_matchable(),
2377                    Delimited::new(vec![Ref::new("SessionVariableNameSegment").to_matchable()])
2378                        .to_matchable(),
2379                ])
2380                .config(|this| this.optional())
2381                .to_matchable(),
2382            ])
2383            .to_matchable()
2384        })
2385        .to_matchable()
2386        .into(),
2387    )]);
2388
2389    // RepeatStatementSegment.
2390    mysql.add([(
2391        "RepeatStatementSegment".into(),
2392        NodeMatcher::new(SyntaxKind::RepeatStatement, |_| {
2393            one_of(vec![
2394                Sequence::new(vec![
2395                    Sequence::new(vec![
2396                        Ref::new("SingleIdentifierGrammar").to_matchable(),
2397                        Ref::new("ColonSegment").to_matchable(),
2398                    ])
2399                    .config(|this| this.optional())
2400                    .to_matchable(),
2401                    Ref::keyword("REPEAT").to_matchable(),
2402                    AnyNumberOf::new(vec![Ref::new("StatementSegment").to_matchable()])
2403                        .to_matchable(),
2404                ])
2405                .to_matchable(),
2406                Sequence::new(vec![
2407                    Ref::keyword("UNTIL").to_matchable(),
2408                    Ref::new("ExpressionSegment").to_matchable(),
2409                    Sequence::new(vec![
2410                        Ref::keyword("END").to_matchable(),
2411                        Ref::keyword("REPEAT").to_matchable(),
2412                        Ref::new("SingleIdentifierGrammar")
2413                            .optional()
2414                            .to_matchable(),
2415                    ])
2416                    .to_matchable(),
2417                ])
2418                .to_matchable(),
2419            ])
2420            .to_matchable()
2421        })
2422        .to_matchable()
2423        .into(),
2424    )]);
2425
2426    // DeallocateSegment.
2427    mysql.add([(
2428        "DeallocateSegment".into(),
2429        NodeMatcher::new(SyntaxKind::DeallocateSegment, |_| {
2430            Sequence::new(vec![
2431                Sequence::new(vec![
2432                    one_of(vec![
2433                        Ref::keyword("DEALLOCATE").to_matchable(),
2434                        Ref::keyword("DROP").to_matchable(),
2435                    ])
2436                    .to_matchable(),
2437                    Ref::keyword("PREPARE").to_matchable(),
2438                ])
2439                .to_matchable(),
2440                Ref::new("NakedIdentifierSegment").to_matchable(),
2441            ])
2442            .to_matchable()
2443        })
2444        .to_matchable()
2445        .into(),
2446    )]);
2447
2448    // ResignalSegment (handles both SIGNAL and RESIGNAL).
2449    mysql.add([(
2450        "ResignalSegment".into(),
2451        NodeMatcher::new(SyntaxKind::ResignalSegment, |_| {
2452            Sequence::new(vec![
2453                one_of(vec![
2454                    Ref::keyword("SIGNAL").to_matchable(),
2455                    Ref::keyword("RESIGNAL").to_matchable(),
2456                ])
2457                .to_matchable(),
2458                one_of(vec![
2459                    Sequence::new(vec![
2460                        Ref::keyword("SQLSTATE").to_matchable(),
2461                        Ref::keyword("VALUE").optional().to_matchable(),
2462                        Ref::new("QuotedLiteralSegment").to_matchable(),
2463                    ])
2464                    .to_matchable(),
2465                    Ref::new("NakedIdentifierSegment").to_matchable(),
2466                ])
2467                .config(|this| this.optional())
2468                .to_matchable(),
2469                Sequence::new(vec![
2470                    Ref::keyword("SET").to_matchable(),
2471                    Delimited::new(vec![
2472                        Sequence::new(vec![
2473                            one_of(vec![
2474                                Ref::keyword("CLASS_ORIGIN").to_matchable(),
2475                                Ref::keyword("SUBCLASS_ORIGIN").to_matchable(),
2476                                Ref::keyword("RETURNED_SQLSTATE").to_matchable(),
2477                                Ref::keyword("MESSAGE_TEXT").to_matchable(),
2478                                Ref::keyword("MYSQL_ERRNO").to_matchable(),
2479                                Ref::keyword("CONSTRAINT_CATALOG").to_matchable(),
2480                                Ref::keyword("CONSTRAINT_SCHEMA").to_matchable(),
2481                                Ref::keyword("CONSTRAINT_NAME").to_matchable(),
2482                                Ref::keyword("CATALOG_NAME").to_matchable(),
2483                                Ref::keyword("SCHEMA_NAME").to_matchable(),
2484                                Ref::keyword("TABLE_NAME").to_matchable(),
2485                                Ref::keyword("COLUMN_NAME").to_matchable(),
2486                                Ref::keyword("CURSOR_NAME").to_matchable(),
2487                            ])
2488                            .to_matchable(),
2489                            Ref::new("EqualsSegment").to_matchable(),
2490                            one_of(vec![
2491                                Ref::new("SessionVariableNameSegment").to_matchable(),
2492                                Ref::new("LocalVariableNameSegment").to_matchable(),
2493                                Ref::new("QuotedLiteralSegment").to_matchable(),
2494                            ])
2495                            .to_matchable(),
2496                        ])
2497                        .to_matchable(),
2498                    ])
2499                    .to_matchable(),
2500                ])
2501                .config(|this| this.optional())
2502                .to_matchable(),
2503            ])
2504            .to_matchable()
2505        })
2506        .to_matchable()
2507        .into(),
2508    )]);
2509
2510    // CursorFetchSegment.
2511    mysql.add([(
2512        "CursorFetchSegment".into(),
2513        NodeMatcher::new(SyntaxKind::CursorFetchSegment, |_| {
2514            Sequence::new(vec![
2515                Ref::keyword("FETCH").to_matchable(),
2516                Sequence::new(vec![
2517                    Ref::keyword("NEXT").optional().to_matchable(),
2518                    Ref::keyword("FROM").to_matchable(),
2519                ])
2520                .config(|this| this.optional())
2521                .to_matchable(),
2522                Ref::new("NakedIdentifierSegment").to_matchable(),
2523                Ref::keyword("INTO").to_matchable(),
2524                Delimited::new(vec![
2525                    Ref::new("SessionVariableNameSegment").to_matchable(),
2526                    Ref::new("LocalVariableNameSegment").to_matchable(),
2527                ])
2528                .to_matchable(),
2529            ])
2530            .to_matchable()
2531        })
2532        .to_matchable()
2533        .into(),
2534    )]);
2535
2536    // DropIndexStatementSegment.
2537    mysql.replace_grammar(
2538        "DropIndexStatementSegment",
2539        Sequence::new(vec![
2540            Ref::keyword("DROP").to_matchable(),
2541            Ref::keyword("INDEX").to_matchable(),
2542            Ref::new("IndexReferenceSegment").to_matchable(),
2543            Ref::keyword("ON").to_matchable(),
2544            Ref::new("TableReferenceSegment").to_matchable(),
2545            one_of(vec![
2546                Sequence::new(vec![
2547                    Ref::keyword("ALGORITHM").to_matchable(),
2548                    Ref::new("EqualsSegment").optional().to_matchable(),
2549                    one_of(vec![
2550                        Ref::keyword("DEFAULT").to_matchable(),
2551                        Ref::keyword("INPLACE").to_matchable(),
2552                        Ref::keyword("COPY").to_matchable(),
2553                    ])
2554                    .to_matchable(),
2555                ])
2556                .to_matchable(),
2557                Sequence::new(vec![
2558                    Ref::keyword("LOCK").to_matchable(),
2559                    Ref::new("EqualsSegment").optional().to_matchable(),
2560                    one_of(vec![
2561                        Ref::keyword("DEFAULT").to_matchable(),
2562                        Ref::keyword("NONE").to_matchable(),
2563                        Ref::keyword("SHARED").to_matchable(),
2564                        Ref::keyword("EXCLUSIVE").to_matchable(),
2565                    ])
2566                    .to_matchable(),
2567                ])
2568                .to_matchable(),
2569            ])
2570            .config(|this| this.optional())
2571            .to_matchable(),
2572        ])
2573        .to_matchable(),
2574    );
2575
2576    // DropProcedureStatementSegment.
2577    mysql.add([(
2578        "DropProcedureStatementSegment".into(),
2579        NodeMatcher::new(SyntaxKind::DropProcedureStatement, |_| {
2580            Sequence::new(vec![
2581                Ref::keyword("DROP").to_matchable(),
2582                one_of(vec![
2583                    Ref::keyword("PROCEDURE").to_matchable(),
2584                    Ref::keyword("FUNCTION").to_matchable(),
2585                ])
2586                .to_matchable(),
2587                Ref::new("IfExistsGrammar").optional().to_matchable(),
2588                Ref::new("ObjectReferenceSegment").to_matchable(),
2589            ])
2590            .to_matchable()
2591        })
2592        .to_matchable()
2593        .into(),
2594    )]);
2595
2596    // AlterTableStatementSegment.
2597    mysql.replace_grammar(
2598        "AlterTableStatementSegment",
2599        Sequence::new(vec![
2600            Ref::keyword("ALTER").to_matchable(),
2601            Ref::keyword("TABLE").to_matchable(),
2602            Ref::new("TableReferenceSegment").to_matchable(),
2603            Delimited::new(vec![
2604                one_of(vec![
2605                    // Table options
2606                    Sequence::new(vec![
2607                        Ref::new("ParameterNameSegment").to_matchable(),
2608                        Ref::new("EqualsSegment").optional().to_matchable(),
2609                        one_of(vec![
2610                            Ref::new("LiteralGrammar").to_matchable(),
2611                            Ref::new("NakedIdentifierSegment").to_matchable(),
2612                        ])
2613                        .to_matchable(),
2614                    ])
2615                    .to_matchable(),
2616                    // ADD/MODIFY column
2617                    Sequence::new(vec![
2618                        one_of(vec![
2619                            Ref::keyword("ADD").to_matchable(),
2620                            Ref::keyword("MODIFY").to_matchable(),
2621                        ])
2622                        .to_matchable(),
2623                        Ref::keyword("COLUMN").optional().to_matchable(),
2624                        Ref::new("ColumnDefinitionSegment").to_matchable(),
2625                        one_of(vec![
2626                            Sequence::new(vec![
2627                                one_of(vec![
2628                                    Ref::keyword("FIRST").to_matchable(),
2629                                    Ref::keyword("AFTER").to_matchable(),
2630                                ])
2631                                .to_matchable(),
2632                                Ref::new("ColumnReferenceSegment").to_matchable(),
2633                            ])
2634                            .to_matchable(),
2635                            Ref::new("BracketedColumnReferenceListGrammar").to_matchable(),
2636                        ])
2637                        .config(|this| this.optional())
2638                        .to_matchable(),
2639                    ])
2640                    .to_matchable(),
2641                    // ADD constraint
2642                    Sequence::new(vec![
2643                        Ref::keyword("ADD").to_matchable(),
2644                        Ref::new("TableConstraintSegment").to_matchable(),
2645                    ])
2646                    .to_matchable(),
2647                    // CHANGE column
2648                    Sequence::new(vec![
2649                        Ref::keyword("CHANGE").to_matchable(),
2650                        Ref::keyword("COLUMN").optional().to_matchable(),
2651                        Ref::new("ColumnReferenceSegment").to_matchable(),
2652                        Ref::new("ColumnDefinitionSegment").to_matchable(),
2653                        one_of(vec![
2654                            Ref::keyword("FIRST").to_matchable(),
2655                            Sequence::new(vec![
2656                                Ref::keyword("AFTER").to_matchable(),
2657                                Ref::new("ColumnReferenceSegment").to_matchable(),
2658                            ])
2659                            .to_matchable(),
2660                        ])
2661                        .config(|this| this.optional())
2662                        .to_matchable(),
2663                    ])
2664                    .to_matchable(),
2665                    // DROP
2666                    Sequence::new(vec![
2667                        Ref::keyword("DROP").to_matchable(),
2668                        one_of(vec![
2669                            Sequence::new(vec![
2670                                Ref::keyword("COLUMN").optional().to_matchable(),
2671                                Ref::new("ColumnReferenceSegment").to_matchable(),
2672                            ])
2673                            .to_matchable(),
2674                            Sequence::new(vec![
2675                                one_of(vec![
2676                                    Ref::keyword("INDEX").to_matchable(),
2677                                    Ref::keyword("KEY").to_matchable(),
2678                                ])
2679                                .config(|this| this.optional())
2680                                .to_matchable(),
2681                                Ref::new("IndexReferenceSegment").to_matchable(),
2682                            ])
2683                            .to_matchable(),
2684                            Ref::new("PrimaryKeyGrammar").to_matchable(),
2685                            Sequence::new(vec![
2686                                Ref::new("ForeignKeyGrammar").to_matchable(),
2687                                Ref::new("ObjectReferenceSegment").to_matchable(),
2688                            ])
2689                            .to_matchable(),
2690                            Sequence::new(vec![
2691                                one_of(vec![
2692                                    Ref::keyword("CHECK").to_matchable(),
2693                                    Ref::keyword("CONSTRAINT").to_matchable(),
2694                                ])
2695                                .to_matchable(),
2696                                Ref::new("ObjectReferenceSegment").to_matchable(),
2697                            ])
2698                            .to_matchable(),
2699                        ])
2700                        .to_matchable(),
2701                    ])
2702                    .to_matchable(),
2703                    // ALTER CHECK/CONSTRAINT
2704                    Sequence::new(vec![
2705                        Ref::keyword("ALTER").to_matchable(),
2706                        one_of(vec![
2707                            Ref::keyword("CHECK").to_matchable(),
2708                            Ref::keyword("CONSTRAINT").to_matchable(),
2709                        ])
2710                        .to_matchable(),
2711                        Ref::new("ObjectReferenceSegment").to_matchable(),
2712                        one_of(vec![
2713                            Ref::keyword("ENFORCED").to_matchable(),
2714                            Sequence::new(vec![
2715                                Ref::keyword("NOT").to_matchable(),
2716                                Ref::keyword("ENFORCED").to_matchable(),
2717                            ])
2718                            .to_matchable(),
2719                        ])
2720                        .to_matchable(),
2721                    ])
2722                    .to_matchable(),
2723                    // ALTER INDEX
2724                    Sequence::new(vec![
2725                        Ref::keyword("ALTER").to_matchable(),
2726                        Ref::keyword("INDEX").to_matchable(),
2727                        Ref::new("IndexReferenceSegment").to_matchable(),
2728                        one_of(vec![
2729                            Ref::keyword("VISIBLE").to_matchable(),
2730                            Ref::keyword("INVISIBLE").to_matchable(),
2731                        ])
2732                        .to_matchable(),
2733                    ])
2734                    .to_matchable(),
2735                    // RENAME
2736                    Sequence::new(vec![
2737                        Ref::keyword("RENAME").to_matchable(),
2738                        one_of(vec![
2739                            Sequence::new(vec![
2740                                one_of(vec![
2741                                    Ref::keyword("AS").to_matchable(),
2742                                    Ref::keyword("TO").to_matchable(),
2743                                ])
2744                                .config(|this| this.optional())
2745                                .to_matchable(),
2746                                Ref::new("TableReferenceSegment").to_matchable(),
2747                            ])
2748                            .to_matchable(),
2749                        ])
2750                        .to_matchable(),
2751                    ])
2752                    .to_matchable(),
2753                    // ENABLE/DISABLE KEYS
2754                    Sequence::new(vec![
2755                        one_of(vec![
2756                            Ref::keyword("DISABLE").to_matchable(),
2757                            Ref::keyword("ENABLE").to_matchable(),
2758                        ])
2759                        .to_matchable(),
2760                        Ref::keyword("KEYS").to_matchable(),
2761                    ])
2762                    .to_matchable(),
2763                ])
2764                .to_matchable(),
2765            ])
2766            .to_matchable(),
2767        ])
2768        .to_matchable(),
2769    );
2770
2771    // WithCheckOptionSegment.
2772    mysql.add([(
2773        "WithCheckOptionSegment".into(),
2774        NodeMatcher::new(SyntaxKind::WithCheckOption, |_| {
2775            Sequence::new(vec![
2776                Ref::keyword("WITH").to_matchable(),
2777                one_of(vec![
2778                    Ref::keyword("CASCADED").to_matchable(),
2779                    Ref::keyword("LOCAL").to_matchable(),
2780                ])
2781                .config(|this| this.optional())
2782                .to_matchable(),
2783                Ref::keyword("CHECK").to_matchable(),
2784                Ref::keyword("OPTION").to_matchable(),
2785            ])
2786            .to_matchable()
2787        })
2788        .to_matchable()
2789        .into(),
2790    )]);
2791
2792    // AlterViewStatementSegment.
2793    mysql.add([(
2794        "AlterViewStatementSegment".into(),
2795        NodeMatcher::new(SyntaxKind::AlterViewStatement, |_| {
2796            Sequence::new(vec![
2797                Ref::keyword("ALTER").to_matchable(),
2798                Sequence::new(vec![
2799                    Ref::keyword("ALGORITHM").to_matchable(),
2800                    Ref::new("EqualsSegment").to_matchable(),
2801                    one_of(vec![
2802                        Ref::keyword("UNDEFINED").to_matchable(),
2803                        Ref::keyword("MERGE").to_matchable(),
2804                        Ref::keyword("TEMPTABLE").to_matchable(),
2805                    ])
2806                    .to_matchable(),
2807                ])
2808                .config(|this| this.optional())
2809                .to_matchable(),
2810                Ref::new("DefinerSegment").optional().to_matchable(),
2811                Sequence::new(vec![
2812                    Ref::keyword("SQL").to_matchable(),
2813                    Ref::keyword("SECURITY").to_matchable(),
2814                    one_of(vec![
2815                        Ref::keyword("DEFINER").to_matchable(),
2816                        Ref::keyword("INVOKER").to_matchable(),
2817                    ])
2818                    .to_matchable(),
2819                ])
2820                .config(|this| this.optional())
2821                .to_matchable(),
2822                Ref::keyword("VIEW").to_matchable(),
2823                Ref::new("TableReferenceSegment").to_matchable(),
2824                Ref::new("BracketedColumnReferenceListGrammar")
2825                    .optional()
2826                    .to_matchable(),
2827                Ref::keyword("AS").to_matchable(),
2828                Ref::new("SelectStatementSegment").to_matchable(),
2829                Ref::new("WithCheckOptionSegment").optional().to_matchable(),
2830            ])
2831            .to_matchable()
2832        })
2833        .to_matchable()
2834        .into(),
2835    )]);
2836
2837    // CreateViewStatementSegment.
2838    mysql.replace_grammar(
2839        "CreateViewStatementSegment",
2840        Sequence::new(vec![
2841            Ref::keyword("CREATE").to_matchable(),
2842            Ref::new("OrReplaceGrammar").optional().to_matchable(),
2843            Sequence::new(vec![
2844                Ref::keyword("ALGORITHM").to_matchable(),
2845                Ref::new("EqualsSegment").to_matchable(),
2846                one_of(vec![
2847                    Ref::keyword("UNDEFINED").to_matchable(),
2848                    Ref::keyword("MERGE").to_matchable(),
2849                    Ref::keyword("TEMPTABLE").to_matchable(),
2850                ])
2851                .to_matchable(),
2852            ])
2853            .config(|this| this.optional())
2854            .to_matchable(),
2855            Ref::new("DefinerSegment").optional().to_matchable(),
2856            Sequence::new(vec![
2857                Ref::keyword("SQL").to_matchable(),
2858                Ref::keyword("SECURITY").to_matchable(),
2859                one_of(vec![
2860                    Ref::keyword("DEFINER").to_matchable(),
2861                    Ref::keyword("INVOKER").to_matchable(),
2862                ])
2863                .to_matchable(),
2864            ])
2865            .config(|this| this.optional())
2866            .to_matchable(),
2867            Ref::keyword("VIEW").to_matchable(),
2868            Ref::new("TableReferenceSegment").to_matchable(),
2869            Ref::new("BracketedColumnReferenceListGrammar")
2870                .optional()
2871                .to_matchable(),
2872            Ref::keyword("AS").to_matchable(),
2873            Ref::new("SelectStatementSegment").to_matchable(),
2874            Ref::new("WithCheckOptionSegment").optional().to_matchable(),
2875        ])
2876        .to_matchable(),
2877    );
2878
2879    // RenameTableStatementSegment.
2880    mysql.add([(
2881        "RenameTableStatementSegment".into(),
2882        NodeMatcher::new(SyntaxKind::RenameTableStatement, |_| {
2883            Sequence::new(vec![
2884                Ref::keyword("RENAME").to_matchable(),
2885                Ref::keyword("TABLE").to_matchable(),
2886                Delimited::new(vec![
2887                    Sequence::new(vec![
2888                        Ref::new("TableReferenceSegment").to_matchable(),
2889                        Ref::keyword("TO").to_matchable(),
2890                        Ref::new("TableReferenceSegment").to_matchable(),
2891                    ])
2892                    .to_matchable(),
2893                ])
2894                .to_matchable(),
2895            ])
2896            .to_matchable()
2897        })
2898        .to_matchable()
2899        .into(),
2900    )]);
2901
2902    // ResetMasterStatementSegment.
2903    mysql.add([(
2904        "ResetMasterStatementSegment".into(),
2905        NodeMatcher::new(SyntaxKind::ResetMasterStatement, |_| {
2906            Sequence::new(vec![
2907                Ref::keyword("RESET").to_matchable(),
2908                Ref::keyword("MASTER").to_matchable(),
2909                Sequence::new(vec![
2910                    Ref::keyword("TO").to_matchable(),
2911                    Ref::new("NumericLiteralSegment").to_matchable(),
2912                ])
2913                .config(|this| this.optional())
2914                .to_matchable(),
2915            ])
2916            .to_matchable()
2917        })
2918        .to_matchable()
2919        .into(),
2920    )]);
2921
2922    // PurgeBinaryLogsStatementSegment.
2923    mysql.add([(
2924        "PurgeBinaryLogsStatementSegment".into(),
2925        NodeMatcher::new(SyntaxKind::PurgeBinaryLogsStatement, |_| {
2926            Sequence::new(vec![
2927                Ref::keyword("PURGE").to_matchable(),
2928                one_of(vec![
2929                    Ref::keyword("BINARY").to_matchable(),
2930                    Ref::keyword("MASTER").to_matchable(),
2931                ])
2932                .to_matchable(),
2933                Ref::keyword("LOGS").to_matchable(),
2934                one_of(vec![
2935                    Sequence::new(vec![
2936                        Ref::keyword("TO").to_matchable(),
2937                        Ref::new("QuotedLiteralSegment").to_matchable(),
2938                    ])
2939                    .to_matchable(),
2940                    Sequence::new(vec![
2941                        Ref::keyword("BEFORE").to_matchable(),
2942                        Ref::new("DateTimeLiteralGrammar").to_matchable(),
2943                    ])
2944                    .to_matchable(),
2945                ])
2946                .to_matchable(),
2947            ])
2948            .to_matchable()
2949        })
2950        .to_matchable()
2951        .into(),
2952    )]);
2953
2954    // HelpStatementSegment.
2955    mysql.add([(
2956        "HelpStatementSegment".into(),
2957        NodeMatcher::new(SyntaxKind::HelpStatement, |_| {
2958            Sequence::new(vec![
2959                Ref::keyword("HELP").to_matchable(),
2960                Ref::new("QuotedLiteralSegment").to_matchable(),
2961            ])
2962            .to_matchable()
2963        })
2964        .to_matchable()
2965        .into(),
2966    )]);
2967
2968    // CheckTableStatementSegment.
2969    mysql.add([(
2970        "CheckTableStatementSegment".into(),
2971        NodeMatcher::new(SyntaxKind::CheckTableStatement, |_| {
2972            Sequence::new(vec![
2973                Ref::keyword("CHECK").to_matchable(),
2974                Ref::keyword("TABLE").to_matchable(),
2975                Delimited::new(vec![Ref::new("TableReferenceSegment").to_matchable()])
2976                    .to_matchable(),
2977                AnyNumberOf::new(vec![
2978                    Sequence::new(vec![
2979                        Ref::keyword("FOR").to_matchable(),
2980                        Ref::keyword("UPGRADE").to_matchable(),
2981                    ])
2982                    .to_matchable(),
2983                    Ref::keyword("QUICK").to_matchable(),
2984                    Ref::keyword("FAST").to_matchable(),
2985                    Ref::keyword("MEDIUM").to_matchable(),
2986                    Ref::keyword("EXTENDED").to_matchable(),
2987                    Ref::keyword("CHANGED").to_matchable(),
2988                ])
2989                .config(|this| this.min_times = 1)
2990                .to_matchable(),
2991            ])
2992            .to_matchable()
2993        })
2994        .to_matchable()
2995        .into(),
2996    )]);
2997
2998    // ChecksumTableStatementSegment.
2999    mysql.add([(
3000        "ChecksumTableStatementSegment".into(),
3001        NodeMatcher::new(SyntaxKind::ChecksumTableStatement, |_| {
3002            Sequence::new(vec![
3003                Ref::keyword("CHECKSUM").to_matchable(),
3004                Ref::keyword("TABLE").to_matchable(),
3005                Delimited::new(vec![Ref::new("TableReferenceSegment").to_matchable()])
3006                    .to_matchable(),
3007                one_of(vec![
3008                    Ref::keyword("QUICK").to_matchable(),
3009                    Ref::keyword("EXTENDED").to_matchable(),
3010                ])
3011                .to_matchable(),
3012            ])
3013            .to_matchable()
3014        })
3015        .to_matchable()
3016        .into(),
3017    )]);
3018
3019    // AnalyzeTableStatementSegment.
3020    mysql.add([(
3021        "AnalyzeTableStatementSegment".into(),
3022        NodeMatcher::new(SyntaxKind::AnalyzeTableStatement, |_| {
3023            Sequence::new(vec![
3024                Ref::keyword("ANALYZE").to_matchable(),
3025                one_of(vec![
3026                    Ref::keyword("NO_WRITE_TO_BINLOG").to_matchable(),
3027                    Ref::keyword("LOCAL").to_matchable(),
3028                ])
3029                .config(|this| this.optional())
3030                .to_matchable(),
3031                Ref::keyword("TABLE").to_matchable(),
3032                one_of(vec![
3033                    Delimited::new(vec![Ref::new("TableReferenceSegment").to_matchable()])
3034                        .to_matchable(),
3035                    Sequence::new(vec![
3036                        Ref::new("TableReferenceSegment").to_matchable(),
3037                        Ref::keyword("UPDATE").to_matchable(),
3038                        Ref::keyword("HISTOGRAM").to_matchable(),
3039                        Ref::keyword("ON").to_matchable(),
3040                        Delimited::new(vec![Ref::new("ColumnReferenceSegment").to_matchable()])
3041                            .to_matchable(),
3042                        Sequence::new(vec![
3043                            Ref::keyword("WITH").to_matchable(),
3044                            Ref::new("NumericLiteralSegment").to_matchable(),
3045                            Ref::keyword("BUCKETS").to_matchable(),
3046                        ])
3047                        .config(|this| this.optional())
3048                        .to_matchable(),
3049                    ])
3050                    .to_matchable(),
3051                    Sequence::new(vec![
3052                        Ref::new("TableReferenceSegment").to_matchable(),
3053                        Ref::keyword("DROP").to_matchable(),
3054                        Ref::keyword("HISTOGRAM").to_matchable(),
3055                        Ref::keyword("ON").to_matchable(),
3056                        Delimited::new(vec![Ref::new("ColumnReferenceSegment").to_matchable()])
3057                            .to_matchable(),
3058                    ])
3059                    .to_matchable(),
3060                ])
3061                .to_matchable(),
3062            ])
3063            .to_matchable()
3064        })
3065        .to_matchable()
3066        .into(),
3067    )]);
3068
3069    // RepairTableStatementSegment.
3070    mysql.add([(
3071        "RepairTableStatementSegment".into(),
3072        NodeMatcher::new(SyntaxKind::RepairTableStatement, |_| {
3073            Sequence::new(vec![
3074                Ref::keyword("REPAIR").to_matchable(),
3075                one_of(vec![
3076                    Ref::keyword("NO_WRITE_TO_BINLOG").to_matchable(),
3077                    Ref::keyword("LOCAL").to_matchable(),
3078                ])
3079                .config(|this| this.optional())
3080                .to_matchable(),
3081                Ref::keyword("TABLE").to_matchable(),
3082                Delimited::new(vec![Ref::new("TableReferenceSegment").to_matchable()])
3083                    .to_matchable(),
3084                AnyNumberOf::new(vec![
3085                    Ref::keyword("QUICK").to_matchable(),
3086                    Ref::keyword("EXTENDED").to_matchable(),
3087                    Ref::keyword("USE_FRM").to_matchable(),
3088                ])
3089                .to_matchable(),
3090            ])
3091            .to_matchable()
3092        })
3093        .to_matchable()
3094        .into(),
3095    )]);
3096
3097    // OptimizeTableStatementSegment.
3098    mysql.add([(
3099        "OptimizeTableStatementSegment".into(),
3100        NodeMatcher::new(SyntaxKind::OptimizeTableStatement, |_| {
3101            Sequence::new(vec![
3102                Ref::keyword("OPTIMIZE").to_matchable(),
3103                one_of(vec![
3104                    Ref::keyword("NO_WRITE_TO_BINLOG").to_matchable(),
3105                    Ref::keyword("LOCAL").to_matchable(),
3106                ])
3107                .config(|this| this.optional())
3108                .to_matchable(),
3109                Ref::keyword("TABLE").to_matchable(),
3110                Delimited::new(vec![Ref::new("TableReferenceSegment").to_matchable()])
3111                    .to_matchable(),
3112            ])
3113            .to_matchable()
3114        })
3115        .to_matchable()
3116        .into(),
3117    )]);
3118
3119    // UpdateStatementSegment.
3120    mysql.replace_grammar(
3121        "UpdateStatementSegment",
3122        Sequence::new(vec![
3123            Ref::keyword("UPDATE").to_matchable(),
3124            Ref::keyword("LOW_PRIORITY").optional().to_matchable(),
3125            Ref::keyword("IGNORE").optional().to_matchable(),
3126            Delimited::new(vec![
3127                Ref::new("TableReferenceSegment").to_matchable(),
3128                Ref::new("FromExpressionSegment").to_matchable(),
3129            ])
3130            .to_matchable(),
3131            Ref::new("SetClauseListSegment").to_matchable(),
3132            Ref::new("WhereClauseSegment").optional().to_matchable(),
3133            Ref::new("OrderByClauseSegment").optional().to_matchable(),
3134            Ref::new("LimitClauseSegment").optional().to_matchable(),
3135        ])
3136        .to_matchable(),
3137    );
3138
3139    // FlushStatementSegment.
3140    mysql.add([(
3141        "FlushStatementSegment".into(),
3142        NodeMatcher::new(SyntaxKind::FlushStatement, |_| {
3143            Sequence::new(vec![
3144                Ref::keyword("FLUSH").to_matchable(),
3145                one_of(vec![
3146                    Ref::keyword("NO_WRITE_TO_BINLOG").to_matchable(),
3147                    Ref::keyword("LOCAL").to_matchable(),
3148                ])
3149                .config(|this| this.optional())
3150                .to_matchable(),
3151                one_of(vec![
3152                    Delimited::new(vec![
3153                        Sequence::new(vec![
3154                            Ref::keyword("BINARY").to_matchable(),
3155                            Ref::keyword("LOGS").to_matchable(),
3156                        ])
3157                        .to_matchable(),
3158                        Sequence::new(vec![
3159                            Ref::keyword("ENGINE").to_matchable(),
3160                            Ref::keyword("LOGS").to_matchable(),
3161                        ])
3162                        .to_matchable(),
3163                        Sequence::new(vec![
3164                            Ref::keyword("ERROR").to_matchable(),
3165                            Ref::keyword("LOGS").to_matchable(),
3166                        ])
3167                        .to_matchable(),
3168                        Sequence::new(vec![
3169                            Ref::keyword("GENERAL").to_matchable(),
3170                            Ref::keyword("LOGS").to_matchable(),
3171                        ])
3172                        .to_matchable(),
3173                        Ref::keyword("HOSTS").to_matchable(),
3174                        Ref::keyword("LOGS").to_matchable(),
3175                        Ref::keyword("PRIVILEGES").to_matchable(),
3176                        Ref::keyword("OPTIMIZER_COSTS").to_matchable(),
3177                        Sequence::new(vec![
3178                            Ref::keyword("RELAY").to_matchable(),
3179                            Ref::keyword("LOGS").to_matchable(),
3180                            Sequence::new(vec![
3181                                Ref::keyword("FOR").to_matchable(),
3182                                Ref::keyword("CHANNEL").to_matchable(),
3183                                Ref::new("ObjectReferenceSegment").to_matchable(),
3184                            ])
3185                            .config(|this| this.optional())
3186                            .to_matchable(),
3187                        ])
3188                        .to_matchable(),
3189                        Sequence::new(vec![
3190                            Ref::keyword("SLOW").to_matchable(),
3191                            Ref::keyword("LOGS").to_matchable(),
3192                        ])
3193                        .to_matchable(),
3194                        Ref::keyword("STATUS").to_matchable(),
3195                        Ref::keyword("USER_RESOURCES").to_matchable(),
3196                    ])
3197                    .to_matchable(),
3198                    Sequence::new(vec![
3199                        Ref::keyword("TABLES").to_matchable(),
3200                        Delimited::new(vec![Ref::new("TableReferenceSegment").to_matchable()])
3201                            .config(|this| {
3202                                this.optional();
3203                                this.base.terminators = vec![Ref::keyword("WITH").to_matchable()];
3204                            })
3205                            .to_matchable(),
3206                        Sequence::new(vec![
3207                            Ref::keyword("WITH").to_matchable(),
3208                            Ref::keyword("READ").to_matchable(),
3209                            Ref::keyword("LOCK").to_matchable(),
3210                        ])
3211                        .config(|this| this.optional())
3212                        .to_matchable(),
3213                    ])
3214                    .to_matchable(),
3215                    Sequence::new(vec![
3216                        Ref::keyword("TABLES").to_matchable(),
3217                        Delimited::new(vec![Ref::new("TableReferenceSegment").to_matchable()])
3218                            .config(|this| {
3219                                this.base.terminators = vec![Ref::keyword("FOR").to_matchable()];
3220                            })
3221                            .to_matchable(),
3222                        Sequence::new(vec![
3223                            Ref::keyword("FOR").to_matchable(),
3224                            Ref::keyword("EXPORT").to_matchable(),
3225                        ])
3226                        .config(|this| this.optional())
3227                        .to_matchable(),
3228                    ])
3229                    .to_matchable(),
3230                ])
3231                .to_matchable(),
3232            ])
3233            .to_matchable()
3234        })
3235        .to_matchable()
3236        .into(),
3237    )]);
3238
3239    // LoadDataSegment.
3240    mysql.add([(
3241        "LoadDataSegment".into(),
3242        NodeMatcher::new(SyntaxKind::LoadDataStatement, |_| {
3243            Sequence::new(vec![
3244                Ref::keyword("LOAD").to_matchable(),
3245                Ref::keyword("DATA").to_matchable(),
3246                one_of(vec![
3247                    Ref::keyword("LOW_PRIORITY").to_matchable(),
3248                    Ref::keyword("CONCURRENT").to_matchable(),
3249                ])
3250                .config(|this| this.optional())
3251                .to_matchable(),
3252                Ref::keyword("LOCAL").optional().to_matchable(),
3253                Ref::keyword("INFILE").to_matchable(),
3254                Ref::new("QuotedLiteralSegment").to_matchable(),
3255                one_of(vec![
3256                    Ref::keyword("REPLACE").to_matchable(),
3257                    Ref::keyword("IGNORE").to_matchable(),
3258                ])
3259                .config(|this| this.optional())
3260                .to_matchable(),
3261                Ref::keyword("INTO").to_matchable(),
3262                Ref::keyword("TABLE").to_matchable(),
3263                Ref::new("TableReferenceSegment").to_matchable(),
3264                Ref::new("SelectPartitionClauseSegment")
3265                    .optional()
3266                    .to_matchable(),
3267                Sequence::new(vec![
3268                    Ref::keyword("CHARACTER").to_matchable(),
3269                    Ref::keyword("SET").to_matchable(),
3270                    Ref::new("NakedIdentifierSegment").to_matchable(),
3271                ])
3272                .config(|this| this.optional())
3273                .to_matchable(),
3274                Sequence::new(vec![
3275                    one_of(vec![
3276                        Ref::keyword("FIELDS").to_matchable(),
3277                        Ref::keyword("COLUMNS").to_matchable(),
3278                    ])
3279                    .to_matchable(),
3280                    Sequence::new(vec![
3281                        Ref::keyword("TERMINATED").to_matchable(),
3282                        Ref::keyword("BY").to_matchable(),
3283                        Ref::new("QuotedLiteralSegment").to_matchable(),
3284                    ])
3285                    .config(|this| this.optional())
3286                    .to_matchable(),
3287                    Sequence::new(vec![
3288                        Ref::keyword("OPTIONALLY").optional().to_matchable(),
3289                        Ref::keyword("ENCLOSED").to_matchable(),
3290                        Ref::keyword("BY").to_matchable(),
3291                        Ref::new("QuotedLiteralSegment").to_matchable(),
3292                    ])
3293                    .config(|this| this.optional())
3294                    .to_matchable(),
3295                    Sequence::new(vec![
3296                        Ref::keyword("ESCAPED").to_matchable(),
3297                        Ref::keyword("BY").to_matchable(),
3298                        Ref::new("QuotedLiteralSegment").to_matchable(),
3299                    ])
3300                    .config(|this| this.optional())
3301                    .to_matchable(),
3302                ])
3303                .config(|this| this.optional())
3304                .to_matchable(),
3305                Sequence::new(vec![
3306                    Ref::keyword("LINES").to_matchable(),
3307                    Sequence::new(vec![
3308                        Ref::keyword("STARTING").to_matchable(),
3309                        Ref::keyword("BY").to_matchable(),
3310                        Ref::new("QuotedLiteralSegment").to_matchable(),
3311                    ])
3312                    .config(|this| this.optional())
3313                    .to_matchable(),
3314                    Sequence::new(vec![
3315                        Ref::keyword("TERMINATED").to_matchable(),
3316                        Ref::keyword("BY").to_matchable(),
3317                        Ref::new("QuotedLiteralSegment").to_matchable(),
3318                    ])
3319                    .config(|this| this.optional())
3320                    .to_matchable(),
3321                ])
3322                .config(|this| this.optional())
3323                .to_matchable(),
3324                Sequence::new(vec![
3325                    Ref::keyword("IGNORE").to_matchable(),
3326                    Ref::new("NumericLiteralSegment").to_matchable(),
3327                    one_of(vec![
3328                        Ref::keyword("LINES").to_matchable(),
3329                        Ref::keyword("ROWS").to_matchable(),
3330                    ])
3331                    .to_matchable(),
3332                ])
3333                .config(|this| this.optional())
3334                .to_matchable(),
3335                Sequence::new(vec![
3336                    Bracketed::new(vec![
3337                        Delimited::new(vec![Ref::new("ColumnReferenceSegment").to_matchable()])
3338                            .to_matchable(),
3339                    ])
3340                    .to_matchable(),
3341                ])
3342                .config(|this| this.optional())
3343                .to_matchable(),
3344                Sequence::new(vec![
3345                    Ref::keyword("SET").to_matchable(),
3346                    Ref::new("Expression_B_Grammar").to_matchable(),
3347                ])
3348                .config(|this| this.optional())
3349                .to_matchable(),
3350            ])
3351            .to_matchable()
3352        })
3353        .to_matchable()
3354        .into(),
3355    )]);
3356
3357    // ReplaceSegment.
3358    mysql.add([(
3359        "ReplaceSegment".into(),
3360        NodeMatcher::new(SyntaxKind::ReplaceStatement, |_| {
3361            Sequence::new(vec![
3362                Ref::keyword("REPLACE").to_matchable(),
3363                one_of(vec![
3364                    Ref::keyword("LOW_PRIORITY").to_matchable(),
3365                    Ref::keyword("DELAYED").to_matchable(),
3366                ])
3367                .config(|this| this.optional())
3368                .to_matchable(),
3369                Ref::keyword("INTO").optional().to_matchable(),
3370                Ref::new("TableReferenceSegment").to_matchable(),
3371                Ref::new("SelectPartitionClauseSegment")
3372                    .optional()
3373                    .to_matchable(),
3374                one_of(vec![
3375                    Sequence::new(vec![
3376                        Ref::new("BracketedColumnReferenceListGrammar")
3377                            .optional()
3378                            .to_matchable(),
3379                        Ref::new("ValuesClauseSegment").to_matchable(),
3380                    ])
3381                    .to_matchable(),
3382                    Ref::new("SetClauseListSegment").to_matchable(),
3383                    Sequence::new(vec![
3384                        Ref::new("BracketedColumnReferenceListGrammar")
3385                            .optional()
3386                            .to_matchable(),
3387                        one_of(vec![
3388                            Ref::new("SelectableGrammar").to_matchable(),
3389                            Sequence::new(vec![
3390                                Ref::keyword("TABLE").to_matchable(),
3391                                Ref::new("TableReferenceSegment").to_matchable(),
3392                            ])
3393                            .to_matchable(),
3394                        ])
3395                        .to_matchable(),
3396                    ])
3397                    .to_matchable(),
3398                ])
3399                .to_matchable(),
3400            ])
3401            .to_matchable()
3402        })
3403        .to_matchable()
3404        .into(),
3405    )]);
3406
3407    // CreateTriggerStatementSegment.
3408    mysql.replace_grammar(
3409        "CreateTriggerStatementSegment",
3410        Sequence::new(vec![
3411            Ref::keyword("CREATE").to_matchable(),
3412            Ref::new("DefinerSegment").optional().to_matchable(),
3413            Ref::keyword("TRIGGER").to_matchable(),
3414            Ref::new("IfNotExistsGrammar").optional().to_matchable(),
3415            Ref::new("TriggerReferenceSegment").to_matchable(),
3416            one_of(vec![
3417                Ref::keyword("BEFORE").to_matchable(),
3418                Ref::keyword("AFTER").to_matchable(),
3419            ])
3420            .to_matchable(),
3421            one_of(vec![
3422                Ref::keyword("INSERT").to_matchable(),
3423                Ref::keyword("UPDATE").to_matchable(),
3424                Ref::keyword("DELETE").to_matchable(),
3425            ])
3426            .to_matchable(),
3427            Ref::keyword("ON").to_matchable(),
3428            Ref::new("TableReferenceSegment").to_matchable(),
3429            Sequence::new(vec![
3430                Ref::keyword("FOR").to_matchable(),
3431                Ref::keyword("EACH").to_matchable(),
3432                Ref::keyword("ROW").to_matchable(),
3433            ])
3434            .to_matchable(),
3435            Sequence::new(vec![
3436                one_of(vec![
3437                    Ref::keyword("FOLLOWS").to_matchable(),
3438                    Ref::keyword("PRECEDES").to_matchable(),
3439                ])
3440                .to_matchable(),
3441                Ref::new("SingleIdentifierGrammar").to_matchable(),
3442            ])
3443            .config(|this| this.optional())
3444            .to_matchable(),
3445            one_of(vec![
3446                Ref::new("StatementSegment").to_matchable(),
3447                Sequence::new(vec![
3448                    Ref::keyword("BEGIN").to_matchable(),
3449                    Ref::new("StatementSegment").to_matchable(),
3450                    Ref::keyword("END").to_matchable(),
3451                ])
3452                .to_matchable(),
3453            ])
3454            .to_matchable(),
3455        ])
3456        .to_matchable(),
3457    );
3458
3459    // DropTriggerStatementSegment.
3460    mysql.replace_grammar(
3461        "DropTriggerStatementSegment",
3462        Sequence::new(vec![
3463            Ref::keyword("DROP").to_matchable(),
3464            Ref::keyword("TRIGGER").to_matchable(),
3465            Ref::new("IfExistsGrammar").optional().to_matchable(),
3466            Ref::new("TriggerReferenceSegment").to_matchable(),
3467        ])
3468        .to_matchable(),
3469    );
3470
3471    // ColumnReferenceSegment - add JSON path operators.
3472    // Base is a delimited list of identifiers (ANSI), plus optional JSON path.
3473    let base_col_ref = Delimited::new(vec![Ref::new("SingleIdentifierGrammar").to_matchable()])
3474        .config(|this| this.delimiter(Ref::new("ObjectReferenceDelimiterGrammar")))
3475        .to_matchable();
3476    mysql.replace_grammar(
3477        "ColumnReferenceSegment",
3478        one_of(vec![
3479            Sequence::new(vec![
3480                base_col_ref.clone(),
3481                one_of(vec![
3482                    Ref::new("ColumnPathOperatorSegment").to_matchable(),
3483                    Ref::new("InlinePathOperatorSegment").to_matchable(),
3484                ])
3485                .to_matchable(),
3486                one_of(vec![
3487                    Ref::new("DoubleQuotedJSONPath").to_matchable(),
3488                    Ref::new("SingleQuotedJSONPath").to_matchable(),
3489                ])
3490                .to_matchable(),
3491            ])
3492            .to_matchable(),
3493            base_col_ref,
3494        ])
3495        .to_matchable(),
3496    );
3497
3498    // CreateDatabaseStatementSegment.
3499    mysql.replace_grammar(
3500        "CreateDatabaseStatementSegment",
3501        Sequence::new(vec![
3502            Ref::keyword("CREATE").to_matchable(),
3503            one_of(vec![
3504                Ref::keyword("DATABASE").to_matchable(),
3505                Ref::keyword("SCHEMA").to_matchable(),
3506            ])
3507            .to_matchable(),
3508            Ref::new("IfNotExistsGrammar").optional().to_matchable(),
3509            Ref::new("DatabaseReferenceSegment").to_matchable(),
3510            AnyNumberOf::new(vec![Ref::new("CreateOptionSegment").to_matchable()]).to_matchable(),
3511        ])
3512        .to_matchable(),
3513    );
3514
3515    // CreateOptionSegment.
3516    mysql.add([(
3517        "CreateOptionSegment".into(),
3518        NodeMatcher::new(SyntaxKind::CreateOptionSegment, |_| {
3519            Sequence::new(vec![
3520                Ref::keyword("DEFAULT").optional().to_matchable(),
3521                one_of(vec![
3522                    Sequence::new(vec![
3523                        Ref::keyword("CHARACTER").to_matchable(),
3524                        Ref::keyword("SET").to_matchable(),
3525                        Ref::new("EqualsSegment").optional().to_matchable(),
3526                        Ref::new("NakedIdentifierSegment").to_matchable(),
3527                    ])
3528                    .to_matchable(),
3529                    Sequence::new(vec![
3530                        Ref::keyword("COLLATE").to_matchable(),
3531                        Ref::new("EqualsSegment").optional().to_matchable(),
3532                        Ref::new("NakedIdentifierSegment").to_matchable(),
3533                    ])
3534                    .to_matchable(),
3535                    Sequence::new(vec![
3536                        Ref::keyword("ENCRYPTION").to_matchable(),
3537                        Ref::new("EqualsSegment").optional().to_matchable(),
3538                        Ref::new("QuotedLiteralSegment").to_matchable(),
3539                    ])
3540                    .to_matchable(),
3541                ])
3542                .to_matchable(),
3543            ])
3544            .to_matchable()
3545        })
3546        .to_matchable()
3547        .into(),
3548    )]);
3549
3550    // AlterDatabaseStatementSegment.
3551    mysql.add([(
3552        "AlterDatabaseStatementSegment".into(),
3553        NodeMatcher::new(SyntaxKind::AlterDatabaseStatement, |_| {
3554            Sequence::new(vec![
3555                Ref::keyword("ALTER").to_matchable(),
3556                one_of(vec![
3557                    Ref::keyword("DATABASE").to_matchable(),
3558                    Ref::keyword("SCHEMA").to_matchable(),
3559                ])
3560                .to_matchable(),
3561                Ref::new("DatabaseReferenceSegment")
3562                    .optional()
3563                    .to_matchable(),
3564                AnyNumberOf::new(vec![Ref::new("AlterOptionSegment").to_matchable()])
3565                    .to_matchable(),
3566            ])
3567            .to_matchable()
3568        })
3569        .to_matchable()
3570        .into(),
3571    )]);
3572
3573    // AlterOptionSegment.
3574    mysql.add([(
3575        "AlterOptionSegment".into(),
3576        NodeMatcher::new(SyntaxKind::AlterOptionSegment, |_| {
3577            one_of(vec![
3578                Sequence::new(vec![
3579                    Ref::keyword("DEFAULT").optional().to_matchable(),
3580                    Ref::keyword("CHARACTER").to_matchable(),
3581                    Ref::keyword("SET").to_matchable(),
3582                    Ref::new("EqualsSegment").optional().to_matchable(),
3583                    Ref::new("NakedIdentifierSegment").to_matchable(),
3584                ])
3585                .to_matchable(),
3586                Sequence::new(vec![
3587                    Ref::keyword("DEFAULT").optional().to_matchable(),
3588                    Ref::keyword("COLLATE").to_matchable(),
3589                    Ref::new("EqualsSegment").optional().to_matchable(),
3590                    Ref::new("NakedIdentifierSegment").to_matchable(),
3591                ])
3592                .to_matchable(),
3593                Sequence::new(vec![
3594                    Ref::keyword("DEFAULT").optional().to_matchable(),
3595                    Ref::keyword("ENCRYPTION").to_matchable(),
3596                    Ref::new("EqualsSegment").optional().to_matchable(),
3597                    Ref::new("QuotedLiteralSegment").to_matchable(),
3598                ])
3599                .to_matchable(),
3600                Sequence::new(vec![
3601                    Ref::keyword("READ").to_matchable(),
3602                    Ref::keyword("ONLY").to_matchable(),
3603                    Ref::new("EqualsSegment").optional().to_matchable(),
3604                    one_of(vec![
3605                        Ref::keyword("DEFAULT").to_matchable(),
3606                        Ref::new("NumericLiteralSegment").to_matchable(),
3607                    ])
3608                    .to_matchable(),
3609                ])
3610                .to_matchable(),
3611            ])
3612            .to_matchable()
3613        })
3614        .to_matchable()
3615        .into(),
3616    )]);
3617
3618    // GrantStatementSegment - MySQL GRANT with additional features.
3619    mysql.replace_grammar(
3620        "AccessStatementSegment",
3621        one_of(vec![
3622            // GRANT
3623            Sequence::new(vec![
3624                Ref::keyword("GRANT").to_matchable(),
3625                Delimited::new(vec![
3626                    one_of(vec![
3627                        Sequence::new(vec![
3628                            Ref::keyword("ALL").to_matchable(),
3629                            Ref::keyword("PRIVILEGES").optional().to_matchable(),
3630                        ])
3631                        .to_matchable(),
3632                        Sequence::new(vec![
3633                            one_of(vec![
3634                                Ref::keyword("SELECT").to_matchable(),
3635                                Ref::keyword("INSERT").to_matchable(),
3636                                Ref::keyword("UPDATE").to_matchable(),
3637                                Ref::keyword("DELETE").to_matchable(),
3638                                Ref::keyword("CREATE").to_matchable(),
3639                                Ref::keyword("DROP").to_matchable(),
3640                                Ref::keyword("ALTER").to_matchable(),
3641                                Ref::keyword("INDEX").to_matchable(),
3642                                Ref::keyword("EXECUTE").to_matchable(),
3643                                Ref::keyword("REFERENCES").to_matchable(),
3644                                Ref::keyword("RELOAD").to_matchable(),
3645                                Ref::keyword("PROCESS").to_matchable(),
3646                                Ref::keyword("SUPER").to_matchable(),
3647                                Ref::keyword("USAGE").to_matchable(),
3648                                Ref::keyword("TRIGGER").to_matchable(),
3649                                Sequence::new(vec![
3650                                    Ref::keyword("CREATE").to_matchable(),
3651                                    Ref::keyword("VIEW").to_matchable(),
3652                                ])
3653                                .to_matchable(),
3654                                Sequence::new(vec![
3655                                    Ref::keyword("SHOW").to_matchable(),
3656                                    Ref::keyword("VIEW").to_matchable(),
3657                                ])
3658                                .to_matchable(),
3659                            ])
3660                            .to_matchable(),
3661                            Bracketed::new(vec![
3662                                Delimited::new(vec![
3663                                    Ref::new("ColumnReferenceSegment").to_matchable(),
3664                                ])
3665                                .to_matchable(),
3666                            ])
3667                            .config(|this| this.optional())
3668                            .to_matchable(),
3669                        ])
3670                        .to_matchable(),
3671                    ])
3672                    .to_matchable(),
3673                ])
3674                .to_matchable(),
3675                Ref::keyword("ON").to_matchable(),
3676                one_of(vec![
3677                    Sequence::new(vec![
3678                        one_of(vec![
3679                            Ref::keyword("TABLE").to_matchable(),
3680                            Ref::keyword("FUNCTION").to_matchable(),
3681                            Ref::keyword("PROCEDURE").to_matchable(),
3682                        ])
3683                        .config(|this| this.optional())
3684                        .to_matchable(),
3685                        Ref::new("ObjectReferenceSegment").to_matchable(),
3686                    ])
3687                    .to_matchable(),
3688                ])
3689                .to_matchable(),
3690                Ref::keyword("TO").to_matchable(),
3691                Delimited::new(vec![Ref::new("RoleReferenceSegment").to_matchable()])
3692                    .to_matchable(),
3693                Sequence::new(vec![
3694                    Ref::keyword("WITH").to_matchable(),
3695                    Ref::keyword("GRANT").to_matchable(),
3696                    Ref::keyword("OPTION").to_matchable(),
3697                ])
3698                .config(|this| this.optional())
3699                .to_matchable(),
3700            ])
3701            .to_matchable(),
3702            // REVOKE
3703            Sequence::new(vec![
3704                Ref::keyword("REVOKE").to_matchable(),
3705                Delimited::new(vec![
3706                    one_of(vec![
3707                        Sequence::new(vec![
3708                            Ref::keyword("ALL").to_matchable(),
3709                            Ref::keyword("PRIVILEGES").optional().to_matchable(),
3710                        ])
3711                        .to_matchable(),
3712                        Ref::keyword("SELECT").to_matchable(),
3713                        Ref::keyword("INSERT").to_matchable(),
3714                        Ref::keyword("UPDATE").to_matchable(),
3715                        Ref::keyword("DELETE").to_matchable(),
3716                        Ref::keyword("USAGE").to_matchable(),
3717                    ])
3718                    .to_matchable(),
3719                ])
3720                .to_matchable(),
3721                Ref::keyword("ON").to_matchable(),
3722                one_of(vec![
3723                    Sequence::new(vec![
3724                        one_of(vec![
3725                            Ref::keyword("TABLE").to_matchable(),
3726                            Ref::keyword("FUNCTION").to_matchable(),
3727                            Ref::keyword("PROCEDURE").to_matchable(),
3728                        ])
3729                        .config(|this| this.optional())
3730                        .to_matchable(),
3731                        Ref::new("ObjectReferenceSegment").to_matchable(),
3732                    ])
3733                    .to_matchable(),
3734                ])
3735                .to_matchable(),
3736                Ref::keyword("FROM").to_matchable(),
3737                Delimited::new(vec![Ref::new("RoleReferenceSegment").to_matchable()])
3738                    .to_matchable(),
3739            ])
3740            .to_matchable(),
3741        ])
3742        .to_matchable(),
3743    );
3744
3745    // ValuesStatementSegment - MySQL VALUES statement.
3746    mysql.add([(
3747        "ValuesStatementSegment".into(),
3748        NodeMatcher::new(SyntaxKind::ValuesClause, |_| {
3749            Sequence::new(vec![
3750                Ref::keyword("VALUES").to_matchable(),
3751                Delimited::new(vec![
3752                    Sequence::new(vec![
3753                        Ref::keyword("ROW").to_matchable(),
3754                        Bracketed::new(vec![
3755                            Delimited::new(vec![Ref::new("ExpressionSegment").to_matchable()])
3756                                .to_matchable(),
3757                        ])
3758                        .to_matchable(),
3759                    ])
3760                    .to_matchable(),
3761                ])
3762                .to_matchable(),
3763                Sequence::new(vec![
3764                    Ref::keyword("ORDER").to_matchable(),
3765                    Ref::keyword("BY").to_matchable(),
3766                    Ref::new("NumericLiteralSegment").to_matchable(),
3767                ])
3768                .config(|this| this.optional())
3769                .to_matchable(),
3770                Sequence::new(vec![
3771                    Ref::keyword("LIMIT").to_matchable(),
3772                    Ref::new("NumericLiteralSegment").to_matchable(),
3773                ])
3774                .config(|this| this.optional())
3775                .to_matchable(),
3776            ])
3777            .to_matchable()
3778        })
3779        .to_matchable()
3780        .into(),
3781    )]);
3782
3783    // ============================================================
3784    // Select clause/statement overrides
3785    // ============================================================
3786
3787    // Add INTO to SelectClauseTerminatorGrammar so SELECT clause stops before INTO.
3788    let select_clause_term = mysql.grammar("SelectClauseTerminatorGrammar");
3789    mysql.replace_grammar(
3790        "SelectClauseTerminatorGrammar",
3791        select_clause_term.copy(
3792            Some(vec![Ref::keyword("INTO").to_matchable()]),
3793            None,
3794            None,
3795            None,
3796            vec![],
3797            false,
3798        ),
3799    );
3800
3801    // UnorderedSelectStatementSegment - add INTO, FOR, index hint, partition clauses.
3802    mysql.replace_grammar(
3803        "UnorderedSelectStatementSegment",
3804        Sequence::new(vec![
3805            Ref::new("SelectClauseSegment").to_matchable(),
3806            MetaSegment::dedent().to_matchable(),
3807            Ref::new("IntoClauseSegment").optional().to_matchable(),
3808            Ref::new("FromClauseSegment").optional().to_matchable(),
3809            Ref::new("SelectPartitionClauseSegment")
3810                .optional()
3811                .to_matchable(),
3812            Ref::new("IndexHintClauseSegment").optional().to_matchable(),
3813            Ref::new("WhereClauseSegment").optional().to_matchable(),
3814            Ref::new("GroupByClauseSegment").optional().to_matchable(),
3815            Ref::new("HavingClauseSegment").optional().to_matchable(),
3816            Ref::new("OverlapsClauseSegment").optional().to_matchable(),
3817            Ref::new("NamedWindowSegment").optional().to_matchable(),
3818            Ref::new("ForClauseSegment").optional().to_matchable(),
3819        ])
3820        .terminators(vec![
3821            Ref::new("SetOperatorSegment").to_matchable(),
3822            Ref::new("WithNoSchemaBindingClauseSegment").to_matchable(),
3823            Ref::new("WithDataClauseSegment").to_matchable(),
3824            Ref::new("OrderByClauseSegment").to_matchable(),
3825            Ref::new("LimitClauseSegment").to_matchable(),
3826            Ref::new("IntoClauseSegment").to_matchable(),
3827            Ref::new("ForClauseSegment").to_matchable(),
3828            Ref::new("IndexHintClauseSegment").to_matchable(),
3829            Ref::new("SelectPartitionClauseSegment").to_matchable(),
3830            Ref::new("UpsertClauseListSegment").to_matchable(),
3831        ])
3832        .config(|this| {
3833            this.parse_mode(ParseMode::GreedyOnceStarted);
3834        })
3835        .to_matchable(),
3836    );
3837
3838    // SelectStatementSegment - add ORDER BY, LIMIT, named window, INTO, FOR.
3839    mysql.replace_grammar(
3840        "SelectStatementSegment",
3841        Sequence::new(vec![
3842            Ref::new("SelectClauseSegment").to_matchable(),
3843            MetaSegment::dedent().to_matchable(),
3844            Ref::new("IntoClauseSegment").optional().to_matchable(),
3845            Ref::new("FromClauseSegment").optional().to_matchable(),
3846            Ref::new("SelectPartitionClauseSegment")
3847                .optional()
3848                .to_matchable(),
3849            Ref::new("IndexHintClauseSegment").optional().to_matchable(),
3850            Ref::new("WhereClauseSegment").optional().to_matchable(),
3851            Ref::new("GroupByClauseSegment").optional().to_matchable(),
3852            Ref::new("HavingClauseSegment").optional().to_matchable(),
3853            Ref::new("OverlapsClauseSegment").optional().to_matchable(),
3854            Ref::new("OrderByClauseSegment").optional().to_matchable(),
3855            Ref::new("LimitClauseSegment").optional().to_matchable(),
3856            Ref::new("NamedWindowSegment").optional().to_matchable(),
3857            Ref::new("IntoClauseSegment").optional().to_matchable(),
3858            Ref::new("ForClauseSegment").optional().to_matchable(),
3859        ])
3860        .terminators(vec![
3861            Ref::new("SetOperatorSegment").to_matchable(),
3862            Ref::new("WithNoSchemaBindingClauseSegment").to_matchable(),
3863            Ref::new("WithDataClauseSegment").to_matchable(),
3864            Ref::new("UpsertClauseListSegment").to_matchable(),
3865            Ref::new("WithCheckOptionSegment").to_matchable(),
3866        ])
3867        .config(|this| {
3868            this.parse_mode(ParseMode::GreedyOnceStarted);
3869        })
3870        .to_matchable(),
3871    );
3872
3873    // ============================================================
3874    // StatementSegment - override to add MySQL-specific statements
3875    // ============================================================
3876
3877    mysql.replace_grammar(
3878        "StatementSegment",
3879        ansi::statement_segment().copy(
3880            Some(vec![
3881                Ref::new("DelimiterStatement").to_matchable(),
3882                Ref::new("CreateProcedureStatementSegment").to_matchable(),
3883                Ref::new("DeclareStatement").to_matchable(),
3884                Ref::new("SetAssignmentStatementSegment").to_matchable(),
3885                Ref::new("IfExpressionStatement").to_matchable(),
3886                Ref::new("WhileStatementSegment").to_matchable(),
3887                Ref::new("IterateStatementSegment").to_matchable(),
3888                Ref::new("RepeatStatementSegment").to_matchable(),
3889                Ref::new("LoopStatementSegment").to_matchable(),
3890                Ref::new("CallStoredProcedureSegment").to_matchable(),
3891                Ref::new("PrepareSegment").to_matchable(),
3892                Ref::new("ExecuteSegment").to_matchable(),
3893                Ref::new("DeallocateSegment").to_matchable(),
3894                Ref::new("GetDiagnosticsSegment").to_matchable(),
3895                Ref::new("ResignalSegment").to_matchable(),
3896                Ref::new("CursorOpenCloseSegment").to_matchable(),
3897                Ref::new("CursorFetchSegment").to_matchable(),
3898                Ref::new("DropProcedureStatementSegment").to_matchable(),
3899                Ref::new("AlterTableStatementSegment").to_matchable(),
3900                Ref::new("AlterViewStatementSegment").to_matchable(),
3901                Ref::new("CreateViewStatementSegment").to_matchable(),
3902                Ref::new("RenameTableStatementSegment").to_matchable(),
3903                Ref::new("ResetMasterStatementSegment").to_matchable(),
3904                Ref::new("PurgeBinaryLogsStatementSegment").to_matchable(),
3905                Ref::new("HelpStatementSegment").to_matchable(),
3906                Ref::new("CheckTableStatementSegment").to_matchable(),
3907                Ref::new("ChecksumTableStatementSegment").to_matchable(),
3908                Ref::new("AnalyzeTableStatementSegment").to_matchable(),
3909                Ref::new("RepairTableStatementSegment").to_matchable(),
3910                Ref::new("OptimizeTableStatementSegment").to_matchable(),
3911                Ref::new("UpsertClauseListSegment").to_matchable(),
3912                Ref::new("InsertRowAliasSegment").to_matchable(),
3913                Ref::new("FlushStatementSegment").to_matchable(),
3914                Ref::new("LoadDataSegment").to_matchable(),
3915                Ref::new("ReplaceSegment").to_matchable(),
3916                Ref::new("AlterDatabaseStatementSegment").to_matchable(),
3917            ]),
3918            None,
3919            None,
3920            Some(vec![
3921                Ref::new("CreateSchemaStatementSegment").to_matchable(),
3922            ]),
3923            vec![],
3924            false,
3925        ),
3926    );
3927
3928    mysql
3929}