use itertools::Itertools;
use sqruff_lib_core::dialects::base::Dialect;
use sqruff_lib_core::dialects::init::DialectKind;
use sqruff_lib_core::dialects::syntax::SyntaxKind;
use sqruff_lib_core::helpers::{Config, ToMatchable};
use sqruff_lib_core::parser::grammar::anyof::{
    any_set_of, one_of, optionally_bracketed, AnyNumberOf,
};
use sqruff_lib_core::parser::grammar::base::{Anything, Ref};
use sqruff_lib_core::parser::grammar::delimited::Delimited;
use sqruff_lib_core::parser::grammar::sequence::{Bracketed, Sequence};
use sqruff_lib_core::parser::lexer::Matcher;
use sqruff_lib_core::parser::matchable::{Matchable, MatchableTrait};
use sqruff_lib_core::parser::node_matcher::NodeMatcher;
use sqruff_lib_core::parser::parsers::{RegexParser, StringParser, TypedParser};
use sqruff_lib_core::parser::segments::generator::SegmentGenerator;
use sqruff_lib_core::parser::segments::meta::MetaSegment;
use sqruff_lib_core::parser::types::ParseMode;
use sqruff_lib_core::vec_of_erased;

use super::ansi;
use super::postgres_keywords::POSTGRES_POSTGIS_DATATYPE_KEYWORDS;
use crate::postgres_keywords::{get_keywords, postgres_keywords};

pub fn dialect() -> Dialect {
    raw_dialect().config(|dialect| dialect.expand())
}

pub fn raw_dialect() -> Dialect {
    let mut postgres = ansi::raw_dialect();
    postgres.name = DialectKind::Postgres;

    postgres.insert_lexer_matchers(
        vec![Matcher::string("right_arrow", "=>", SyntaxKind::RightArrow)],
        "equals",
    );

    postgres.insert_lexer_matchers(vec![
        Matcher::legacy(
            "unicode_single_quote",
            |s| s.starts_with("U&'"),
            r"(?s)U&(('')+?(?!')|('.*?(?<!')(?:'')*'(?!')))(\s*UESCAPE\s*'[^0-9A-Fa-f'+\-\s)]')?",
            SyntaxKind::UnicodeSingleQuote
        ),
        Matcher::legacy(
            "escaped_single_quote",
            |s| s.starts_with("E'"),
            r"(?s)E(('')+?(?!')|'.*?((?<!\\)(?:\\\\)*(?<!')(?:'')*|(?<!\\)(?:\\\\)*\\(?<!')(?:'')*')'(?!'))",
            SyntaxKind::EscapedSingleQuote
        ),
        Matcher::regex(
            "unicode_double_quote",
            r#"(?s)U&".+?"(\s*UESCAPE\s*\'[^0-9A-Fa-f\'+\-\s)]\')?"#,
            SyntaxKind::UnicodeDoubleQuote
        ),
        Matcher::regex(
            "json_operator",
            r#"->>|#>>|->|#>|@>|<@|\?\||\?|\?&|#-"#,
            SyntaxKind::JsonOperator
        ),
        Matcher::string(
            "at",
            "@",
            SyntaxKind::At
        ),
        Matcher::regex(
            "bit_string_literal",
            r#"[bBxX]'[0-9a-fA-F]*'"#,
            SyntaxKind::BitStringLiteral
        ),
    ], "like_operator");

    postgres.insert_lexer_matchers(
        vec![
            Matcher::legacy(
                "meta_command",
                |s| s.starts_with("\\"),
                r"\\([^\\\r\n])+((\\\\)|(?=\n)|(?=\r\n))?",
                SyntaxKind::Comment,
            ),
            Matcher::regex(
                "dollar_numeric_literal",
                r"\$\d+",
                SyntaxKind::DollarNumericLiteral,
            ),
        ],
        "word",
    );

    postgres.patch_lexer_matchers(vec![
        Matcher::regex("inline_comment", r"(--)[^\n]*", SyntaxKind::InlineComment),
        Matcher::legacy(
            "single_quote",
            |s| s.starts_with("'"),
            r"(?s)('')+?(?!')|('.*?(?<!')(?:'')*'(?!'))",
            SyntaxKind::SingleQuote,
        ),
        Matcher::regex("double_quote", r#"(?s)".+?""#, SyntaxKind::DoubleQuote),
        Matcher::regex("word", r"[a-zA-Z_][0-9a-zA-Z_$]*", SyntaxKind::Word),
    ]);

    let keywords = postgres_keywords();
    let not_keywords = get_keywords(&keywords, "not-keyword");

    postgres
        .sets_mut("reserved_keywords")
        .extend(get_keywords(&keywords, "reserved"));
    postgres
        .sets_mut("unreserved_keywords")
        .extend(get_keywords(&keywords, "non-reserved"));

    postgres
        .sets_mut("reserved_keywords")
        .retain(|keyword| !not_keywords.contains(keyword));
    postgres
        .sets_mut("unreserved_keywords")
        .retain(|keyword| !not_keywords.contains(keyword));

    // Add datetime units
    postgres.sets_mut("datetime_units").extend([
        "CENTURY",
        "DECADE",
        "DOW",
        "DOY",
        "EPOCH",
        "ISODOW",
        "ISOYEAR",
        "MICROSECONDS",
        "MILLENNIUM",
        "MILLISECONDS",
        "TIMEZONE",
        "TIMEZONE_HOUR",
        "TIMEZONE_MINUTE",
    ]);

    // Set the bare functions
    postgres.sets_mut("bare_functions").extend([
        "CURRENT_TIMESTAMP",
        "CURRENT_TIME",
        "CURRENT_DATE",
        "LOCALTIME",
        "LOCALTIMESTAMP",
    ]);

    // Postgres doesn't have a dateadd function
    // Also according to https://www.postgresql.org/docs/14/functions-datetime.html
    // It quotes dateparts. So don't need this.
    postgres.sets_mut("date_part_function_name").clear();

    // In Postgres, UNNEST() returns a "value table", similar to BigQuery
    postgres
        .sets_mut("value_table_functions")
        .extend(["UNNEST", "GENERATE_SERIES"]);

    postgres.add([
        (
            "JsonOperatorSegment".into(),
            TypedParser::new(SyntaxKind::JsonOperator, SyntaxKind::BinaryOperator)
                .to_matchable()
                .into(),
        ),
        (
            "SimpleGeometryGrammar".into(),
            AnyNumberOf::new(vec_of_erased![Ref::new("NumericLiteralSegment")])
                .to_matchable()
                .into(),
        ),
        (
            "MultilineConcatenateNewline".into(),
            TypedParser::new(SyntaxKind::Newline, SyntaxKind::Newline)
                .to_matchable()
                .into(),
        ),
        (
            "MultilineConcatenateDelimiterGrammar".into(),
            AnyNumberOf::new(vec_of_erased![Ref::new("MultilineConcatenateNewline")])
                .config(|this| {
                    this.min_times(1);
                    this.disallow_gaps();
                })
                .to_matchable()
                .into(),
        ),
        (
            "NakedIdentifierFullSegment".into(),
            TypedParser::new(SyntaxKind::Word, SyntaxKind::NakedIdentifier)
                .to_matchable()
                .into(),
        ),
        (
            "PropertiesNakedIdentifierSegment".into(),
            TypedParser::new(SyntaxKind::Word, SyntaxKind::PropertiesNakedIdentifier)
                .to_matchable()
                .into(),
        ),
        (
            "SingleIdentifierFullGrammar".into(),
            one_of(vec_of_erased![
                Ref::new("NakedIdentifierSegment"),
                Ref::new("QuotedIdentifierSegment"),
                Ref::new("NakedIdentifierFullSegment")
            ])
            .to_matchable()
            .into(),
        ),
        (
            "DefinitionArgumentValueGrammar".into(),
            one_of(vec_of_erased![
                Ref::new("LiteralGrammar"),
                Ref::new("PropertiesNakedIdentifierSegment")
            ])
            .to_matchable()
            .into(),
        ),
        (
            "CascadeRestrictGrammar".into(),
            one_of(vec_of_erased![
                Ref::keyword("CASCADE"),
                Ref::keyword("RESTRICT")
            ])
            .to_matchable()
            .into(),
        ),
        (
            "ExtendedTableReferenceGrammar".into(),
            one_of(vec_of_erased![
                Ref::new("TableReferenceSegment"),
                Sequence::new(vec_of_erased![
                    Ref::keyword("ONLY"),
                    optionally_bracketed(vec_of_erased![Ref::new("TableReferenceSegment")])
                ]),
                Sequence::new(vec_of_erased![
                    Ref::new("TableReferenceSegment"),
                    Ref::new("StarSegment")
                ])
            ])
            .to_matchable()
            .into(),
        ),
        (
            "RightArrowSegment".into(),
            StringParser::new("=>", SyntaxKind::RightArrow)
                .to_matchable()
                .into(),
        ),
        (
            "OnKeywordAsIdentifierSegment".into(),
            StringParser::new("ON", SyntaxKind::NakedIdentifier)
                .to_matchable()
                .into(),
        ),
        (
            "DollarNumericLiteralSegment".into(),
            TypedParser::new(
                SyntaxKind::DollarNumericLiteral,
                SyntaxKind::DollarNumericLiteral,
            )
            .to_matchable()
            .into(),
        ),
        (
            "ForeignDataWrapperGrammar".into(),
            Sequence::new(vec_of_erased![
                Ref::keyword("FOREIGN"),
                Ref::keyword("DATA"),
                Ref::keyword("WRAPPER"),
            ])
            .to_matchable()
            .into(),
        ),
        (
            "OptionsListGrammar".into(),
            Sequence::new(vec_of_erased![Delimited::new(vec_of_erased![
                Ref::new("NakedIdentifierFullSegment"),
                Ref::new("QuotedLiteralSegment")
            ])])
            .to_matchable()
            .into(),
        ),
        (
            "OptionsGrammar".into(),
            Sequence::new(vec_of_erased![
                Ref::keyword("OPTIONS"),
                Bracketed::new(vec_of_erased![AnyNumberOf::new(vec_of_erased![Ref::new(
                    "OptionsListGrammar"
                )])])
            ])
            .to_matchable()
            .into(),
        ),
        (
            "CreateUserMappingGrammar".into(),
            Sequence::new(vec_of_erased![
                Ref::keyword("CREATE"),
                Ref::keyword("USER"),
                Ref::keyword("MAPPING"),
            ])
            .to_matchable()
            .into(),
        ),
        (
            "SessionInformationUserFunctionsGrammar".into(),
            one_of(vec_of_erased![
                Ref::keyword("USER"),
                Ref::keyword("CURRENT_ROLE"),
                Ref::keyword("CURRENT_USER"),
                Ref::keyword("SESSION_USER"),
            ])
            .to_matchable()
            .into(),
        ),
        (
            "ImportForeignSchemaGrammar".into(),
            Sequence::new(vec_of_erased![
                Ref::keyword("IMPORT"),
                Ref::keyword("FOREIGN"),
                Ref::keyword("SCHEMA"),
            ])
            .to_matchable()
            .into(),
        ),
    ]);

    postgres.add(
        [
            (
                "LikeGrammar".into(),
                one_of(vec_of_erased![
                    Ref::keyword("LIKE"),
                    Ref::keyword("ILIKE"),
                    Sequence::new(vec_of_erased![Ref::keyword("SIMILAR"), Ref::keyword("TO")])
                ])
                .to_matchable()
                .into(),
            ),
            (
                "StringBinaryOperatorGrammar".into(),
                one_of(vec_of_erased![
                    Ref::new("ConcatSegment"),
                    Ref::keyword("COLLATE"),
                ])
                .to_matchable()
                .into(),
            ),
            (
                "ComparisonOperatorGrammar".into(),
                one_of(vec_of_erased![
                    Ref::new("EqualsSegment"),
                    Ref::new("GreaterThanSegment"),
                    Ref::new("LessThanSegment"),
                    Ref::new("GreaterThanOrEqualToSegment"),
                    Ref::new("LessThanOrEqualToSegment"),
                    Ref::new("NotEqualToSegment"),
                    Ref::new("LikeOperatorSegment"),
                    Sequence::new(vec_of_erased![
                        Ref::keyword("IS"),
                        Ref::keyword("DISTINCT"),
                        Ref::keyword("FROM"),
                    ]),
                    Sequence::new(vec_of_erased![
                        Ref::keyword("IS"),
                        Ref::keyword("NOT"),
                        Ref::keyword("DISTINCT"),
                        Ref::keyword("FROM"),
                    ]),
                    Ref::new("OverlapSegment"),
                    Ref::new("NotExtendRightSegment"),
                    Ref::new("NotExtendLeftSegment"),
                    Ref::new("AdjacentSegment"),
                ])
                .to_matchable()
                .into(),
            ),
            (
                "NakedIdentifierSegment".into(),
                SegmentGenerator::new(|dialect| {
                    // Generate the anti-template from the set of reserved keywords
                    let reserved_keywords = dialect.sets("reserved_keywords");
                    let pattern = reserved_keywords.iter().join("|");
                    let anti_template = format!("^({})$", pattern);

                    RegexParser::new(
                        r"([A-Z_]+|[0-9]+[A-Z_$])[A-Z0-9_$]*",
                        SyntaxKind::NakedIdentifier,
                    )
                    .anti_template(&anti_template)
                    .to_matchable()
                })
                .into(),
            ),
            (
                "ParameterNameSegment".into(),
                RegexParser::new(r#"[A-Z_][A-Z0-9_$]*|\"[^\"]*\""#, SyntaxKind::Parameter)
                    .to_matchable()
                    .into(),
            ),
            (
                "FunctionNameIdentifierSegment".into(),
                RegexParser::new(r"[A-Z_][A-Z0-9_$]*", SyntaxKind::FunctionNameIdentifier)
                    .to_matchable()
                    .into(),
            ),
            (
                "FunctionContentsExpressionGrammar".into(),
                one_of(vec_of_erased![
                    Ref::new("ExpressionSegment"),
                    Ref::new("NamedArgumentSegment")
                ])
                .to_matchable()
                .into(),
            ),
            (
                "QuotedLiteralSegment".into(),
                one_of(vec_of_erased![
                    Sequence::new(vec_of_erased![
                        TypedParser::new(SyntaxKind::SingleQuote, SyntaxKind::QuotedLiteral),
                        AnyNumberOf::new(vec_of_erased![
                            Ref::new("MultilineConcatenateDelimiterGrammar"),
                            TypedParser::new(SyntaxKind::SingleQuote, SyntaxKind::QuotedLiteral),
                        ])
                    ]),
                    Sequence::new(vec_of_erased![
                        TypedParser::new(SyntaxKind::BitStringLiteral, SyntaxKind::QuotedLiteral),
                        AnyNumberOf::new(vec_of_erased![
                            Ref::new("MultilineConcatenateDelimiterGrammar"),
                            TypedParser::new(
                                SyntaxKind::BitStringLiteral,
                                SyntaxKind::QuotedLiteral
                            ),
                        ])
                    ]),
                    Delimited::new(vec_of_erased![
                        TypedParser::new(SyntaxKind::UnicodeSingleQuote, SyntaxKind::QuotedLiteral),
                        AnyNumberOf::new(vec_of_erased![
                            Ref::new("MultilineConcatenateDelimiterGrammar"),
                            TypedParser::new(
                                SyntaxKind::UnicodeSingleQuote,
                                SyntaxKind::QuotedLiteral
                            ),
                        ])
                    ]),
                    Delimited::new(vec_of_erased![
                        TypedParser::new(SyntaxKind::EscapedSingleQuote, SyntaxKind::QuotedLiteral),
                        AnyNumberOf::new(vec_of_erased![
                            Ref::new("MultilineConcatenateDelimiterGrammar"),
                            TypedParser::new(
                                SyntaxKind::EscapedSingleQuote,
                                SyntaxKind::QuotedLiteral,
                            ),
                        ])
                    ]),
                    Delimited::new(vec_of_erased![
                        TypedParser::new(SyntaxKind::DollarQuote, SyntaxKind::QuotedLiteral,),
                        AnyNumberOf::new(vec_of_erased![
                            Ref::new("MultilineConcatenateDelimiterGrammar"),
                            TypedParser::new(SyntaxKind::DollarQuote, SyntaxKind::QuotedLiteral),
                        ])
                    ]),
                ])
                .to_matchable()
                .into(),
            ),
            (
                "QuotedIdentifierSegment".into(),
                one_of(vec_of_erased![
                    TypedParser::new(SyntaxKind::DoubleQuote, SyntaxKind::QuotedIdentifier),
                    TypedParser::new(SyntaxKind::UnicodeDoubleQuote, SyntaxKind::QuotedLiteral),
                ])
                .to_matchable()
                .into(),
            ),
            (
                "PostFunctionGrammar".into(),
                AnyNumberOf::new(vec_of_erased![
                    Ref::new("WithinGroupClauseSegment"),
                    Ref::new("OverClauseSegment"),
                    Ref::new("FilterClauseGrammar"),
                ])
                .to_matchable()
                .into(),
            ),
            (
                "BinaryOperatorGrammar".into(),
                one_of(vec_of_erased![
                    Ref::new("ArithmeticBinaryOperatorGrammar"),
                    Ref::new("StringBinaryOperatorGrammar"),
                    Ref::new("BooleanBinaryOperatorGrammar"),
                    Ref::new("ComparisonOperatorGrammar"),
                    Ref::new("JsonOperatorSegment"),
                ])
                .to_matchable()
                .into(),
            ),
            (
                "FunctionParameterGrammar".into(),
                Sequence::new(vec_of_erased![
                    one_of(vec_of_erased![
                        Ref::keyword("IN"),
                        Ref::keyword("OUT"),
                        Ref::keyword("INOUT"),
                        Ref::keyword("VARIADIC"),
                    ])
                    .config(|this| this.optional()),
                    one_of(vec_of_erased![
                        Ref::new("DatatypeSegment"),
                        Sequence::new(vec_of_erased![
                            Ref::new("ParameterNameSegment"),
                            Ref::new("DatatypeSegment"),
                        ])
                    ]),
                    Sequence::new(vec_of_erased![
                        one_of(vec_of_erased![
                            Ref::keyword("DEFAULT"),
                            Ref::new("EqualsSegment"),
                        ]),
                        Ref::new("ExpressionSegment"),
                    ])
                    .config(|this| this.optional()),
                ])
                .to_matchable()
                .into(),
            ),
            (
                "FrameClauseUnitGrammar".into(),
                one_of(vec_of_erased![
                    Ref::keyword("RANGE"),
                    Ref::keyword("ROWS"),
                    Ref::keyword("GROUPS"),
                ])
                .to_matchable()
                .into(),
            ),
            (
                "IsNullGrammar".into(),
                Ref::keyword("ISNULL").to_matchable().into(),
            ),
            (
                "NotNullGrammar".into(),
                Ref::keyword("NOTNULL").to_matchable().into(),
            ),
            (
                "JoinKeywordsGrammar".into(),
                Sequence::new(vec_of_erased![
                    Ref::keyword("JOIN"),
                    Sequence::new(vec_of_erased![Ref::keyword("LATERAL")])
                        .config(|this| this.optional()),
                ])
                .to_matchable()
                .into(),
            ),
            (
                "SelectClauseTerminatorGrammar".into(),
                one_of(vec_of_erased![
                    Ref::keyword("INTO"),
                    Ref::keyword("FROM"),
                    Ref::keyword("WHERE"),
                    Sequence::new(vec_of_erased![Ref::keyword("ORDER"), Ref::keyword("BY"),]),
                    Ref::keyword("LIMIT"),
                    Ref::new("CommaSegment"),
                    Ref::new("SetOperatorSegment"),
                ])
                .to_matchable()
                .into(),
            ),
            // Assuming the existence of `ansi_dialect` in Rust and a way to manipulate its
            // grammar:
            (
                "LiteralGrammar".into(),
                postgres
                    .grammar("LiteralGrammar")
                    .copy(
                        Some(vec_of_erased![
                            Ref::new("DollarNumericLiteralSegment"),
                            Ref::new("PsqlVariableGrammar")
                        ]),
                        None,
                        Some(Ref::new("ArrayLiteralSegment").to_matchable()),
                        None,
                        Vec::new(),
                        false,
                    )
                    .into(),
            ),
            (
                "FromClauseTerminatorGrammar".into(),
                postgres
                    .grammar("FromClauseTerminatorGrammar")
                    .copy(
                        Some(vec_of_erased![Ref::new("ForClauseSegment")]),
                        None,
                        None,
                        None,
                        Vec::new(),
                        false,
                    )
                    .into(),
            ),
            (
                "WhereClauseTerminatorGrammar".into(),
                one_of(vec_of_erased![
                    Ref::keyword("LIMIT"),
                    Sequence::new(vec_of_erased![Ref::keyword("GROUP"), Ref::keyword("BY"),]),
                    Sequence::new(vec_of_erased![Ref::keyword("ORDER"), Ref::keyword("BY"),]),
                    Ref::keyword("HAVING"),
                    Ref::keyword("QUALIFY"),
                    Ref::keyword("WINDOW"),
                    Ref::keyword("OVERLAPS"),
                    Ref::keyword("RETURNING"),
                    Sequence::new(vec_of_erased![Ref::keyword("ON"), Ref::keyword("CONFLICT"),]),
                    Ref::new("ForClauseSegment"),
                ])
                .to_matchable()
                .into(),
            ),
            (
                "OrderByClauseTerminators".into(),
                one_of(vec_of_erased![
                    Ref::keyword("LIMIT"),
                    Ref::keyword("HAVING"),
                    Ref::keyword("QUALIFY"),
                    Ref::keyword("WINDOW"),
                    Ref::new("FrameClauseUnitGrammar"),
                    Ref::keyword("SEPARATOR"),
                    Sequence::new(vec_of_erased![Ref::keyword("WITH"), Ref::keyword("DATA"),]),
                    Ref::new("ForClauseSegment"),
                ])
                .to_matchable()
                .into(),
            ),
            (
                "AccessorGrammar".into(),
                AnyNumberOf::new(vec_of_erased![
                    Ref::new("ArrayAccessorSegment"),
                    Ref::new("SemiStructuredAccessorSegment"),
                ])
                .to_matchable()
                .into(),
            ),
            (
                "NonWithSelectableGrammar".into(),
                one_of(vec_of_erased![
                    Ref::new("SetExpressionSegment"),
                    optionally_bracketed(vec_of_erased![Ref::new("SelectStatementSegment")]),
                    Ref::new("NonSetSelectableGrammar"),
                    Ref::new("UpdateStatementSegment"),
                    Ref::new("InsertStatementSegment"),
                    Ref::new("DeleteStatementSegment"),
                ])
                .to_matchable()
                .into(),
            ),
            (
                "NonWithNonSelectableGrammar".into(),
                one_of(vec_of_erased![]).to_matchable().into(),
            ),
        ],
    );

    postgres.add([
        (
            "OverlapSegment".into(),
            NodeMatcher::new(
                SyntaxKind::ComparisonOperator,
                Sequence::new(vec_of_erased![
                    Ref::new("AmpersandSegment"),
                    Ref::new("AmpersandSegment")
                ])
                .to_matchable(),
            )
            .to_matchable()
            .into(),
        ),
        (
            "NotExtendRightSegment".into(),
            NodeMatcher::new(
                SyntaxKind::ComparisonOperator,
                Sequence::new(vec_of_erased![
                    Ref::new("AmpersandSegment"),
                    Ref::new("RawGreaterThanSegment")
                ])
                .allow_gaps(false)
                .to_matchable(),
            )
            .to_matchable()
            .into(),
        ),
        (
            "NotExtendLeftSegment".into(),
            NodeMatcher::new(
                SyntaxKind::ComparisonOperator,
                Sequence::new(vec_of_erased![
                    Ref::new("AmpersandSegment"),
                    Ref::new("RawLessThanSegment")
                ])
                .allow_gaps(false)
                .to_matchable(),
            )
            .to_matchable()
            .into(),
        ),
        (
            "AdjacentSegment".into(),
            NodeMatcher::new(
                SyntaxKind::ComparisonOperator,
                Sequence::new(vec_of_erased![
                    Ref::new("MinusSegment"),
                    Ref::new("PipeSegment"),
                    Ref::new("MinusSegment")
                ])
                .allow_gaps(false)
                .to_matchable(),
            )
            .to_matchable()
            .into(),
        ),
    ]);

    postgres.add([(
        "PsqlVariableGrammar".into(),
        NodeMatcher::new(
            SyntaxKind::PsqlVariable,
            Sequence::new(vec_of_erased![optionally_bracketed(vec_of_erased![
                Ref::new("ColonSegment"),
                one_of(vec_of_erased![
                    Ref::new("ParameterNameSegment"),
                    Ref::new("QuotedLiteralSegment")
                ])
            ])])
            .to_matchable(),
        )
        .to_matchable()
        .into(),
    )]);

    postgres.replace_grammar(
        "ArrayAccessorSegment",
        Bracketed::new(vec_of_erased![one_of(vec_of_erased![
            // These three are for a single element access: [n]
            Ref::new("QualifiedNumericLiteralSegment"),
            Ref::new("NumericLiteralSegment"),
            Ref::new("ExpressionSegment"),
            // This is for slice access: [n:m], [:m], [n:], and [:]
            Sequence::new(vec_of_erased![
                one_of(vec_of_erased![
                    Ref::new("QualifiedNumericLiteralSegment"),
                    Ref::new("NumericLiteralSegment"),
                    Ref::new("ExpressionSegment"),
                ])
                .config(|this| this.optional()),
                Ref::new("SliceSegment"),
                one_of(vec_of_erased![
                    Ref::new("QualifiedNumericLiteralSegment"),
                    Ref::new("NumericLiteralSegment"),
                    Ref::new("ExpressionSegment"),
                ])
                .config(|this| this.optional()),
            ]),
        ])])
        .config(|this| {
            this.bracket_type("square");
        })
        .to_matchable(),
    );

    postgres.add([(
        "DateTimeTypeIdentifier".into(),
        NodeMatcher::new(
            SyntaxKind::DatetimeTypeIdentifier,
            one_of(vec_of_erased![
                Ref::keyword("DATE"),
                Sequence::new(vec_of_erased![
                    one_of(vec_of_erased![
                        Ref::keyword("TIME"),
                        Ref::keyword("TIMESTAMP")
                    ]),
                    Bracketed::new(vec_of_erased![Ref::new("NumericLiteralSegment")])
                        .config(|this| this.optional()),
                    Sequence::new(vec_of_erased![
                        one_of(vec_of_erased![
                            Ref::keyword("WITH"),
                            Ref::keyword("WITHOUT")
                        ]),
                        Ref::keyword("TIME"),
                        Ref::keyword("ZONE")
                    ])
                    .config(|this| this.optional())
                ]),
                Sequence::new(vec_of_erased![
                    one_of(vec_of_erased![
                        Ref::keyword("INTERVAL"),
                        Ref::keyword("TIMETZ"),
                        Ref::keyword("TIMESTAMPTZ")
                    ]),
                    Bracketed::new(vec_of_erased![Ref::new("NumericLiteralSegment")])
                        .config(|this| this.optional())
                ])
            ])
            .to_matchable(),
        )
        .to_matchable()
        .into(),
    )]);

    postgres.add([(
        "DateTimeLiteralGrammar".into(),
        NodeMatcher::new(
            SyntaxKind::DatetimeLiteral,
            Sequence::new(vec_of_erased![
                Ref::new("DateTimeTypeIdentifier").optional(),
                Ref::new("QuotedLiteralSegment")
            ])
            .to_matchable(),
        )
        .to_matchable()
        .into(),
    )]);

    postgres.replace_grammar(
        "DatatypeSegment",
        Sequence::new(vec_of_erased![
            Sequence::new(vec_of_erased![
                Ref::new("SingleIdentifierGrammar"),
                Ref::new("DotSegment")
            ])
            .config(|this| {
                this.allow_gaps = false;
                this.optional();
            }),
            one_of(vec_of_erased![
                Ref::new("WellKnownTextGeometrySegment"),
                Ref::new("DateTimeTypeIdentifier"),
                Sequence::new(vec_of_erased![one_of(vec_of_erased![
                    Ref::keyword("SMALLINT"),
                    Ref::keyword("INTEGER"),
                    Ref::keyword("INT"),
                    Ref::keyword("INT2"),
                    Ref::keyword("INT4"),
                    Ref::keyword("INT8"),
                    Ref::keyword("BIGINT"),
                    Ref::keyword("FLOAT4"),
                    Ref::keyword("FLOAT8"),
                    Ref::keyword("REAL"),
                    Sequence::new(vec_of_erased![
                        Ref::keyword("DOUBLE"),
                        Ref::keyword("PRECISION")
                    ]),
                    Ref::keyword("SMALLSERIAL"),
                    Ref::keyword("SERIAL"),
                    Ref::keyword("SERIAL2"),
                    Ref::keyword("SERIAL4"),
                    Ref::keyword("SERIAL8"),
                    Ref::keyword("BIGSERIAL"),
                    // Numeric types [(precision)]
                    Sequence::new(vec_of_erased![
                        one_of(vec_of_erased![Ref::keyword("FLOAT")]),
                        Ref::new("BracketedArguments").optional()
                    ]),
                    // Numeric types [precision ["," scale])]
                    Sequence::new(vec_of_erased![
                        one_of(vec_of_erased![
                            Ref::keyword("DECIMAL"),
                            Ref::keyword("NUMERIC")
                        ]),
                        Ref::new("BracketedArguments").optional()
                    ]),
                    // Monetary type
                    Ref::keyword("MONEY"),
                    // Character types
                    one_of(vec_of_erased![
                        Sequence::new(vec_of_erased![
                            one_of(vec_of_erased![
                                Ref::keyword("BPCHAR"),
                                Ref::keyword("CHAR"),
                                Sequence::new(vec_of_erased![
                                    Ref::keyword("CHAR"),
                                    Ref::keyword("VARYING")
                                ]),
                                Ref::keyword("CHARACTER"),
                                Sequence::new(vec_of_erased![
                                    Ref::keyword("CHARACTER"),
                                    Ref::keyword("VARYING")
                                ]),
                                Ref::keyword("VARCHAR")
                            ]),
                            Ref::new("BracketedArguments").optional()
                        ]),
                        Ref::keyword("TEXT")
                    ]),
                    // Binary type
                    Ref::keyword("BYTEA"),
                    // Boolean types
                    one_of(vec_of_erased![
                        Ref::keyword("BOOLEAN"),
                        Ref::keyword("BOOL")
                    ]),
                    // Geometric types
                    one_of(vec_of_erased![
                        Ref::keyword("POINT"),
                        Ref::keyword("LINE"),
                        Ref::keyword("LSEG"),
                        Ref::keyword("BOX"),
                        Ref::keyword("PATH"),
                        Ref::keyword("POLYGON"),
                        Ref::keyword("CIRCLE")
                    ]),
                    // Network address types
                    one_of(vec_of_erased![
                        Ref::keyword("CIDR"),
                        Ref::keyword("INET"),
                        Ref::keyword("MACADDR"),
                        Ref::keyword("MACADDR8")
                    ]),
                    // Text search types
                    one_of(vec_of_erased![
                        Ref::keyword("TSVECTOR"),
                        Ref::keyword("TSQUERY")
                    ]),
                    // Bit string types
                    Sequence::new(vec_of_erased![
                        Ref::keyword("BIT"),
                        one_of(vec_of_erased![Ref::keyword("VARYING")])
                            .config(|this| this.optional()),
                        Ref::new("BracketedArguments").optional()
                    ]),
                    // UUID type
                    Ref::keyword("UUID"),
                    // XML type
                    Ref::keyword("XML"),
                    // JSON types
                    one_of(vec_of_erased![Ref::keyword("JSON"), Ref::keyword("JSONB")]),
                    // Range types
                    Ref::keyword("INT4RANGE"),
                    Ref::keyword("INT8RANGE"),
                    Ref::keyword("NUMRANGE"),
                    Ref::keyword("TSRANGE"),
                    Ref::keyword("TSTZRANGE"),
                    Ref::keyword("DATERANGE"),
                    // pg_lsn type
                    Ref::keyword("PG_LSN")
                ])]),
                Ref::new("DatatypeIdentifierSegment")
            ]),
            one_of(vec_of_erased![
                AnyNumberOf::new(vec_of_erased![Bracketed::new(vec_of_erased![Ref::new(
                    "ExpressionSegment"
                )
                .optional()])
                .config(|this| this.bracket_type("square"))]),
                Ref::new("ArrayTypeSegment"),
                Ref::new("SizedArrayTypeSegment"),
            ])
            .config(|this| this.optional()),
        ])
        .to_matchable(),
    );

    postgres.replace_grammar("ArrayTypeSegment", Ref::keyword("ARRAY").to_matchable());

    postgres.add([(
        "IndexAccessMethodSegment".into(),
        NodeMatcher::new(
            SyntaxKind::IndexAccessMethod,
            Ref::new("SingleIdentifierGrammar").to_matchable(),
        )
        .to_matchable()
        .into(),
    )]);

    postgres.add([(
        "OperatorClassReferenceSegment".into(),
        NodeMatcher::new(
            SyntaxKind::OperatorClassReference,
            postgres
                .grammar("ObjectReferenceSegment")
                .match_grammar()
                .unwrap(),
        )
        .to_matchable()
        .into(),
    )]);

    postgres.add([
        (
            "DefinitionParameterSegment".into(),
            NodeMatcher::new(
                SyntaxKind::DefinitionParameter,
                Sequence::new(vec_of_erased![
                    Ref::new("PropertiesNakedIdentifierSegment"),
                    Sequence::new(vec_of_erased![
                        Ref::new("EqualsSegment"),
                        Ref::new("DefinitionArgumentValueGrammar").optional()
                    ])
                ])
                .to_matchable(),
            )
            .to_matchable()
            .into(),
        ),
        (
            "DefinitionParametersSegment".into(),
            NodeMatcher::new(
                SyntaxKind::DefinitionParameters,
                Bracketed::new(vec_of_erased![Delimited::new(vec_of_erased![Ref::new(
                    "DefinitionParameterSegment"
                )])])
                .to_matchable(),
            )
            .to_matchable()
            .into(),
        ),
    ]);

    postgres.replace_grammar(
        "CreateCastStatementSegment",
        Sequence::new(vec_of_erased![
            Ref::keyword("CREATE"),
            Ref::keyword("CAST"),
            Bracketed::new(vec_of_erased![Sequence::new(vec_of_erased![
                Ref::new("DatatypeSegment"),
                Ref::keyword("AS"),
                Ref::new("DatatypeSegment"),
            ])]),
            one_of(vec_of_erased![
                Sequence::new(vec_of_erased![
                    Ref::keyword("WITH"),
                    Ref::keyword("FUNCTION"),
                    Ref::new("FunctionNameSegment"),
                    Ref::new("FunctionParameterListGrammar").optional(),
                ]),
                Sequence::new(vec_of_erased![
                    Ref::keyword("WITHOUT"),
                    Ref::keyword("FUNCTION")
                ]),
                Sequence::new(vec_of_erased![Ref::keyword("WITH"), Ref::keyword("INOUT")]),
            ]),
            one_of(vec_of_erased![
                Sequence::new(vec_of_erased![
                    Ref::keyword("AS"),
                    Ref::keyword("ASSIGNMENT")
                ])
                .config(|this| this.optional()),
                Sequence::new(vec_of_erased![Ref::keyword("AS"), Ref::keyword("IMPLICIT")])
                    .config(|this| this.optional()),
            ])
            .config(|this| this.optional()),
        ])
        .to_matchable(),
    );

    postgres.replace_grammar(
        "DropCastStatementSegment",
        Sequence::new(vec_of_erased![
            Ref::keyword("DROP"),
            Ref::keyword("CAST"),
            Sequence::new(vec_of_erased![Ref::keyword("IF"), Ref::keyword("EXISTS")])
                .config(|this| this.optional()),
            Bracketed::new(vec_of_erased![Sequence::new(vec_of_erased![
                Ref::new("DatatypeSegment"),
                Ref::keyword("AS"),
                Ref::new("DatatypeSegment"),
            ])]),
            Ref::new("DropBehaviorGrammar").optional(),
        ])
        .to_matchable(),
    );

    postgres.add([
        (
            "RelationOptionSegment".into(),
            NodeMatcher::new(
                SyntaxKind::RelationOption,
                Sequence::new(vec_of_erased![
                    Ref::new("PropertiesNakedIdentifierSegment"),
                    Sequence::new(vec_of_erased![
                        Ref::new("DotSegment"),
                        Ref::new("PropertiesNakedIdentifierSegment"),
                    ])
                    .config(|this| this.optional()),
                    Sequence::new(vec_of_erased![
                        Ref::new("EqualsSegment"),
                        Ref::new("DefinitionArgumentValueGrammar").optional(),
                    ])
                    .config(|this| this.optional()),
                ])
                .to_matchable(),
            )
            .to_matchable()
            .into(),
        ),
        (
            "RelationOptionsSegment".into(),
            NodeMatcher::new(
                SyntaxKind::RelationOptions,
                Bracketed::new(vec_of_erased![Delimited::new(vec_of_erased![Ref::new(
                    "RelationOptionSegment"
                )])])
                .to_matchable(),
            )
            .to_matchable()
            .into(),
        ),
    ]);

    postgres.replace_grammar(
        "CreateFunctionStatementSegment",
        Sequence::new(vec_of_erased![
            Ref::keyword("CREATE"),
            Sequence::new(vec_of_erased![Ref::keyword("OR"), Ref::keyword("REPLACE")])
                .config(|this| this.optional()),
            Ref::new("TemporaryGrammar").optional(),
            Ref::keyword("FUNCTION"),
            Ref::new("IfNotExistsGrammar").optional(),
            Ref::new("FunctionNameSegment"),
            Ref::new("FunctionParameterListGrammar"),
            Sequence::new(vec_of_erased![
                Ref::keyword("RETURNS"),
                one_of(vec_of_erased![
                    Sequence::new(vec_of_erased![
                        Ref::keyword("TABLE"),
                        Bracketed::new(vec_of_erased![Delimited::new(vec_of_erased![one_of(
                            vec_of_erased![
                                Ref::new("DatatypeSegment"),
                                Sequence::new(vec_of_erased![
                                    Ref::new("ColumnReferenceSegment"),
                                    Ref::new("DatatypeSegment"),
                                ]),
                            ]
                        )])])
                        .config(|this| this.optional()),
                    ]),
                    Sequence::new(vec_of_erased![
                        Ref::keyword("SETOF"),
                        Ref::new("DatatypeSegment"),
                    ]),
                    Ref::new("DatatypeSegment"),
                ])
                .config(|this| this.optional()),
            ])
            .config(|this| this.optional()),
            Ref::new("FunctionDefinitionGrammar"),
        ])
        .to_matchable(),
    );

    postgres.add([
        (
            "DropFunctionStatementSegment".into(),
            NodeMatcher::new(
                SyntaxKind::DropFunctionStatement,
                Sequence::new(vec_of_erased![
                    Ref::keyword("DROP"),
                    Ref::keyword("FUNCTION"),
                    Ref::new("IfExistsGrammar").optional(),
                    Delimited::new(vec_of_erased![Sequence::new(vec_of_erased![
                        Ref::new("FunctionNameSegment"),
                        Ref::new("FunctionParameterListGrammar").optional(),
                    ])]),
                    Ref::new("DropBehaviorGrammar").optional(),
                ])
                .to_matchable(),
            )
            .to_matchable()
            .into(),
        ),
        (
            "AlterFunctionStatementSegment".into(),
            NodeMatcher::new(
                SyntaxKind::AlterFunctionStatement,
                Sequence::new(vec_of_erased![
                    Ref::keyword("ALTER"),
                    Ref::keyword("FUNCTION"),
                    Delimited::new(vec_of_erased![Sequence::new(vec_of_erased![
                        Ref::new("FunctionNameSegment"),
                        Ref::new("FunctionParameterListGrammar").optional(),
                    ])]),
                    one_of(vec_of_erased![
                        Ref::new("AlterFunctionActionSegment").optional(),
                        Sequence::new(vec_of_erased![
                            Ref::keyword("RENAME"),
                            Ref::keyword("TO"),
                            Ref::new("FunctionNameSegment")
                        ]),
                        Sequence::new(vec_of_erased![
                            Ref::keyword("SET"),
                            Ref::keyword("SCHEMA"),
                            Ref::new("SchemaReferenceSegment")
                        ]),
                        Sequence::new(vec_of_erased![
                            Ref::keyword("OWNER"),
                            Ref::keyword("TO"),
                            one_of(vec_of_erased![
                                one_of(vec_of_erased![
                                    Ref::new("ParameterNameSegment"),
                                    Ref::new("QuotedIdentifierSegment")
                                ]),
                                Ref::keyword("CURRENT_ROLE"),
                                Ref::keyword("CURRENT_USER"),
                                Ref::keyword("SESSION_USER")
                            ])
                        ]),
                        Sequence::new(vec_of_erased![
                            Ref::keyword("NO").optional(),
                            Ref::keyword("DEPENDS"),
                            Ref::keyword("ON"),
                            Ref::keyword("EXTENSION"),
                            Ref::new("ExtensionReferenceSegment")
                        ])
                    ])
                ])
                .to_matchable(),
            )
            .to_matchable()
            .into(),
        ),
        (
            "AlterFunctionActionSegment".into(),
            NodeMatcher::new(
                SyntaxKind::AlterFunctionActionSegment,
                Sequence::new(vec_of_erased![
                    one_of(vec_of_erased![
                        one_of(vec_of_erased![
                            Sequence::new(vec_of_erased![
                                Ref::keyword("CALLED"),
                                Ref::keyword("ON"),
                                Ref::keyword("NULL"),
                                Ref::keyword("INPUT"),
                            ]),
                            Sequence::new(vec_of_erased![
                                Ref::keyword("RETURNS"),
                                Ref::keyword("NULL"),
                                Ref::keyword("ON"),
                                Ref::keyword("NULL"),
                                Ref::keyword("INPUT"),
                            ]),
                            Ref::keyword("STRICT"),
                        ]),
                        one_of(vec_of_erased![
                            Ref::keyword("IMMUTABLE"),
                            Ref::keyword("STABLE"),
                            Ref::keyword("VOLATILE"),
                        ]),
                        Sequence::new(vec_of_erased![
                            Ref::keyword("NOT").optional(),
                            Ref::keyword("LEAKPROOF"),
                        ]),
                        Sequence::new(vec_of_erased![
                            Ref::keyword("EXTERNAL").optional(),
                            Ref::keyword("SECURITY"),
                            one_of(vec_of_erased![
                                Ref::keyword("DEFINER"),
                                Ref::keyword("INVOKER"),
                            ]),
                        ]),
                        Sequence::new(vec_of_erased![
                            Ref::keyword("PARALLEL"),
                            one_of(vec_of_erased![
                                Ref::keyword("UNSAFE"),
                                Ref::keyword("RESTRICTED"),
                                Ref::keyword("SAFE"),
                            ]),
                        ]),
                        Sequence::new(vec_of_erased![
                            Ref::keyword("COST"),
                            Ref::new("NumericLiteralSegment"),
                        ]),
                        Sequence::new(vec_of_erased![
                            Ref::keyword("ROWS"),
                            Ref::new("NumericLiteralSegment"),
                        ]),
                        Sequence::new(vec_of_erased![
                            Ref::keyword("SUPPORT"),
                            Ref::new("ParameterNameSegment"),
                        ]),
                        Sequence::new(vec_of_erased![
                            Ref::keyword("SET"),
                            Ref::new("ParameterNameSegment"),
                            one_of(vec_of_erased![
                                Sequence::new(vec_of_erased![
                                    one_of(vec_of_erased![
                                        Ref::keyword("TO"),
                                        Ref::new("EqualsSegment"),
                                    ]),
                                    one_of(vec_of_erased![
                                        Ref::new("LiteralGrammar"),
                                        Ref::new("NakedIdentifierSegment"),
                                        Ref::keyword("DEFAULT"),
                                    ]),
                                ]),
                                Sequence::new(vec_of_erased![
                                    Ref::keyword("FROM"),
                                    Ref::keyword("CURRENT"),
                                ]),
                            ]),
                        ]),
                        Sequence::new(vec_of_erased![
                            Ref::keyword("RESET"),
                            one_of(vec_of_erased![
                                Ref::keyword("ALL"),
                                Ref::new("ParameterNameSegment"),
                            ]),
                        ]),
                    ]),
                    Ref::keyword("RESTRICT").optional(),
                ])
                .to_matchable(),
            )
            .to_matchable()
            .into(),
        ),
        (
            "AlterProcedureActionSegment".into(),
            NodeMatcher::new(
                SyntaxKind::AlterProcedureActionSegment,
                Sequence::new(vec_of_erased![
                    one_of(vec_of_erased![
                        Sequence::new(vec_of_erased![
                            Ref::keyword("EXTERNAL").optional(),
                            Ref::keyword("SECURITY"),
                            one_of(vec_of_erased![
                                Ref::keyword("DEFINER"),
                                Ref::keyword("INVOKER"),
                            ]),
                        ]),
                        Sequence::new(vec_of_erased![
                            Ref::keyword("SET"),
                            Ref::new("ParameterNameSegment"),
                            one_of(vec_of_erased![
                                Sequence::new(vec_of_erased![
                                    one_of(vec_of_erased![
                                        Ref::keyword("TO"),
                                        Ref::new("EqualsSegment"),
                                    ]),
                                    one_of(vec_of_erased![
                                        Ref::new("LiteralGrammar"),
                                        Ref::new("NakedIdentifierSegment"),
                                        Ref::keyword("DEFAULT"),
                                    ]),
                                ]),
                                Sequence::new(vec_of_erased![
                                    Ref::keyword("FROM"),
                                    Ref::keyword("CURRENT"),
                                ]),
                            ]),
                        ]),
                        Sequence::new(vec_of_erased![
                            Ref::keyword("RESET"),
                            one_of(vec_of_erased![
                                Ref::keyword("ALL"),
                                Ref::new("ParameterNameSegment"),
                            ]),
                        ]),
                    ]),
                    Ref::keyword("RESTRICT").optional(),
                ])
                .to_matchable(),
            )
            .to_matchable()
            .into(),
        ),
        (
            "AlterProcedureStatementSegment".into(),
            NodeMatcher::new(
                SyntaxKind::AlterProcedureStatement,
                Sequence::new(vec_of_erased![
                    Ref::keyword("ALTER"),
                    Ref::keyword("PROCEDURE"),
                    Delimited::new(vec_of_erased![Sequence::new(vec_of_erased![
                        Ref::new("FunctionNameSegment"),
                        Ref::new("FunctionParameterListGrammar").optional(),
                    ])]),
                    one_of(vec_of_erased![
                        Ref::new("AlterProcedureActionSegment").optional(),
                        Sequence::new(vec_of_erased![
                            Ref::keyword("RENAME"),
                            Ref::keyword("TO"),
                            Ref::new("FunctionNameSegment"),
                        ]),
                        Sequence::new(vec_of_erased![
                            Ref::keyword("SET"),
                            Ref::keyword("SCHEMA"),
                            Ref::new("SchemaReferenceSegment"),
                        ]),
                        Sequence::new(vec_of_erased![
                            Ref::keyword("SET"),
                            Ref::new("ParameterNameSegment"),
                            one_of(vec_of_erased![
                                Sequence::new(vec_of_erased![
                                    one_of(vec_of_erased![
                                        Ref::keyword("TO"),
                                        Ref::new("EqualsSegment"),
                                    ]),
                                    Delimited::new(vec_of_erased![one_of(vec_of_erased![
                                        Ref::new("ParameterNameSegment"),
                                        Ref::new("LiteralGrammar"),
                                    ])]),
                                ]),
                                Sequence::new(vec_of_erased![
                                    Ref::keyword("FROM"),
                                    Ref::keyword("CURRENT"),
                                ]),
                            ]),
                        ]),
                        Sequence::new(vec_of_erased![
                            Ref::keyword("OWNER"),
                            Ref::keyword("TO"),
                            one_of(vec_of_erased![
                                one_of(vec_of_erased![
                                    Ref::new("ParameterNameSegment"),
                                    Ref::new("QuotedIdentifierSegment"),
                                ]),
                                Ref::keyword("CURRENT_ROLE"),
                                Ref::keyword("CURRENT_USER"),
                                Ref::keyword("SESSION_USER"),
                            ]),
                        ]),
                        Sequence::new(vec_of_erased![
                            Ref::keyword("NO").optional(),
                            Ref::keyword("DEPENDS"),
                            Ref::keyword("ON"),
                            Ref::keyword("EXTENSION"),
                            Ref::new("ExtensionReferenceSegment"),
                        ]),
                    ])
                ])
                .to_matchable(),
            )
            .to_matchable()
            .into(),
        ),
        (
            "CreateProcedureStatementSegment".into(),
            NodeMatcher::new(
                SyntaxKind::CreateProcedureStatement,
                Sequence::new(vec_of_erased![
                    Ref::keyword("CREATE"),
                    Sequence::new(vec_of_erased![Ref::keyword("OR"), Ref::keyword("REPLACE")])
                        .config(|this| this.optional()),
                    Ref::keyword("PROCEDURE"),
                    Ref::new("FunctionNameSegment"),
                    Ref::new("FunctionParameterListGrammar"),
                    Ref::new("FunctionDefinitionGrammar"),
                ])
                .to_matchable(),
            )
            .to_matchable()
            .into(),
        ),
        (
            "DropProcedureStatementSegment".into(),
            NodeMatcher::new(
                SyntaxKind::DropProcedureStatement,
                Sequence::new(vec_of_erased![
                    Ref::keyword("DROP"),
                    Ref::keyword("PROCEDURE"),
                    Ref::new("IfExistsGrammar").optional(),
                    Delimited::new(vec_of_erased![Sequence::new(vec_of_erased![
                        Ref::new("FunctionNameSegment"),
                        Ref::new("FunctionParameterListGrammar").optional(),
                    ])]),
                    one_of(vec_of_erased![
                        Ref::keyword("CASCADE"),
                        Ref::keyword("RESTRICT")
                    ])
                    .config(|this| this.optional()),
                ])
                .to_matchable(),
            )
            .to_matchable()
            .into(),
        ),
        (
            "WellKnownTextGeometrySegment".into(),
            NodeMatcher::new(SyntaxKind::WktGeometryType, {
                let geometry_type_keywords = POSTGRES_POSTGIS_DATATYPE_KEYWORDS
                    .iter()
                    .map(|(kw, _)| Ref::keyword(kw).to_matchable())
                    .collect_vec();

                let mut geometry_type_keywords0 = geometry_type_keywords.clone();
                geometry_type_keywords0.extend(
                    ["GEOMETRY", "GEOGRAPHY"]
                        .into_iter()
                        .map(|it| Ref::keyword(it).to_matchable()),
                );

                one_of(vec_of_erased![
                    Sequence::new(vec_of_erased![
                        one_of(geometry_type_keywords.clone()),
                        Bracketed::new(vec_of_erased![Delimited::new(vec_of_erased![
                            optionally_bracketed(vec_of_erased![Delimited::new(vec_of_erased![
                                Ref::new("SimpleGeometryGrammar")
                            ])]),
                            Bracketed::new(vec_of_erased![Delimited::new(vec_of_erased![
                                Bracketed::new(vec_of_erased![Delimited::new(vec_of_erased![
                                    Ref::new("SimpleGeometryGrammar")
                                ])])
                            ])]),
                            Ref::new("WellKnownTextGeometrySegment"),
                        ])]),
                    ]),
                    Sequence::new(vec_of_erased![
                        one_of(vec_of_erased![
                            Ref::keyword("GEOMETRY"),
                            Ref::keyword("GEOGRAPHY")
                        ]),
                        Bracketed::new(vec_of_erased![Sequence::new(vec_of_erased![
                            one_of(geometry_type_keywords0),
                            Ref::new("CommaSegment"),
                            Ref::new("NumericLiteralSegment"),
                        ])]),
                    ]),
                ])
                .to_matchable()
            })
            .to_matchable()
            .into(),
        ),
        (
            "SemiStructuredAccessorSegment".into(),
            NodeMatcher::new(
                SyntaxKind::SemiStructuredExpression,
                Sequence::new(vec_of_erased![
                    Ref::new("DotSegment"),
                    Ref::new("SingleIdentifierGrammar"),
                    Ref::new("ArrayAccessorSegment").optional(),
                    AnyNumberOf::new(vec_of_erased![
                        Sequence::new(vec_of_erased![
                            Ref::new("DotSegment"),
                            Ref::new("SingleIdentifierGrammar"),
                        ]),
                        Ref::new("ArrayAccessorSegment").optional(),
                    ])
                ])
                .to_matchable(),
            )
            .to_matchable()
            .into(),
        ),
    ]);

    postgres.replace_grammar(
        "FunctionDefinitionGrammar",
        Sequence::new(vec_of_erased![
            AnyNumberOf::new(vec_of_erased![
                Ref::new("LanguageClauseSegment"),
                Sequence::new(vec_of_erased![
                    Ref::keyword("TRANSFORM"),
                    Ref::keyword("FOR"),
                    Ref::keyword("TYPE"),
                    Ref::new("ParameterNameSegment"),
                ]),
                Ref::keyword("WINDOW"),
                one_of(vec_of_erased![
                    Ref::keyword("IMMUTABLE"),
                    Ref::keyword("STABLE"),
                    Ref::keyword("VOLATILE"),
                ]),
                Sequence::new(vec_of_erased![
                    Ref::keyword("NOT").optional(),
                    Ref::keyword("LEAKPROOF"),
                ]),
                one_of(vec_of_erased![
                    Sequence::new(vec_of_erased![
                        Ref::keyword("CALLED"),
                        Ref::keyword("ON"),
                        Ref::keyword("NULL"),
                        Ref::keyword("INPUT"),
                    ]),
                    Sequence::new(vec_of_erased![
                        Ref::keyword("RETURNS"),
                        Ref::keyword("NULL"),
                        Ref::keyword("ON"),
                        Ref::keyword("NULL"),
                        Ref::keyword("INPUT"),
                    ]),
                    Ref::keyword("STRICT"),
                ]),
                Sequence::new(vec_of_erased![
                    Ref::keyword("EXTERNAL").optional(),
                    Ref::keyword("SECURITY"),
                    one_of(vec_of_erased![
                        Ref::keyword("INVOKER"),
                        Ref::keyword("DEFINER"),
                    ]),
                ]),
                Sequence::new(vec_of_erased![
                    Ref::keyword("PARALLEL"),
                    one_of(vec_of_erased![
                        Ref::keyword("UNSAFE"),
                        Ref::keyword("RESTRICTED"),
                        Ref::keyword("SAFE"),
                    ]),
                ]),
                Sequence::new(vec_of_erased![
                    Ref::keyword("COST"),
                    Ref::new("NumericLiteralSegment"),
                ]),
                Sequence::new(vec_of_erased![
                    Ref::keyword("ROWS"),
                    Ref::new("NumericLiteralSegment"),
                ]),
                Sequence::new(vec_of_erased![
                    Ref::keyword("SUPPORT"),
                    Ref::new("ParameterNameSegment"),
                ]),
                Sequence::new(vec_of_erased![
                    Ref::keyword("SET"),
                    Ref::new("ParameterNameSegment"),
                    one_of(vec_of_erased![
                        Sequence::new(vec_of_erased![
                            one_of(vec_of_erased![
                                Ref::keyword("TO"),
                                Ref::new("EqualsSegment"),
                            ]),
                            Delimited::new(vec_of_erased![one_of(vec_of_erased![
                                Ref::new("ParameterNameSegment"),
                                Ref::new("LiteralGrammar"),
                            ]),]),
                        ]),
                        Sequence::new(vec_of_erased![
                            Ref::keyword("FROM"),
                            Ref::keyword("CURRENT"),
                        ]),
                    ]),
                ]),
                Sequence::new(vec_of_erased![
                    Ref::keyword("AS"),
                    one_of(vec_of_erased![
                        Ref::new("QuotedLiteralSegment"),
                        Sequence::new(vec_of_erased![
                            Ref::new("QuotedLiteralSegment"),
                            Ref::new("CommaSegment"),
                            Ref::new("QuotedLiteralSegment"),
                        ]),
                    ]),
                ]),
            ]),
            Sequence::new(vec_of_erased![
                Ref::keyword("WITH"),
                Bracketed::new(vec_of_erased![Delimited::new(vec_of_erased![Ref::new(
                    "ParameterNameSegment"
                )])]),
            ])
            .config(|this| this.optional()),
        ])
        .to_matchable(),
    );

    postgres.add([
        (
            "IntoClauseSegment".into(),
            NodeMatcher::new(
                SyntaxKind::IntoClause,
                Sequence::new(vec_of_erased![
                    Ref::keyword("INTO"),
                    one_of(vec_of_erased![
                        Ref::keyword("TEMPORARY"),
                        Ref::keyword("TEMP"),
                        Ref::keyword("UNLOGGED"),
                    ])
                    .config(|this| this.optional()),
                    Ref::keyword("TABLE").optional(),
                    Ref::new("TableReferenceSegment"),
                ])
                .to_matchable(),
            )
            .to_matchable()
            .into(),
        ),
        (
            "ForClauseSegment".into(),
            NodeMatcher::new(
                SyntaxKind::ForClause,
                Sequence::new(vec_of_erased![
                    Ref::keyword("FOR"),
                    one_of(vec_of_erased![
                        Ref::keyword("UPDATE"),
                        Sequence::new(vec_of_erased![
                            Ref::keyword("NO"),
                            Ref::keyword("KEY"),
                            Ref::keyword("UPDATE"),
                        ]),
                        Ref::keyword("SHARE"),
                        Sequence::new(vec_of_erased![Ref::keyword("KEY"), Ref::keyword("SHARE")]),
                    ]),
                    Sequence::new(vec_of_erased![
                        Ref::keyword("OF"),
                        Delimited::new(vec_of_erased![Ref::new("TableReferenceSegment")]),
                    ])
                    .config(|this| this.optional()),
                    one_of(vec_of_erased![
                        Ref::keyword("NOWAIT"),
                        Sequence::new(vec_of_erased![Ref::keyword("SKIP"), Ref::keyword("LOCKED")]),
                    ])
                    .config(|this| this.optional()),
                ])
                .to_matchable(),
            )
            .to_matchable()
            .into(),
        ),
    ]);

    postgres.replace_grammar(
        "UnorderedSelectStatementSegment",
        ansi::get_unordered_select_statement_segment_grammar().copy(
            Some(vec![Ref::new("IntoClauseSegment")
                .optional()
                .to_matchable()]),
            None,
            Some(Ref::new("FromClauseSegment").optional().to_matchable()),
            None,
            vec![
                Sequence::new(vec_of_erased![
                    Ref::keyword("WITH"),
                    Ref::keyword("NO").optional(),
                    Ref::keyword("DATA")
                ])
                .to_matchable(),
                Sequence::new(vec_of_erased![Ref::keyword("ON"), Ref::keyword("CONFLICT")])
                    .to_matchable(),
                Ref::keyword("RETURNING").to_matchable(),
                Ref::new("WithCheckOptionSegment").to_matchable(),
            ],
            false,
        ),
    );

    postgres.replace_grammar(
        "SelectStatementSegment",
        postgres
            .grammar("UnorderedSelectStatementSegment")
            .match_grammar()
            .unwrap()
            .copy(
                Some(vec![
                    Ref::new("OrderByClauseSegment").optional().to_matchable(),
                    Ref::new("LimitClauseSegment").optional().to_matchable(),
                    Ref::new("NamedWindowSegment").optional().to_matchable(),
                ]),
                None,
                None,
                None,
                vec![],
                false,
            )
            .copy(
                Some(vec![Ref::new("ForClauseSegment").optional().to_matchable()]),
                None,
                Some(Ref::new("LimitClauseSegment").optional().to_matchable()),
                None,
                vec![
                    Ref::new("SetOperatorSegment").to_matchable(),
                    Ref::new("WithNoSchemaBindingClauseSegment").to_matchable(),
                    Ref::new("WithDataClauseSegment").to_matchable(),
                    Sequence::new(vec_of_erased![Ref::keyword("ON"), Ref::keyword("CONFLICT")])
                        .to_matchable(),
                    Ref::keyword("RETURNING").to_matchable(),
                    Ref::new("WithCheckOptionSegment").to_matchable(),
                ],
                true,
            ),
    );

    postgres.replace_grammar(
        "SelectClauseSegment",
        Sequence::new(vec_of_erased![
            Ref::keyword("SELECT"),
            Ref::new("SelectClauseModifierSegment").optional(),
            MetaSegment::indent(),
            Delimited::new(vec_of_erased![Ref::new("SelectClauseElementSegment")]).config(|this| {
                this.optional();
                this.allow_trailing = true;
            })
        ])
        .config(|this| {
            this.terminators = vec_of_erased![
                Ref::keyword("INTO"),
                Ref::keyword("FROM"),
                Ref::keyword("WHERE"),
                Sequence::new(vec_of_erased![Ref::keyword("ORDER"), Ref::keyword("BY")]),
                Ref::keyword("LIMIT"),
                Ref::keyword("OVERLAPS"),
                Ref::new("SetOperatorSegment"),
                Sequence::new(vec_of_erased![
                    Ref::keyword("WITH"),
                    Ref::keyword("NO").optional(),
                    Ref::keyword("DATA"),
                ]),
                Ref::new("WithCheckOptionSegment"),
            ];
            this.parse_mode(ParseMode::GreedyOnceStarted);
        })
        .to_matchable(),
    );

    postgres.replace_grammar(
        "SelectClauseModifierSegment",
        one_of(vec_of_erased![
            Sequence::new(vec_of_erased![
                Ref::keyword("DISTINCT"),
                Sequence::new(vec_of_erased![
                    Ref::keyword("ON"),
                    Bracketed::new(vec_of_erased![Delimited::new(vec_of_erased![Ref::new(
                        "ExpressionSegment"
                    )])])
                    .config(|this| this.optional()),
                ]),
            ]),
            Ref::keyword("ALL"),
        ])
        .to_matchable(),
    );

    postgres.add([
        (
            "WithinGroupClauseSegment".into(),
            NodeMatcher::new(
                SyntaxKind::WithingroupClause,
                Sequence::new(vec_of_erased![
                    Ref::keyword("WITHIN"),
                    Ref::keyword("GROUP"),
                    Bracketed::new(vec_of_erased![Ref::new("OrderByClauseSegment").optional()]),
                ])
                .to_matchable(),
            )
            .to_matchable()
            .into(),
        ),
        (
            "GroupByClauseSegment".into(),
            NodeMatcher::new(
                SyntaxKind::GroupbyClause,
                Sequence::new(vec_of_erased![
                    Ref::keyword("GROUP"),
                    Ref::keyword("BY"),
                    MetaSegment::indent(),
                    Delimited::new(vec_of_erased![one_of(vec_of_erased![
                        Ref::new("ColumnReferenceSegment"),
                        Ref::new("NumericLiteralSegment"),
                        Ref::new("CubeRollupClauseSegment"),
                        Ref::new("GroupingSetsClauseSegment"),
                        Ref::new("ExpressionSegment"),
                        Bracketed::new(vec_of_erased![]),
                    ])])
                    .config(|this| {
                        this.terminators = vec_of_erased![
                            Sequence::new(vec_of_erased![
                                Ref::keyword("ORDER"),
                                Ref::keyword("BY")
                            ]),
                            Ref::keyword("LIMIT"),
                            Ref::keyword("HAVING"),
                            Ref::keyword("QUALIFY"),
                            Ref::keyword("WINDOW"),
                            Ref::new("SetOperatorSegment"),
                        ];
                    }),
                    MetaSegment::dedent(),
                ])
                .to_matchable(),
            )
            .to_matchable()
            .into(),
        ),
    ]);

    postgres.replace_grammar(
        "CreateRoleStatementSegment",
        Sequence::new(vec_of_erased![
            Ref::keyword("CREATE"),
            one_of(vec_of_erased![Ref::keyword("ROLE"), Ref::keyword("USER"),]),
            Ref::new("RoleReferenceSegment"),
            Sequence::new(vec_of_erased![
                Ref::keyword("WITH").optional(),
                any_set_of(vec_of_erased![
                    one_of(vec_of_erased![
                        Ref::keyword("SUPERUSER"),
                        Ref::keyword("NOSUPERUSER"),
                    ]),
                    one_of(vec_of_erased![
                        Ref::keyword("CREATEDB"),
                        Ref::keyword("NOCREATEDB"),
                    ]),
                    one_of(vec_of_erased![
                        Ref::keyword("CREATEROLE"),
                        Ref::keyword("NOCREATEROLE"),
                    ]),
                    one_of(vec_of_erased![
                        Ref::keyword("INHERIT"),
                        Ref::keyword("NOINHERIT"),
                    ]),
                    one_of(vec_of_erased![
                        Ref::keyword("LOGIN"),
                        Ref::keyword("NOLOGIN"),
                    ]),
                    one_of(vec_of_erased![
                        Ref::keyword("REPLICATION"),
                        Ref::keyword("NOREPLICATION"),
                    ]),
                    one_of(vec_of_erased![
                        Ref::keyword("BYPASSRLS"),
                        Ref::keyword("NOBYPASSRLS"),
                    ]),
                    Sequence::new(vec_of_erased![
                        Ref::keyword("CONNECTION"),
                        Ref::keyword("LIMIT"),
                        Ref::new("NumericLiteralSegment"),
                    ]),
                    Sequence::new(vec_of_erased![
                        Ref::keyword("PASSWORD"),
                        one_of(vec_of_erased![
                            Ref::new("QuotedLiteralSegment"),
                            Ref::keyword("NULL"),
                        ]),
                    ]),
                    Sequence::new(vec_of_erased![
                        Ref::keyword("VALID"),
                        Ref::keyword("UNTIL"),
                        Ref::new("QuotedLiteralSegment"),
                    ]),
                    Sequence::new(vec_of_erased![
                        Ref::keyword("IN"),
                        Ref::keyword("ROLE"),
                        Ref::new("RoleReferenceSegment"),
                    ]),
                    Sequence::new(vec_of_erased![
                        Ref::keyword("IN"),
                        Ref::keyword("GROUP"),
                        Ref::new("RoleReferenceSegment"),
                    ]),
                    Sequence::new(vec_of_erased![
                        Ref::keyword("ROLE"),
                        Ref::new("RoleReferenceSegment"),
                    ]),
                    Sequence::new(vec_of_erased![
                        Ref::keyword("ADMIN"),
                        Ref::new("RoleReferenceSegment"),
                    ]),
                    Sequence::new(vec_of_erased![
                        Ref::keyword("USER"),
                        Ref::new("RoleReferenceSegment"),
                    ]),
                    Sequence::new(vec_of_erased![
                        Ref::keyword("SYSID"),
                        Ref::new("NumericLiteralSegment"),
                    ]),
                ])
                .config(|this| this.optional()),
            ])
            .config(|this| this.optional()),
        ])
        .to_matchable(),
    );

    postgres.add([(
        "AlterRoleStatementSegment".into(),
        NodeMatcher::new(
            SyntaxKind::AlterRoleStatement,
            Sequence::new(vec_of_erased![
                Ref::keyword("ALTER"),
                one_of(vec_of_erased![Ref::keyword("ROLE"), Ref::keyword("USER"),]),
                one_of(vec_of_erased![
                    // role_specification
                    Sequence::new(vec_of_erased![
                        one_of(vec_of_erased![
                            Ref::keyword("CURRENT_ROLE"),
                            Ref::keyword("CURRENT_USER"),
                            Ref::keyword("SESSION_USER"),
                            Ref::new("RoleReferenceSegment"),
                        ]),
                        Ref::keyword("WITH").optional(),
                        any_set_of(vec_of_erased![
                            one_of(vec_of_erased![
                                Ref::keyword("SUPERUSER"),
                                Ref::keyword("NOSUPERUSER"),
                            ]),
                            one_of(vec_of_erased![
                                Ref::keyword("CREATEDB"),
                                Ref::keyword("NOCREATEDB"),
                            ]),
                            one_of(vec_of_erased![
                                Ref::keyword("CREATEROLE"),
                                Ref::keyword("NOCREATEROLE"),
                            ]),
                            one_of(vec_of_erased![
                                Ref::keyword("INHERIT"),
                                Ref::keyword("NOINHERIT"),
                            ]),
                            one_of(vec_of_erased![
                                Ref::keyword("LOGIN"),
                                Ref::keyword("NOLOGIN"),
                            ]),
                            one_of(vec_of_erased![
                                Ref::keyword("REPLICATION"),
                                Ref::keyword("NOREPLICATION"),
                            ]),
                            one_of(vec_of_erased![
                                Ref::keyword("BYPASSRLS"),
                                Ref::keyword("NOBYPASSRLS"),
                            ]),
                            Sequence::new(vec_of_erased![
                                Ref::keyword("CONNECTION"),
                                Ref::keyword("LIMIT"),
                                Ref::new("NumericLiteralSegment"),
                            ]),
                            Sequence::new(vec_of_erased![
                                Ref::keyword("ENCRYPTED").optional(),
                                Ref::keyword("PASSWORD"),
                                one_of(vec_of_erased![
                                    Ref::new("QuotedLiteralSegment"),
                                    Ref::keyword("NULL"),
                                ]),
                            ]),
                            Sequence::new(vec_of_erased![
                                Ref::keyword("VALID"),
                                Ref::keyword("UNTIL"),
                                Ref::new("QuotedLiteralSegment"),
                            ]),
                        ]),
                    ]),
                    // name only
                    Sequence::new(vec_of_erased![
                        Ref::new("RoleReferenceSegment"),
                        Sequence::new(vec_of_erased![
                            Ref::keyword("RENAME"),
                            Ref::keyword("TO"),
                            Ref::new("RoleReferenceSegment"),
                        ]),
                    ]),
                    // role_specification | all
                    Sequence::new(vec_of_erased![
                        one_of(vec_of_erased![
                            Ref::keyword("CURRENT_ROLE"),
                            Ref::keyword("CURRENT_USER"),
                            Ref::keyword("SESSION_USER"),
                            Ref::keyword("ALL"),
                            Ref::new("RoleReferenceSegment"),
                        ]),
                        Sequence::new(vec_of_erased![
                            Ref::keyword("IN"),
                            Ref::keyword("DATABASE"),
                            Ref::new("DatabaseReferenceSegment"),
                        ])
                        .config(|this| this.optional()),
                        one_of(vec_of_erased![
                            Sequence::new(vec_of_erased![
                                Ref::keyword("SET"),
                                Ref::new("ParameterNameSegment"),
                                one_of(vec_of_erased![
                                    Sequence::new(vec_of_erased![
                                        one_of(vec_of_erased![
                                            Ref::keyword("TO"),
                                            Ref::new("EqualsSegment"),
                                        ]),
                                        one_of(vec_of_erased![
                                            Ref::keyword("DEFAULT"),
                                            Delimited::new(vec_of_erased![
                                                Ref::new("LiteralGrammar"),
                                                Ref::new("NakedIdentifierSegment"),
                                                Ref::new("OnKeywordAsIdentifierSegment"),
                                            ]),
                                        ]),
                                    ]),
                                    Sequence::new(vec_of_erased![
                                        Ref::keyword("FROM"),
                                        Ref::keyword("CURRENT"),
                                    ]),
                                ]),
                            ]),
                            Sequence::new(vec_of_erased![
                                Ref::keyword("RESET"),
                                one_of(vec_of_erased![
                                    Ref::new("ParameterNameSegment"),
                                    Ref::keyword("ALL"),
                                ]),
                            ]),
                        ]),
                    ]),
                ]),
            ])
            .to_matchable(),
        )
        .to_matchable()
        .into(),
    )]);

    postgres.replace_grammar(
        "ExplainStatementSegment",
        Sequence::new(vec_of_erased![
            Ref::keyword("EXPLAIN"),
            one_of(vec_of_erased![
                Sequence::new(vec_of_erased![
                    one_of(vec_of_erased![
                        Ref::keyword("ANALYZE").optional(),
                        Ref::keyword("ANALYSE").optional(),
                    ]),
                    Ref::keyword("VERBOSE").optional(),
                ]),
                Bracketed::new(vec_of_erased![Delimited::new(vec_of_erased![Ref::new(
                    "ExplainOptionSegment"
                )])]),
            ])
            .config(|this| this.optional()),
            ansi::explainable_stmt(),
        ])
        .to_matchable(),
    );

    postgres.add([(
        "ExplainOptionSegment".into(),
        NodeMatcher::new(
            SyntaxKind::ExplainOption,
            one_of(vec_of_erased![
                Sequence::new(vec_of_erased![
                    one_of(vec_of_erased![
                        Ref::keyword("ANALYZE"),
                        Ref::keyword("ANALYSE"),
                        Ref::keyword("VERBOSE"),
                        Ref::keyword("COSTS"),
                        Ref::keyword("SETTINGS"),
                        Ref::keyword("BUFFERS"),
                        Ref::keyword("WAL"),
                        Ref::keyword("TIMING"),
                        Ref::keyword("SUMMARY"),
                    ]),
                    Ref::new("BooleanLiteralGrammar").optional(),
                ]),
                Sequence::new(vec_of_erased![
                    Ref::keyword("FORMAT"),
                    one_of(vec_of_erased![
                        Ref::keyword("TEXT"),
                        Ref::keyword("XML"),
                        Ref::keyword("JSON"),
                        Ref::keyword("YAML"),
                    ]),
                ]),
            ])
            .to_matchable(),
        )
        .to_matchable()
        .into(),
    )]);

    postgres.replace_grammar(
        "CreateSchemaStatementSegment",
        Sequence::new(vec_of_erased![
            Ref::keyword("CREATE"),
            Ref::keyword("SCHEMA"),
            Ref::new("IfNotExistsGrammar").optional(),
            one_of(vec_of_erased![
                Sequence::new(vec_of_erased![
                    Ref::new("SchemaReferenceSegment").optional(),
                    Ref::keyword("AUTHORIZATION"),
                    Ref::new("RoleReferenceSegment"),
                ]),
                Ref::new("SchemaReferenceSegment"),
            ]),
        ])
        .to_matchable(),
    );

    postgres.replace_grammar(
        "CreateTableStatementSegment",
        Sequence::new(vec_of_erased![
            Ref::keyword("CREATE"),
            one_of(vec_of_erased![
                Sequence::new(vec_of_erased![
                    one_of(vec_of_erased![
                        Ref::keyword("GLOBAL"),
                        Ref::keyword("LOCAL"),
                    ])
                    .config(|this| this.optional()),
                    Ref::new("TemporaryGrammar").optional(),
                ]),
                Ref::keyword("UNLOGGED"),
            ])
            .config(|this| this.optional()),
            Ref::keyword("TABLE"),
            Ref::new("IfNotExistsGrammar").optional(),
            Ref::new("TableReferenceSegment"),
            one_of(vec_of_erased![
                Sequence::new(vec_of_erased![
                    Bracketed::new(vec_of_erased![Delimited::new(vec_of_erased![one_of(
                        vec_of_erased![
                            Sequence::new(vec_of_erased![
                                Ref::new("ColumnReferenceSegment"),
                                Ref::new("DatatypeSegment"),
                                AnyNumberOf::new(vec_of_erased![one_of(vec_of_erased![
                                    Ref::new("ColumnConstraintSegment"),
                                    Sequence::new(vec_of_erased![
                                        Ref::keyword("COLLATE"),
                                        Ref::new("CollationReferenceSegment"),
                                    ]),
                                ]),]),
                            ]),
                            Ref::new("TableConstraintSegment"),
                            Sequence::new(vec_of_erased![
                                Ref::keyword("LIKE"),
                                Ref::new("TableReferenceSegment"),
                                AnyNumberOf::new(vec_of_erased![Ref::new("LikeOptionSegment"),])
                                    .config(|this| this.optional()),
                            ]),
                        ]
                    ),])
                    .config(|this| this.optional()),]),
                    Sequence::new(vec_of_erased![
                        Ref::keyword("INHERITS"),
                        Bracketed::new(vec_of_erased![Delimited::new(vec_of_erased![Ref::new(
                            "TableReferenceSegment"
                        ),]),]),
                    ])
                    .config(|this| this.optional()),
                ]),
                Sequence::new(vec_of_erased![
                    Ref::keyword("OF"),
                    Ref::new("ParameterNameSegment"),
                    Bracketed::new(vec_of_erased![Delimited::new(vec_of_erased![
                        Sequence::new(vec_of_erased![
                            Ref::new("ColumnReferenceSegment"),
                            Sequence::new(vec_of_erased![
                                Ref::keyword("WITH"),
                                Ref::keyword("OPTIONS"),
                            ])
                            .config(|this| this.optional()),
                            AnyNumberOf::new(vec_of_erased![Ref::new("ColumnConstraintSegment"),]),
                        ]),
                        Ref::new("TableConstraintSegment"),
                    ])
                    .config(|this| this.optional()),]),
                ]),
                Sequence::new(vec_of_erased![
                    Ref::keyword("PARTITION"),
                    Ref::keyword("OF"),
                    Ref::new("TableReferenceSegment"),
                    Bracketed::new(vec_of_erased![Delimited::new(vec_of_erased![
                        Sequence::new(vec_of_erased![
                            Ref::new("ColumnReferenceSegment"),
                            Sequence::new(vec_of_erased![
                                Ref::keyword("WITH"),
                                Ref::keyword("OPTIONS"),
                            ])
                            .config(|this| this.optional()),
                            AnyNumberOf::new(vec_of_erased![Ref::new("ColumnConstraintSegment"),]),
                        ]),
                        Ref::new("TableConstraintSegment"),
                    ]),])
                    .config(|this| this.optional()),
                    one_of(vec_of_erased![
                        Sequence::new(vec_of_erased![
                            Ref::keyword("FOR"),
                            Ref::keyword("VALUES"),
                            Ref::new("PartitionBoundSpecSegment"),
                        ]),
                        Ref::keyword("DEFAULT"),
                    ]),
                ]),
            ]),
            AnyNumberOf::new(vec_of_erased![
                Sequence::new(vec_of_erased![
                    Ref::keyword("PARTITION"),
                    Ref::keyword("BY"),
                    one_of(vec_of_erased![
                        Ref::keyword("RANGE"),
                        Ref::keyword("LIST"),
                        Ref::keyword("HASH"),
                    ]),
                    Bracketed::new(vec_of_erased![AnyNumberOf::new(vec_of_erased![
                        Delimited::new(vec_of_erased![Sequence::new(vec_of_erased![
                            one_of(vec_of_erased![
                                Ref::new("ColumnReferenceSegment"),
                                Ref::new("FunctionSegment"),
                            ]),
                            AnyNumberOf::new(vec_of_erased![
                                Sequence::new(vec_of_erased![
                                    Ref::keyword("COLLATE"),
                                    Ref::new("CollationReferenceSegment"),
                                ])
                                .config(|this| this.optional()),
                                Ref::new("ParameterNameSegment").optional(),
                            ]),
                        ]),]),
                    ]),]),
                ]),
                Sequence::new(vec_of_erased![
                    Ref::keyword("USING"),
                    Ref::new("ParameterNameSegment"),
                ]),
                one_of(vec_of_erased![
                    Sequence::new(vec_of_erased![
                        Ref::keyword("WITH"),
                        Ref::new("RelationOptionsSegment"),
                    ]),
                    Sequence::new(vec_of_erased![
                        Ref::keyword("WITHOUT"),
                        Ref::keyword("OIDS"),
                    ]),
                ]),
                Sequence::new(vec_of_erased![
                    Ref::keyword("ON"),
                    Ref::keyword("COMMIT"),
                    one_of(vec_of_erased![
                        Sequence::new(vec_of_erased![
                            Ref::keyword("PRESERVE"),
                            Ref::keyword("ROWS"),
                        ]),
                        Sequence::new(
                            vec_of_erased![Ref::keyword("DELETE"), Ref::keyword("ROWS"),]
                        ),
                        Ref::keyword("DROP"),
                    ]),
                ]),
                Sequence::new(vec_of_erased![
                    Ref::keyword("TABLESPACE"),
                    Ref::new("TablespaceReferenceSegment"),
                ]),
            ]),
        ])
        .to_matchable(),
    );

    postgres.add([(
        "CreateTableAsStatementSegment".into(),
        NodeMatcher::new(
            SyntaxKind::CreateTableAsStatement,
            Sequence::new(vec_of_erased![
                Ref::keyword("CREATE"),
                one_of(vec_of_erased![
                    Sequence::new(vec_of_erased![
                        one_of(vec_of_erased![
                            Ref::keyword("GLOBAL"),
                            Ref::keyword("LOCAL")
                        ])
                        .config(|this| this.optional()),
                        Ref::new("TemporaryGrammar"),
                    ]),
                    Ref::keyword("UNLOGGED"),
                ])
                .config(|this| this.optional()),
                Ref::keyword("TABLE"),
                Ref::new("IfNotExistsGrammar").optional(),
                Ref::new("TableReferenceSegment"),
                AnyNumberOf::new(vec_of_erased![
                    Sequence::new(vec_of_erased![Bracketed::new(vec_of_erased![
                        Delimited::new(vec_of_erased![Ref::new("ColumnReferenceSegment"),])
                    ])])
                    .config(|this| this.optional()),
                    Sequence::new(vec_of_erased![
                        Ref::keyword("USING"),
                        Ref::new("ParameterNameSegment"),
                    ])
                    .config(|this| this.optional()),
                    one_of(vec_of_erased![
                        Sequence::new(vec_of_erased![
                            Ref::keyword("WITH"),
                            Bracketed::new(vec_of_erased![Delimited::new(vec_of_erased![
                                Sequence::new(vec_of_erased![
                                    Ref::new("ParameterNameSegment"),
                                    Sequence::new(vec_of_erased![
                                        Ref::new("EqualsSegment"),
                                        one_of(vec_of_erased![
                                            Ref::new("LiteralGrammar"),
                                            Ref::new("NakedIdentifierSegment"),
                                        ]),
                                    ])
                                    .config(|this| this.optional()),
                                ]),
                            ])]),
                        ]),
                        Sequence::new(vec_of_erased![
                            Ref::keyword("WITHOUT"),
                            Ref::keyword("OIDS")
                        ]),
                    ])
                    .config(|this| this.optional()),
                    Sequence::new(vec_of_erased![
                        Ref::keyword("ON"),
                        Ref::keyword("COMMIT"),
                        one_of(vec_of_erased![
                            Sequence::new(vec_of_erased![
                                Ref::keyword("PRESERVE"),
                                Ref::keyword("ROWS"),
                            ]),
                            Sequence::new(vec_of_erased![
                                Ref::keyword("DELETE"),
                                Ref::keyword("ROWS")
                            ]),
                            Ref::keyword("DROP"),
                        ]),
                    ])
                    .config(|this| this.optional()),
                    Sequence::new(vec_of_erased![
                        Ref::keyword("TABLESPACE"),
                        Ref::new("TablespaceReferenceSegment"),
                    ])
                    .config(|this| this.optional()),
                ]),
                Ref::keyword("AS"),
                one_of(vec_of_erased![
                    optionally_bracketed(vec_of_erased![Ref::new("SelectableGrammar"),]),
                    optionally_bracketed(vec_of_erased![Sequence::new(vec_of_erased![
                        Ref::keyword("TABLE"),
                        Ref::new("TableReferenceSegment"),
                    ])]),
                    Ref::new("ValuesClauseSegment"),
                    optionally_bracketed(vec_of_erased![Sequence::new(vec_of_erased![
                        Ref::keyword("EXECUTE"),
                        Ref::new("FunctionSegment"),
                    ])]),
                ]),
                Ref::new("WithDataClauseSegment").optional(),
            ])
            .to_matchable(),
        )
        .to_matchable()
        .into(),
    )]);

    // A `ALTER AGGREGATE` statement.
    // https://www.postgresql.org/docs/current/sql-alteraggregate.html
    postgres.add([(
        "AlterAggregateStatementSegment".into(),
        Sequence::new(vec_of_erased![
            Ref::keyword("ALTER"),
            Ref::keyword("AGGREGATE"),
            Ref::new("ObjectReferenceSegment"),
            Bracketed::new(vec_of_erased![one_of(vec_of_erased![
                Ref::new("FunctionParameterListGrammar"),
                Anything::new(),
                Ref::new("StarSegment"),
            ])]),
            one_of(vec_of_erased![
                Sequence::new(vec_of_erased![
                    Ref::keyword("RENAME"),
                    Ref::keyword("TO"),
                    Ref::new("FunctionNameSegment"),
                ]),
                Sequence::new(vec_of_erased![
                    Ref::keyword("OWNER"),
                    Ref::keyword("TO"),
                    one_of(vec_of_erased![
                        Ref::keyword("CURRENT_ROLE"),
                        Ref::keyword("CURRENT_USER"),
                        Ref::keyword("SESSION_USER"),
                        Ref::new("RoleReferenceSegment"),
                    ])
                ]),
                Sequence::new(vec_of_erased![
                    Ref::keyword("SET"),
                    Ref::keyword("SCHEMA"),
                    Ref::new("SchemaReferenceSegment"),
                ])
            ])
        ])
        .to_matchable()
        .into(),
    )]);

    postgres.replace_grammar(
        "AlterTableStatementSegment",
        Sequence::new(vec_of_erased![
            Ref::keyword("ALTER"),
            Ref::keyword("TABLE"),
            one_of(vec_of_erased![
                Sequence::new(vec_of_erased![
                    Ref::new("IfExistsGrammar").optional(),
                    Ref::keyword("ONLY").optional(),
                    Ref::new("TableReferenceSegment"),
                    Ref::new("StarSegment").optional(),
                    one_of(vec_of_erased![
                        Delimited::new(vec_of_erased![Ref::new("AlterTableActionSegment")]),
                        Sequence::new(vec_of_erased![
                            Ref::keyword("RENAME"),
                            Ref::keyword("COLUMN").optional(),
                            Ref::new("ColumnReferenceSegment"),
                            Ref::keyword("TO"),
                            Ref::new("ColumnReferenceSegment"),
                        ]),
                        Sequence::new(vec_of_erased![
                            Ref::keyword("RENAME"),
                            Ref::keyword("CONSTRAINT"),
                            Ref::new("ParameterNameSegment"),
                            Ref::keyword("TO"),
                            Ref::new("ParameterNameSegment"),
                        ]),
                    ]),
                ]),
                Sequence::new(vec_of_erased![
                    Ref::new("IfExistsGrammar").optional(),
                    Ref::new("TableReferenceSegment"),
                    one_of(vec_of_erased![
                        Sequence::new(vec_of_erased![
                            Ref::keyword("RENAME"),
                            Ref::keyword("TO"),
                            Ref::new("TableReferenceSegment"),
                        ]),
                        Sequence::new(vec_of_erased![
                            Ref::keyword("SET"),
                            Ref::keyword("SCHEMA"),
                            Ref::new("SchemaReferenceSegment"),
                        ]),
                        Sequence::new(vec_of_erased![
                            Ref::keyword("ATTACH"),
                            Ref::keyword("PARTITION"),
                            Ref::new("ParameterNameSegment"),
                            one_of(vec_of_erased![
                                Sequence::new(vec_of_erased![
                                    Ref::keyword("FOR"),
                                    Ref::keyword("VALUES"),
                                    Ref::new("PartitionBoundSpecSegment"),
                                ]),
                                Ref::keyword("DEFAULT"),
                            ]),
                        ]),
                        Sequence::new(vec_of_erased![
                            Ref::keyword("DETACH"),
                            Ref::keyword("PARTITION"),
                            Ref::new("ParameterNameSegment"),
                            Ref::keyword("CONCURRENTLY").optional(),
                            Ref::keyword("FINALIZE").optional(),
                        ]),
                    ]),
                ]),
                Sequence::new(vec_of_erased![
                    Ref::keyword("ALL"),
                    Ref::keyword("IN"),
                    Ref::keyword("TABLESPACE"),
                    Ref::new("TablespaceReferenceSegment"),
                    Sequence::new(vec_of_erased![
                        Ref::keyword("OWNED"),
                        Ref::keyword("BY"),
                        Delimited::new(vec_of_erased![Ref::new("ObjectReferenceSegment")])
                            .config(|this| this.optional()),
                    ]),
                    Ref::keyword("SET"),
                    Ref::keyword("TABLESPACE"),
                    Ref::new("TablespaceReferenceSegment"),
                    Ref::keyword("NOWAIT").optional(),
                ]),
            ]),
        ])
        .to_matchable(),
    );

    postgres.add([
        (
            "AlterTableActionSegment".into(),
            NodeMatcher::new(
                SyntaxKind::AlterTableActionSegment,
                one_of(vec_of_erased![
                    Sequence::new(vec_of_erased![
                        Ref::keyword("ADD"),
                        Ref::keyword("COLUMN").optional(),
                        Ref::new("IfNotExistsGrammar").optional(),
                        Ref::new("ColumnReferenceSegment"),
                        Ref::new("DatatypeSegment"),
                        Sequence::new(vec_of_erased![
                            Ref::keyword("COLLATE"),
                            Ref::new("CollationReferenceSegment"),
                        ])
                        .config(|this| this.optional()),
                        AnyNumberOf::new(vec_of_erased![Ref::new("ColumnConstraintSegment")]),
                    ]),
                    Sequence::new(vec_of_erased![
                        Ref::keyword("DROP"),
                        Ref::keyword("COLUMN").optional(),
                        Ref::new("IfExistsGrammar").optional(),
                        Ref::new("ColumnReferenceSegment"),
                        Ref::new("DropBehaviorGrammar").optional(),
                    ]),
                    Sequence::new(vec_of_erased![
                        Ref::keyword("ALTER"),
                        Ref::keyword("COLUMN").optional(),
                        Ref::new("ColumnReferenceSegment"),
                        one_of(vec_of_erased![
                            Sequence::new(vec_of_erased![
                                Sequence::new(vec_of_erased![
                                    Ref::keyword("SET"),
                                    Ref::keyword("DATA")
                                ])
                                .config(|this| this.optional()),
                                Ref::keyword("TYPE"),
                                Ref::new("DatatypeSegment"),
                                Sequence::new(vec_of_erased![
                                    Ref::keyword("COLLATE"),
                                    Ref::new("CollationReferenceSegment"),
                                ])
                                .config(|this| this.optional()),
                                Sequence::new(vec_of_erased![
                                    Ref::keyword("USING"),
                                    one_of(vec_of_erased![Ref::new("ExpressionSegment")]),
                                ])
                                .config(|this| this.optional()),
                            ]),
                            Sequence::new(vec_of_erased![
                                Ref::keyword("SET"),
                                Ref::keyword("DEFAULT"),
                                one_of(vec_of_erased![
                                    Ref::new("LiteralGrammar"),
                                    Ref::new("FunctionSegment"),
                                    Ref::new("BareFunctionSegment"),
                                    Ref::new("ExpressionSegment"),
                                ]),
                            ]),
                            Sequence::new(vec_of_erased![
                                Ref::keyword("DROP"),
                                Ref::keyword("DEFAULT")
                            ]),
                            Sequence::new(vec_of_erased![
                                one_of(vec_of_erased![Ref::keyword("SET"), Ref::keyword("DROP")])
                                    .config(|this| this.optional()),
                                Ref::keyword("NOT"),
                                Ref::keyword("NULL"),
                            ]),
                            Sequence::new(vec_of_erased![
                                Ref::keyword("DROP"),
                                Ref::keyword("EXPRESSION"),
                                Ref::new("IfExistsGrammar").optional(),
                            ]),
                            Sequence::new(vec_of_erased![
                                Ref::keyword("ADD"),
                                Ref::keyword("GENERATED"),
                                one_of(vec_of_erased![
                                    Ref::keyword("ALWAYS"),
                                    Sequence::new(vec_of_erased![
                                        Ref::keyword("BY"),
                                        Ref::keyword("DEFAULT"),
                                    ]),
                                ]),
                                Ref::keyword("AS"),
                                Ref::keyword("IDENTITY"),
                                Bracketed::new(vec_of_erased![AnyNumberOf::new(vec_of_erased![
                                    Ref::new("AlterSequenceOptionsSegment")
                                ])
                                .config(|this| this.optional()),]),
                            ]),
                            Sequence::new(vec_of_erased![one_of(vec_of_erased![
                                Sequence::new(vec_of_erased![
                                    Ref::keyword("SET"),
                                    Ref::keyword("GENERATED"),
                                    one_of(vec_of_erased![
                                        Ref::keyword("ALWAYS"),
                                        Sequence::new(vec_of_erased![
                                            Ref::keyword("BY"),
                                            Ref::keyword("DEFAULT"),
                                        ]),
                                    ]),
                                ]),
                                Sequence::new(vec_of_erased![
                                    Ref::keyword("SET"),
                                    Ref::new("AlterSequenceOptionsSegment"),
                                ]),
                                Sequence::new(vec_of_erased![
                                    Ref::keyword("RESTART"),
                                    Sequence::new(vec_of_erased![
                                        Ref::keyword("WITH"),
                                        Ref::new("NumericLiteralSegment"),
                                    ]),
                                ]),
                            ]),]),
                            Sequence::new(vec_of_erased![
                                Ref::keyword("DROP"),
                                Ref::keyword("IDENTITY"),
                                Ref::new("IfExistsGrammar").optional(),
                            ]),
                            Sequence::new(vec_of_erased![
                                Ref::keyword("SET"),
                                Ref::keyword("STATISTICS"),
                                Ref::new("NumericLiteralSegment"),
                            ]),
                            Sequence::new(vec_of_erased![
                                Ref::keyword("SET"),
                                Ref::new("RelationOptionsSegment"),
                            ]),
                            Sequence::new(vec_of_erased![
                                Ref::keyword("RESET"),
                                Ref::new("RelationOptionsSegment"),
                            ]),
                            Sequence::new(vec_of_erased![
                                Ref::keyword("SET"),
                                Ref::keyword("STORAGE"),
                                one_of(vec_of_erased![
                                    Ref::keyword("PLAIN"),
                                    Ref::keyword("EXTERNAL"),
                                    Ref::keyword("EXTENDED"),
                                    Ref::keyword("MAIN"),
                                ]),
                            ]),
                        ]),
                    ]),
                    Sequence::new(vec_of_erased![
                        Ref::keyword("ADD"),
                        Ref::new("TableConstraintSegment"),
                    ]),
                    Sequence::new(vec_of_erased![
                        Ref::keyword("ADD"),
                        Ref::new("TableConstraintUsingIndexSegment"),
                    ]),
                    Sequence::new(vec_of_erased![
                        Ref::keyword("ALTER"),
                        Ref::keyword("CONSTRAINT"),
                        Ref::new("ParameterNameSegment"),
                        one_of(vec_of_erased![
                            Ref::keyword("DEFERRABLE"),
                            Sequence::new(vec_of_erased![
                                Ref::keyword("NOT"),
                                Ref::keyword("DEFERRABLE"),
                            ])
                        ])
                        .config(|this| this.optional()),
                        one_of(vec_of_erased![
                            Sequence::new(vec_of_erased![
                                Ref::keyword("INITIALLY"),
                                Ref::keyword("DEFERRED"),
                            ]),
                            Sequence::new(vec_of_erased![
                                Ref::keyword("INITIALLY"),
                                Ref::keyword("IMMEDIATE"),
                            ]),
                        ])
                        .config(|this| this.optional()),
                    ]),
                    Sequence::new(vec_of_erased![
                        Ref::keyword("VALIDATE"),
                        Ref::keyword("CONSTRAINT"),
                        Ref::new("ParameterNameSegment")
                    ]),
                    Sequence::new(vec_of_erased![
                        Ref::keyword("DROP"),
                        Ref::keyword("CONSTRAINT"),
                        Ref::new("IfExistsGrammar").optional(),
                        Ref::new("ParameterNameSegment"),
                        Ref::new("DropBehaviorGrammar").optional(),
                    ]),
                    Sequence::new(vec_of_erased![
                        one_of(vec_of_erased![
                            Ref::keyword("ENABLE"),
                            Ref::keyword("DISABLE"),
                        ]),
                        Ref::keyword("TRIGGER"),
                        one_of(vec_of_erased![
                            Ref::new("ParameterNameSegment"),
                            Ref::keyword("ALL"),
                            Ref::keyword("USER"),
                        ]),
                    ]),
                    Sequence::new(vec_of_erased![
                        Ref::keyword("ENABLE"),
                        one_of(vec_of_erased![
                            Ref::keyword("REPLICA"),
                            Ref::keyword("ALWAYS"),
                        ]),
                        Ref::keyword("TRIGGER"),
                        Ref::new("ParameterNameSegment"),
                    ]),
                    Sequence::new(vec_of_erased![
                        one_of(vec_of_erased![
                            Ref::keyword("ENABLE"),
                            Ref::keyword("DISABLE"),
                            Sequence::new(vec_of_erased![
                                Ref::keyword("ENABLE"),
                                Ref::keyword("REPLICA"),
                            ]),
                            Sequence::new(vec_of_erased![
                                Ref::keyword("ENABLE"),
                                Ref::keyword("RULE"),
                            ]),
                        ]),
                        Ref::keyword("RULE"),
                        Ref::new("ParameterNameSegment"),
                    ]),
                    Sequence::new(vec_of_erased![
                        one_of(vec_of_erased![
                            Ref::keyword("DISABLE"),
                            Ref::keyword("ENABLE"),
                            Ref::keyword("FORCE"),
                            Sequence::new(vec_of_erased![
                                Ref::keyword("NO"),
                                Ref::keyword("FORCE"),
                            ]),
                        ]),
                        Ref::keyword("ROW"),
                        Ref::keyword("LEVEL"),
                        Ref::keyword("SECURITY"),
                    ]),
                    Sequence::new(vec_of_erased![
                        Ref::keyword("CLUSTER"),
                        Ref::keyword("ON"),
                        Ref::new("ParameterNameSegment"),
                    ]),
                    Sequence::new(vec_of_erased![
                        Ref::keyword("SET"),
                        Ref::keyword("WITHOUT"),
                        one_of(vec_of_erased![
                            Ref::keyword("CLUSTER"),
                            Ref::keyword("OIDS"),
                        ]),
                    ]),
                    Sequence::new(vec_of_erased![
                        Ref::keyword("SET"),
                        Ref::keyword("TABLESPACE"),
                        Ref::new("TablespaceReferenceSegment"),
                    ]),
                    Sequence::new(vec_of_erased![
                        Ref::keyword("SET"),
                        one_of(vec_of_erased![
                            Ref::keyword("LOGGED"),
                            Ref::keyword("UNLOGGED"),
                        ]),
                    ]),
                    Sequence::new(vec_of_erased![
                        Ref::keyword("SET"),
                        Ref::new("RelationOptionsSegment"),
                    ]),
                    Sequence::new(vec_of_erased![
                        Ref::keyword("RESET"),
                        Ref::new("RelationOptionsSegment"),
                    ]),
                    Sequence::new(vec_of_erased![
                        Ref::keyword("NO").optional(),
                        Ref::keyword("INHERIT"),
                        Ref::new("TableReferenceSegment"),
                    ]),
                    Sequence::new(vec_of_erased![
                        Ref::keyword("OF"),
                        Ref::new("ParameterNameSegment"),
                    ]),
                    Sequence::new(vec_of_erased![Ref::keyword("NOT"), Ref::keyword("OF"),]),
                    Sequence::new(vec_of_erased![
                        Ref::keyword("OWNER"),
                        Ref::keyword("TO"),
                        one_of(vec_of_erased![
                            Ref::new("ParameterNameSegment"),
                            Ref::keyword("CURRENT_ROLE"),
                            Ref::keyword("CURRENT_USER"),
                            Ref::keyword("SESSION_USER"),
                        ]),
                    ]),
                    Sequence::new(vec_of_erased![
                        Ref::keyword("REPLICA"),
                        Ref::keyword("IDENTITY"),
                        one_of(vec_of_erased![
                            Ref::keyword("DEFAULT"),
                            Sequence::new(vec_of_erased![
                                Ref::keyword("USING"),
                                Ref::keyword("INDEX"),
                                Ref::new("IndexReferenceSegment"),
                            ]),
                            Ref::keyword("FULL"),
                            Ref::keyword("NOTHING"),
                        ]),
                    ]),
                ])
                .to_matchable(),
            )
            .to_matchable()
            .into(),
        ),
        (
            "VersionIdentifierSegment".into(),
            NodeMatcher::new(
                SyntaxKind::VersionIdentifier,
                one_of(vec_of_erased![
                    Ref::new("QuotedLiteralSegment"),
                    Ref::new("NakedIdentifierSegment"),
                ])
                .to_matchable(),
            )
            .to_matchable()
            .into(),
        ),
        (
            "CreateExtensionStatementSegment".into(),
            NodeMatcher::new(
                SyntaxKind::CreateExtensionStatement,
                Sequence::new(vec_of_erased![
                    Ref::keyword("CREATE"),
                    Ref::keyword("EXTENSION"),
                    Ref::new("IfNotExistsGrammar").optional(),
                    Ref::new("ExtensionReferenceSegment"),
                    Ref::keyword("WITH").optional(),
                    Sequence::new(vec_of_erased![
                        Ref::keyword("SCHEMA"),
                        Ref::new("SchemaReferenceSegment"),
                    ])
                    .config(|this| this.optional()),
                    Sequence::new(vec_of_erased![
                        Ref::keyword("VERSION"),
                        Ref::new("VersionIdentifierSegment"),
                    ])
                    .config(|this| this.optional()),
                    Sequence::new(vec_of_erased![
                        Ref::keyword("FROM"),
                        Ref::new("VersionIdentifierSegment"),
                    ])
                    .config(|this| this.optional()),
                ])
                .to_matchable(),
            )
            .to_matchable()
            .into(),
        ),
        (
            "DropExtensionStatementSegment".into(),
            NodeMatcher::new(
                SyntaxKind::DropExtensionStatement,
                Sequence::new(vec_of_erased![
                    Ref::keyword("DROP"),
                    Ref::keyword("EXTENSION"),
                    Ref::new("IfExistsGrammar").optional(),
                    Ref::new("ExtensionReferenceSegment"),
                    Ref::new("DropBehaviorGrammar").optional(),
                ])
                .to_matchable(),
            )
            .to_matchable()
            .into(),
        ),
        (
            "PublicationReferenceSegment".into(),
            NodeMatcher::new(
                SyntaxKind::PublicationReference,
                Ref::new("SingleIdentifierGrammar").to_matchable(),
            )
            .to_matchable()
            .into(),
        ),
        (
            "PublicationTableSegment".into(),
            NodeMatcher::new(
                SyntaxKind::PublicationTable,
                Sequence::new(vec_of_erased![
                    Ref::new("ExtendedTableReferenceGrammar"),
                    Ref::new("BracketedColumnReferenceListGrammar").optional(),
                    Sequence::new(vec_of_erased![
                        Ref::keyword("WHERE"),
                        Bracketed::new(vec_of_erased![Ref::new("ExpressionSegment")]),
                    ])
                    .config(|this| this.optional()),
                ])
                .to_matchable(),
            )
            .to_matchable()
            .into(),
        ),
        (
            "PublicationObjectsSegment".into(),
            NodeMatcher::new(
                SyntaxKind::PublicationObjects,
                one_of(vec_of_erased![
                    Sequence::new(vec_of_erased![
                        Ref::keyword("TABLE"),
                        Delimited::new(vec_of_erased![Ref::new("PublicationTableSegment")]).config(
                            |this| {
                                this.terminators = vec_of_erased![Sequence::new(vec_of_erased![
                                    Ref::new("CommaSegment"),
                                    one_of(vec_of_erased![
                                        Ref::keyword("TABLE"),
                                        Ref::keyword("TABLES")
                                    ]),
                                ])];
                            }
                        ),
                    ]),
                    Sequence::new(vec_of_erased![
                        Ref::keyword("TABLES"),
                        Ref::keyword("IN"),
                        Ref::keyword("SCHEMA"),
                        Delimited::new(vec_of_erased![one_of(vec_of_erased![
                            Ref::new("SchemaReferenceSegment"),
                            Ref::keyword("CURRENT_SCHEMA"),
                        ]),])
                        .config(|this| {
                            this.terminators = vec_of_erased![Sequence::new(vec_of_erased![
                                Ref::new("CommaSegment"),
                                one_of(vec_of_erased![
                                    Ref::keyword("TABLE"),
                                    Ref::keyword("TABLES"),
                                ]),
                            ]),];
                        }),
                    ]),
                ])
                .to_matchable(),
            )
            .to_matchable()
            .into(),
        ),
        (
            "CreatePublicationStatementSegment".into(),
            NodeMatcher::new(
                SyntaxKind::CreatePublicationStatement,
                Sequence::new(vec_of_erased![
                    Ref::keyword("CREATE"),
                    Ref::keyword("PUBLICATION"),
                    Ref::new("PublicationReferenceSegment"),
                    one_of(vec_of_erased![
                        Sequence::new(vec_of_erased![
                            Ref::keyword("FOR"),
                            Ref::keyword("ALL"),
                            Ref::keyword("TABLES"),
                        ]),
                        Sequence::new(vec_of_erased![
                            Ref::keyword("FOR"),
                            Delimited::new(vec_of_erased![Ref::new("PublicationObjectsSegment"),]),
                        ]),
                    ])
                    .config(|this| this.optional()),
                    Sequence::new(vec_of_erased![
                        Ref::keyword("WITH"),
                        Ref::new("DefinitionParametersSegment"),
                    ])
                    .config(|this| this.optional()),
                ])
                .to_matchable(),
            )
            .to_matchable()
            .into(),
        ),
        (
            "AlterPublicationStatementSegment".into(),
            NodeMatcher::new(
                SyntaxKind::AlterPublicationStatement,
                Sequence::new(vec_of_erased![
                    Ref::keyword("ALTER"),
                    Ref::keyword("PUBLICATION"),
                    Ref::new("PublicationReferenceSegment"),
                    one_of(vec_of_erased![
                        Sequence::new(vec_of_erased![
                            Ref::keyword("SET"),
                            Ref::new("DefinitionParametersSegment"),
                        ]),
                        Sequence::new(vec_of_erased![
                            Ref::keyword("ADD"),
                            Delimited::new(vec_of_erased![Ref::new("PublicationObjectsSegment")]),
                        ]),
                        Sequence::new(vec_of_erased![
                            Ref::keyword("SET"),
                            Delimited::new(vec_of_erased![Ref::new("PublicationObjectsSegment")]),
                        ]),
                        Sequence::new(vec_of_erased![
                            Ref::keyword("DROP"),
                            Delimited::new(vec_of_erased![Ref::new("PublicationObjectsSegment")]),
                        ]),
                        Sequence::new(vec_of_erased![
                            Ref::keyword("RENAME"),
                            Ref::keyword("TO"),
                            Ref::new("PublicationReferenceSegment"),
                        ]),
                        Sequence::new(vec_of_erased![
                            Ref::keyword("OWNER"),
                            Ref::keyword("TO"),
                            one_of(vec_of_erased![
                                Ref::keyword("CURRENT_ROLE"),
                                Ref::keyword("CURRENT_USER"),
                                Ref::keyword("SESSION_USER"),
                                Ref::new("RoleReferenceSegment"),
                            ]),
                        ]),
                    ]),
                ])
                .to_matchable(),
            )
            .to_matchable()
            .into(),
        ),
    ]);

    postgres.add([
        (
            "DropPublicationStatementSegment".into(),
            NodeMatcher::new(
                SyntaxKind::DropPublicationStatement,
                Sequence::new(vec_of_erased![
                    Ref::keyword("DROP"),
                    Ref::keyword("PUBLICATION"),
                    Ref::new("IfExistsGrammar").optional(),
                    Delimited::new(vec_of_erased![Ref::new("PublicationReferenceSegment")]),
                    Ref::new("DropBehaviorGrammar").optional(),
                ])
                .to_matchable(),
            )
            .to_matchable()
            .into(),
        ),
        (
            "CreateMaterializedViewStatementSegment".into(),
            NodeMatcher::new(
                SyntaxKind::CreateMaterializedViewStatement,
                Sequence::new(vec_of_erased![
                    Ref::keyword("CREATE"),
                    Ref::new("OrReplaceGrammar").optional(),
                    Ref::keyword("MATERIALIZED"),
                    Ref::keyword("VIEW"),
                    Ref::new("IfNotExistsGrammar").optional(),
                    Ref::new("TableReferenceSegment"),
                    Ref::new("BracketedColumnReferenceListGrammar").optional(),
                    Sequence::new(vec_of_erased![
                        Ref::keyword("USING"),
                        Ref::new("ParameterNameSegment")
                    ])
                    .config(|this| this.optional()),
                    Sequence::new(vec_of_erased![
                        Ref::keyword("WITH"),
                        Ref::new("RelationOptionsSegment")
                    ])
                    .config(|this| this.optional()),
                    Sequence::new(vec_of_erased![
                        Ref::keyword("TABLESPACE"),
                        Ref::new("TablespaceReferenceSegment"),
                    ])
                    .config(|this| this.optional()),
                    Ref::keyword("AS"),
                    one_of(vec_of_erased![
                        optionally_bracketed(vec_of_erased![Ref::new("SelectableGrammar")]),
                        optionally_bracketed(vec_of_erased![Sequence::new(vec_of_erased![
                            Ref::keyword("TABLE"),
                            Ref::new("TableReferenceSegment"),
                        ])]),
                        Ref::new("ValuesClauseSegment"),
                        optionally_bracketed(vec_of_erased![Sequence::new(vec_of_erased![
                            Ref::keyword("EXECUTE"),
                            Ref::new("FunctionSegment"),
                        ])]),
                    ]),
                    Ref::new("WithDataClauseSegment").optional(),
                ])
                .to_matchable(),
            )
            .to_matchable()
            .into(),
        ),
        (
            "AlterMaterializedViewStatementSegment".into(),
            NodeMatcher::new(
                SyntaxKind::AlterMaterializedViewStatement,
                Sequence::new(vec_of_erased![
                    Ref::keyword("ALTER"),
                    Ref::keyword("MATERIALIZED"),
                    Ref::keyword("VIEW"),
                    one_of(vec_of_erased![
                        Sequence::new(vec_of_erased![
                            Ref::new("IfExistsGrammar").optional(),
                            Ref::new("TableReferenceSegment"),
                            one_of(vec_of_erased![
                                Delimited::new(vec_of_erased![Ref::new(
                                    "AlterMaterializedViewActionSegment"
                                )]),
                                Sequence::new(vec_of_erased![
                                    Ref::keyword("RENAME"),
                                    Sequence::new(vec_of_erased![Ref::keyword("COLUMN")])
                                        .config(|this| this.optional()),
                                    Ref::new("ColumnReferenceSegment"),
                                    Ref::keyword("TO"),
                                    Ref::new("ColumnReferenceSegment"),
                                ]),
                                Sequence::new(vec_of_erased![
                                    Ref::keyword("RENAME"),
                                    Ref::keyword("TO"),
                                    Ref::new("TableReferenceSegment"),
                                ]),
                                Sequence::new(vec_of_erased![
                                    Ref::keyword("SET"),
                                    Ref::keyword("SCHEMA"),
                                    Ref::new("SchemaReferenceSegment"),
                                ]),
                            ]),
                        ]),
                        Sequence::new(vec_of_erased![
                            Ref::new("TableReferenceSegment"),
                            Ref::keyword("NO").optional(),
                            Ref::keyword("DEPENDS"),
                            Ref::keyword("ON"),
                            Ref::keyword("EXTENSION"),
                            Ref::new("ExtensionReferenceSegment"),
                        ]),
                        Sequence::new(vec_of_erased![
                            Ref::keyword("ALL"),
                            Ref::keyword("IN"),
                            Ref::keyword("TABLESPACE"),
                            Ref::new("TablespaceReferenceSegment"),
                            Sequence::new(vec_of_erased![
                                Ref::keyword("OWNED"),
                                Ref::keyword("BY"),
                                Delimited::new(vec_of_erased![Ref::new("ObjectReferenceSegment")]),
                            ])
                            .config(|this| this.optional()),
                            Ref::keyword("SET"),
                            Ref::keyword("TABLESPACE"),
                            Ref::new("TablespaceReferenceSegment"),
                            Sequence::new(vec_of_erased![Ref::keyword("NOWAIT")])
                                .config(|this| this.optional()),
                        ]),
                    ]),
                ])
                .to_matchable(),
            )
            .to_matchable()
            .into(),
        ),
        (
            "AlterMaterializedViewActionSegment".into(),
            NodeMatcher::new(
                SyntaxKind::AlterMaterializedViewActionSegment,
                one_of(vec_of_erased![
                    Sequence::new(vec_of_erased![
                        Ref::keyword("ALTER"),
                        Ref::keyword("COLUMN").optional(),
                        Ref::new("ColumnReferenceSegment"),
                        one_of(vec_of_erased![
                            Sequence::new(vec_of_erased![
                                Ref::keyword("SET"),
                                Ref::keyword("STATISTICS"),
                                Ref::new("NumericLiteralSegment"),
                            ]),
                            Sequence::new(vec_of_erased![
                                Ref::keyword("SET"),
                                Bracketed::new(vec_of_erased![Delimited::new(vec_of_erased![
                                    Sequence::new(vec_of_erased![
                                        Ref::new("ParameterNameSegment"),
                                        Ref::new("EqualsSegment"),
                                        Ref::new("LiteralGrammar"),
                                    ]),
                                ])]),
                            ]),
                            Sequence::new(vec_of_erased![
                                Ref::keyword("RESET"),
                                Bracketed::new(vec_of_erased![Delimited::new(vec_of_erased![
                                    Ref::new("ParameterNameSegment")
                                ])]),
                            ]),
                            Sequence::new(vec_of_erased![
                                Ref::keyword("SET"),
                                Ref::keyword("STORAGE"),
                                one_of(vec_of_erased![
                                    Ref::keyword("PLAIN"),
                                    Ref::keyword("EXTERNAL"),
                                    Ref::keyword("EXTENDED"),
                                    Ref::keyword("MAIN"),
                                ]),
                            ]),
                            Sequence::new(vec_of_erased![
                                Ref::keyword("SET"),
                                Ref::keyword("COMPRESSION"),
                                Ref::new("ParameterNameSegment"),
                            ]),
                        ]),
                    ]),
                    Sequence::new(vec_of_erased![
                        Ref::keyword("CLUSTER"),
                        Ref::keyword("ON"),
                        Ref::new("ParameterNameSegment"),
                    ]),
                    Sequence::new(vec_of_erased![
                        Ref::keyword("SET"),
                        Ref::keyword("WITHOUT"),
                        Ref::keyword("CLUSTER"),
                    ]),
                    Sequence::new(vec_of_erased![
                        Ref::keyword("SET"),
                        Bracketed::new(vec_of_erased![Delimited::new(vec_of_erased![
                            Sequence::new(vec_of_erased![
                                Ref::new("ParameterNameSegment"),
                                Sequence::new(vec_of_erased![
                                    Ref::new("EqualsSegment"),
                                    Ref::new("LiteralGrammar"),
                                ])
                                .config(|this| this.optional()),
                            ])
                        ])]),
                    ]),
                    Sequence::new(vec_of_erased![
                        Ref::keyword("RESET"),
                        Bracketed::new(vec_of_erased![Delimited::new(vec_of_erased![Ref::new(
                            "ParameterNameSegment"
                        )])]),
                    ]),
                    Sequence::new(vec_of_erased![
                        Ref::keyword("OWNER"),
                        Ref::keyword("TO"),
                        one_of(vec_of_erased![
                            Ref::new("ObjectReferenceSegment"),
                            Ref::keyword("CURRENT_ROLE"),
                            Ref::keyword("CURRENT_USER"),
                            Ref::keyword("SESSION_USER"),
                        ]),
                    ]),
                ])
                .to_matchable(),
            )
            .to_matchable()
            .into(),
        ),
        (
            "RefreshMaterializedViewStatementSegment".into(),
            NodeMatcher::new(
                SyntaxKind::RefreshMaterializedViewStatement,
                Sequence::new(vec_of_erased![
                    Ref::keyword("REFRESH"),
                    Ref::keyword("MATERIALIZED"),
                    Ref::keyword("VIEW"),
                    Ref::keyword("CONCURRENTLY").optional(),
                    Ref::new("TableReferenceSegment"),
                    Ref::new("WithDataClauseSegment").optional(),
                ])
                .to_matchable(),
            )
            .to_matchable()
            .into(),
        ),
        (
            "DropMaterializedViewStatementSegment".into(),
            NodeMatcher::new(
                SyntaxKind::DropMaterializedViewStatement,
                Sequence::new(vec_of_erased![
                    Ref::keyword("DROP"),
                    Ref::keyword("MATERIALIZED"),
                    Ref::keyword("VIEW"),
                    Ref::new("IfExistsGrammar").optional(),
                    Delimited::new(vec_of_erased![Ref::new("TableReferenceSegment")]),
                    Ref::new("DropBehaviorGrammar").optional(),
                ])
                .to_matchable(),
            )
            .to_matchable()
            .into(),
        ),
        (
            "WithCheckOptionSegment".into(),
            NodeMatcher::new(
                SyntaxKind::WithCheckOption,
                Sequence::new(vec_of_erased![
                    Ref::keyword("WITH"),
                    one_of(vec_of_erased![
                        Ref::keyword("CASCADED"),
                        Ref::keyword("LOCAL")
                    ]),
                    Ref::keyword("CHECK"),
                    Ref::keyword("OPTION"),
                ])
                .to_matchable(),
            )
            .to_matchable()
            .into(),
        ),
        (
            "AlterPolicyStatementSegment".into(),
            NodeMatcher::new(
                SyntaxKind::AlterPolicyStatement,
                Sequence::new(vec_of_erased![
                    Ref::keyword("ALTER"),
                    Ref::keyword("POLICY"),
                    Ref::new("ObjectReferenceSegment"),
                    Ref::keyword("ON"),
                    Ref::new("TableReferenceSegment"),
                    one_of(vec_of_erased![
                        Sequence::new(vec_of_erased![
                            Ref::keyword("RENAME"),
                            Ref::keyword("TO"),
                            Ref::new("ObjectReferenceSegment"),
                        ]),
                        Sequence::new(vec_of_erased![
                            Ref::keyword("TO"),
                            Delimited::new(vec_of_erased![one_of(vec_of_erased![
                                Ref::new("RoleReferenceSegment"),
                                Ref::keyword("PUBLIC"),
                                Ref::keyword("CURRENT_ROLE"),
                                Ref::keyword("CURRENT_USER"),
                                Ref::keyword("SESSION_USER"),
                            ])]),
                        ])
                        .config(|this| this.optional()),
                        Sequence::new(vec_of_erased![
                            Ref::keyword("USING"),
                            Bracketed::new(vec_of_erased![Ref::new("ExpressionSegment")]),
                        ])
                        .config(|this| this.optional()),
                        Sequence::new(vec_of_erased![
                            Ref::keyword("WITH"),
                            Ref::keyword("CHECK"),
                            Bracketed::new(vec_of_erased![Ref::new("ExpressionSegment")]),
                        ])
                        .config(|this| this.optional()),
                    ]),
                ])
                .to_matchable(),
            )
            .to_matchable()
            .into(),
        ),
    ]);

    postgres.add([
        (
            "CreateViewStatementSegment".into(),
            NodeMatcher::new(
                SyntaxKind::CreateViewStatement,
                Sequence::new(vec_of_erased![
                    Ref::keyword("CREATE"),
                    Ref::new("OrReplaceGrammar").optional(),
                    Ref::new("TemporaryGrammar").optional(),
                    Ref::keyword("RECURSIVE").optional(),
                    Ref::keyword("VIEW"),
                    Ref::new("TableReferenceSegment"),
                    Ref::new("BracketedColumnReferenceListGrammar").optional(),
                    Sequence::new(vec_of_erased![
                        Ref::keyword("WITH"),
                        Ref::new("RelationOptionsSegment")
                    ])
                    .config(|this| this.optional()),
                    Ref::keyword("AS"),
                    one_of(vec_of_erased![
                        optionally_bracketed(vec_of_erased![Ref::new("SelectableGrammar")]),
                        Ref::new("ValuesClauseSegment"),
                    ]),
                    Ref::new("WithCheckOptionSegment").optional(),
                ])
                .to_matchable(),
            )
            .to_matchable()
            .into(),
        ),
        (
            "AlterViewStatementSegment".into(),
            NodeMatcher::new(
                SyntaxKind::AlterViewStatement,
                Sequence::new(vec_of_erased![
                    Ref::keyword("ALTER"),
                    Ref::keyword("VIEW"),
                    Ref::new("IfExistsGrammar").optional(),
                    Ref::new("TableReferenceSegment"),
                    one_of(vec_of_erased![
                        Sequence::new(vec_of_erased![
                            Ref::keyword("ALTER"),
                            Ref::keyword("COLUMN").optional(),
                            Ref::new("ColumnReferenceSegment"),
                            one_of(vec_of_erased![
                                Sequence::new(vec_of_erased![
                                    Ref::keyword("SET"),
                                    Ref::keyword("DEFAULT"),
                                    one_of(vec_of_erased![
                                        Ref::new("LiteralGrammar"),
                                        Ref::new("FunctionSegment"),
                                        Ref::new("BareFunctionSegment"),
                                        Ref::new("ExpressionSegment"),
                                    ]),
                                ]),
                                Sequence::new(vec_of_erased![
                                    Ref::keyword("DROP"),
                                    Ref::keyword("DEFAULT"),
                                ]),
                            ]),
                        ]),
                        Sequence::new(vec_of_erased![
                            Ref::keyword("OWNER"),
                            Ref::keyword("TO"),
                            one_of(vec_of_erased![
                                Ref::new("ObjectReferenceSegment"),
                                Ref::keyword("CURRENT_ROLE"),
                                Ref::keyword("CURRENT_USER"),
                                Ref::keyword("SESSION_USER"),
                            ]),
                        ]),
                        Sequence::new(vec_of_erased![
                            Ref::keyword("RENAME"),
                            Ref::keyword("COLUMN").optional(),
                            Ref::new("ColumnReferenceSegment"),
                            Ref::keyword("TO"),
                            Ref::new("ColumnReferenceSegment"),
                        ]),
                        Sequence::new(vec_of_erased![
                            Ref::keyword("RENAME"),
                            Ref::keyword("TO"),
                            Ref::new("TableReferenceSegment"),
                        ]),
                        Sequence::new(vec_of_erased![
                            Ref::keyword("SET"),
                            Ref::keyword("SCHEMA"),
                            Ref::new("SchemaReferenceSegment"),
                        ]),
                        Sequence::new(vec_of_erased![
                            Ref::keyword("SET"),
                            Bracketed::new(vec_of_erased![Delimited::new(vec_of_erased![
                                Sequence::new(vec_of_erased![
                                    Ref::new("ParameterNameSegment"),
                                    Sequence::new(vec_of_erased![
                                        Ref::new("EqualsSegment"),
                                        Ref::new("LiteralGrammar"),
                                    ])
                                    .config(|this| this.optional()),
                                ]),
                            ]),]),
                        ]),
                        Sequence::new(vec_of_erased![
                            Ref::keyword("RESET"),
                            Bracketed::new(vec_of_erased![Delimited::new(vec_of_erased![
                                Ref::new("ParameterNameSegment")
                            ])]),
                        ]),
                    ]),
                ])
                .to_matchable(),
            )
            .to_matchable()
            .into(),
        ),
    ]);

    postgres.add([
        (
            "DropViewStatementSegment".into(),
            NodeMatcher::new(
                SyntaxKind::DropViewStatement,
                Sequence::new(vec_of_erased![
                    Ref::keyword("DROP"),
                    Ref::keyword("VIEW"),
                    Ref::new("IfExistsGrammar").optional(),
                    Delimited::new(vec_of_erased![Ref::new("TableReferenceSegment")]),
                    Ref::new("DropBehaviorGrammar").optional(),
                ])
                .to_matchable(),
            )
            .to_matchable()
            .into(),
        ),
        (
            "CreateDatabaseStatementSegment".into(),
            NodeMatcher::new(
                SyntaxKind::CreateDatabaseStatement,
                Sequence::new(vec_of_erased![
                    Ref::keyword("CREATE"),
                    Ref::keyword("DATABASE"),
                    Ref::new("DatabaseReferenceSegment"),
                    Ref::keyword("WITH").optional(),
                    AnyNumberOf::new(vec_of_erased![
                        Sequence::new(vec_of_erased![
                            Ref::keyword("OWNER"),
                            Ref::new("EqualsSegment").optional(),
                            Ref::new("ObjectReferenceSegment"),
                        ]),
                        Sequence::new(vec_of_erased![
                            Ref::keyword("TEMPLATE"),
                            Ref::new("EqualsSegment").optional(),
                            Ref::new("ObjectReferenceSegment"),
                        ]),
                        Sequence::new(vec_of_erased![
                            Ref::keyword("ENCODING"),
                            Ref::new("EqualsSegment").optional(),
                            one_of(vec_of_erased![
                                Ref::new("QuotedLiteralSegment"),
                                Ref::keyword("DEFAULT"),
                            ]),
                        ]),
                        one_of(vec_of_erased![
                            Sequence::new(vec_of_erased![
                                Ref::keyword("LOCALE"),
                                Ref::new("EqualsSegment").optional(),
                                Ref::new("QuotedLiteralSegment"),
                            ]),
                            AnyNumberOf::new(vec_of_erased![
                                Sequence::new(vec_of_erased![
                                    Ref::keyword("LC_COLLATE"),
                                    Ref::new("EqualsSegment").optional(),
                                    Ref::new("QuotedLiteralSegment"),
                                ]),
                                Sequence::new(vec_of_erased![
                                    Ref::keyword("LC_CTYPE"),
                                    Ref::new("EqualsSegment").optional(),
                                    Ref::new("QuotedLiteralSegment"),
                                ]),
                            ]),
                        ]),
                        Sequence::new(vec_of_erased![
                            Ref::keyword("TABLESPACE"),
                            Ref::new("EqualsSegment").optional(),
                            one_of(vec_of_erased![
                                Ref::new("TablespaceReferenceSegment"),
                                Ref::keyword("DEFAULT"),
                            ]),
                        ]),
                        Sequence::new(vec_of_erased![
                            Ref::keyword("ALLOW_CONNECTIONS"),
                            Ref::new("EqualsSegment").optional(),
                            Ref::new("BooleanLiteralGrammar"),
                        ]),
                        Sequence::new(vec_of_erased![
                            Ref::keyword("CONNECTION"),
                            Ref::keyword("LIMIT"),
                            Ref::new("EqualsSegment").optional(),
                            Ref::new("NumericLiteralSegment"),
                        ]),
                        Sequence::new(vec_of_erased![
                            Ref::keyword("IS_TEMPLATE"),
                            Ref::new("EqualsSegment").optional(),
                            Ref::new("BooleanLiteralGrammar"),
                        ]),
                    ]),
                ])
                .to_matchable(),
            )
            .to_matchable()
            .into(),
        ),
    ]);

    postgres.add([(
        "AlterDatabaseStatementSegment".into(),
        NodeMatcher::new(
            SyntaxKind::AlterDatabaseStatement,
            Sequence::new(vec_of_erased![
                Ref::keyword("ALTER"),
                Ref::keyword("DATABASE"),
                Ref::new("DatabaseReferenceSegment"),
                one_of(vec_of_erased![
                    Sequence::new(vec_of_erased![
                        Ref::keyword("WITH").optional(),
                        AnyNumberOf::new(vec_of_erased![
                            Sequence::new(vec_of_erased![
                                Ref::keyword("ALLOW_CONNECTIONS"),
                                Ref::new("BooleanLiteralGrammar"),
                            ]),
                            Sequence::new(vec_of_erased![
                                Ref::keyword("CONNECTION"),
                                Ref::keyword("LIMIT"),
                                Ref::new("NumericLiteralSegment"),
                            ]),
                            Sequence::new(vec_of_erased![
                                Ref::keyword("IS_TEMPLATE"),
                                Ref::new("BooleanLiteralGrammar"),
                            ]),
                        ])
                        .config(|this| this.min_times(1)),
                    ]),
                    Sequence::new(vec_of_erased![
                        Ref::keyword("RENAME"),
                        Ref::keyword("TO"),
                        Ref::new("DatabaseReferenceSegment"),
                    ]),
                    Sequence::new(vec_of_erased![
                        Ref::keyword("OWNER"),
                        Ref::keyword("TO"),
                        one_of(vec_of_erased![
                            Ref::new("ObjectReferenceSegment"),
                            Ref::keyword("CURRENT_ROLE"),
                            Ref::keyword("CURRENT_USER"),
                            Ref::keyword("SESSION_USER"),
                        ]),
                    ]),
                    Sequence::new(vec_of_erased![
                        Ref::keyword("SET"),
                        Ref::keyword("TABLESPACE"),
                        Ref::new("TablespaceReferenceSegment"),
                    ]),
                    Sequence::new(vec_of_erased![
                        Ref::keyword("SET"),
                        Ref::new("ParameterNameSegment"),
                        one_of(vec_of_erased![
                            Sequence::new(vec_of_erased![
                                one_of(vec_of_erased![
                                    Ref::keyword("TO"),
                                    Ref::new("EqualsSegment"),
                                ]),
                                one_of(vec_of_erased![
                                    Ref::keyword("DEFAULT"),
                                    Ref::new("LiteralGrammar"),
                                ]),
                            ]),
                            Sequence::new(vec_of_erased![
                                Ref::keyword("FROM"),
                                Ref::keyword("CURRENT"),
                            ]),
                        ]),
                    ]),
                    Sequence::new(vec_of_erased![
                        Ref::keyword("RESET"),
                        one_of(vec_of_erased![
                            Ref::keyword("ALL"),
                            Ref::new("ParameterNameSegment"),
                        ]),
                    ]),
                ])
                .config(|this| this.optional()),
            ])
            .to_matchable(),
        )
        .to_matchable()
        .into(),
    )]);

    postgres.replace_grammar(
        "DropDatabaseStatementSegment",
        Sequence::new(vec_of_erased![
            Ref::keyword("DROP"),
            Ref::keyword("DATABASE"),
            Ref::new("IfExistsGrammar").optional(),
            Ref::new("DatabaseReferenceSegment"),
            Sequence::new(vec_of_erased![
                Ref::keyword("WITH").optional(),
                Bracketed::new(vec_of_erased![Ref::keyword("FORCE")]),
            ])
            .config(|this| this.optional()),
        ])
        .to_matchable(),
    );

    postgres.add([
        (
            "VacuumStatementSegment".into(),
            NodeMatcher::new(
                SyntaxKind::VacuumStatement,
                Sequence::new(vec_of_erased![
                    Ref::keyword("VACUUM"),
                    one_of(vec_of_erased![
                        Sequence::new(vec_of_erased![
                            Ref::keyword("FULL").optional(),
                            Ref::keyword("FREEZE").optional(),
                            Ref::keyword("VERBOSE").optional(),
                            one_of(vec_of_erased![
                                Ref::keyword("ANALYZE"),
                                Ref::keyword("ANALYSE")
                            ])
                            .config(|this| this.optional()),
                        ]),
                        Bracketed::new(vec_of_erased![Delimited::new(vec_of_erased![
                            Sequence::new(vec_of_erased![
                                one_of(vec_of_erased![
                                    Ref::keyword("FULL"),
                                    Ref::keyword("FREEZE"),
                                    Ref::keyword("VERBOSE"),
                                    Ref::keyword("ANALYZE"),
                                    Ref::keyword("ANALYSE"),
                                    Ref::keyword("DISABLE_PAGE_SKIPPING"),
                                    Ref::keyword("SKIP_LOCKED"),
                                    Ref::keyword("INDEX_CLEANUP"),
                                    Ref::keyword("PROCESS_TOAST"),
                                    Ref::keyword("TRUNCATE"),
                                    Ref::keyword("PARALLEL"),
                                ]),
                                one_of(vec_of_erased![
                                    Ref::new("LiteralGrammar"),
                                    Ref::new("NakedIdentifierSegment"),
                                    Ref::new("OnKeywordAsIdentifierSegment"),
                                ])
                                .config(|this| this.optional()),
                            ]),
                        ]),]),
                    ])
                    .config(|this| this.optional()),
                    Delimited::new(vec_of_erased![Sequence::new(vec_of_erased![
                        Ref::new("TableReferenceSegment"),
                        Ref::new("BracketedColumnReferenceListGrammar").optional(),
                    ])])
                    .config(|this| this.optional()),
                ])
                .to_matchable(),
            )
            .to_matchable()
            .into(),
        ),
        (
            "LikeOptionSegment".into(),
            NodeMatcher::new(
                SyntaxKind::LikeOptionSegment,
                Sequence::new(vec_of_erased![
                    one_of(vec_of_erased![
                        Ref::keyword("INCLUDING"),
                        Ref::keyword("EXCLUDING")
                    ]),
                    one_of(vec_of_erased![
                        Ref::keyword("COMMENTS"),
                        Ref::keyword("CONSTRAINTS"),
                        Ref::keyword("DEFAULTS"),
                        Ref::keyword("GENERATED"),
                        Ref::keyword("IDENTITY"),
                        Ref::keyword("INDEXES"),
                        Ref::keyword("STATISTICS"),
                        Ref::keyword("STORAGE"),
                        Ref::keyword("ALL"),
                    ]),
                ])
                .to_matchable(),
            )
            .to_matchable()
            .into(),
        ),
    ]);

    postgres.replace_grammar(
        "ColumnConstraintSegment",
        Sequence::new(vec_of_erased![
            Sequence::new(vec_of_erased![
                Ref::keyword("CONSTRAINT"),
                Ref::new("ObjectReferenceSegment"),
            ])
            .config(|this| this.optional()),
            one_of(vec_of_erased![
                Sequence::new(vec_of_erased![
                    Ref::keyword("NOT").optional(),
                    Ref::keyword("NULL"),
                ]),
                Sequence::new(vec_of_erased![
                    Ref::keyword("CHECK"),
                    Bracketed::new(vec_of_erased![Ref::new("ExpressionSegment")]),
                    Sequence::new(vec_of_erased![Ref::keyword("NO"), Ref::keyword("INHERIT"),])
                        .config(|this| this.optional()),
                ]),
                Sequence::new(vec_of_erased![
                    Ref::keyword("DEFAULT"),
                    one_of(vec_of_erased![
                        Ref::new("ShorthandCastSegment"),
                        Ref::new("LiteralGrammar"),
                        Ref::new("FunctionSegment"),
                        Ref::new("BareFunctionSegment"),
                        Ref::new("ExpressionSegment"),
                    ]),
                ]),
                Sequence::new(vec_of_erased![
                    Ref::keyword("GENERATED"),
                    Ref::keyword("ALWAYS"),
                    Ref::keyword("AS"),
                    Ref::new("ExpressionSegment"),
                    Ref::keyword("STORED"),
                ]),
                Sequence::new(vec_of_erased![
                    Ref::keyword("GENERATED"),
                    one_of(vec_of_erased![
                        Ref::keyword("ALWAYS"),
                        Sequence::new(vec_of_erased![Ref::keyword("BY"), Ref::keyword("DEFAULT")]),
                    ]),
                    Ref::keyword("AS"),
                    Ref::keyword("IDENTITY"),
                    Bracketed::new(vec_of_erased![AnyNumberOf::new(vec_of_erased![Ref::new(
                        "AlterSequenceOptionsSegment"
                    )])])
                    .config(|this| this.optional()),
                ]),
                Sequence::new(vec_of_erased![
                    Ref::keyword("UNIQUE"),
                    Sequence::new(vec_of_erased![
                        Ref::keyword("NULLS"),
                        Ref::keyword("NOT").optional(),
                        Ref::keyword("DISTINCT"),
                    ])
                    .config(|this| this.optional()),
                    Sequence::new(vec_of_erased![
                        Ref::keyword("WITH"),
                        Ref::new("DefinitionParametersSegment"),
                    ])
                    .config(|this| this.optional()),
                    Sequence::new(vec_of_erased![
                        Ref::keyword("USING"),
                        Ref::keyword("INDEX"),
                        Ref::keyword("TABLESPACE"),
                        Ref::new("TablespaceReferenceSegment"),
                    ])
                    .config(|this| this.optional()),
                ]),
                Sequence::new(vec_of_erased![
                    Ref::keyword("PRIMARY"),
                    Ref::keyword("KEY"),
                    Sequence::new(vec_of_erased![
                        Ref::keyword("WITH"),
                        Ref::new("DefinitionParametersSegment"),
                    ])
                    .config(|this| this.optional()),
                    Sequence::new(vec_of_erased![
                        Ref::keyword("USING"),
                        Ref::keyword("INDEX"),
                        Ref::keyword("TABLESPACE"),
                        Ref::new("TablespaceReferenceSegment"),
                    ])
                    .config(|this| this.optional()),
                ]),
                Ref::new("ReferenceDefinitionGrammar"),
            ]),
            one_of(vec_of_erased![
                Ref::keyword("DEFERRABLE"),
                Sequence::new(vec_of_erased![
                    Ref::keyword("NOT"),
                    Ref::keyword("DEFERRABLE")
                ]),
            ])
            .config(|this| this.optional()),
            one_of(vec_of_erased![
                Sequence::new(vec_of_erased![
                    Ref::keyword("INITIALLY"),
                    Ref::keyword("DEFERRED")
                ]),
                Sequence::new(vec_of_erased![
                    Ref::keyword("INITIALLY"),
                    Ref::keyword("IMMEDIATE")
                ]),
            ])
            .config(|this| this.optional()),
        ])
        .to_matchable(),
    );

    postgres.add([(
        "PartitionBoundSpecSegment".into(),
        NodeMatcher::new(
            SyntaxKind::PartitionBoundSpec,
            one_of(vec_of_erased![
                Sequence::new(vec_of_erased![
                    Ref::keyword("IN"),
                    Bracketed::new(vec_of_erased![Delimited::new(vec_of_erased![Ref::new(
                        "ExpressionSegment"
                    ),]),]),
                ]),
                Sequence::new(vec_of_erased![
                    Ref::keyword("FROM"),
                    Bracketed::new(vec_of_erased![Delimited::new(vec_of_erased![one_of(
                        vec_of_erased![
                            Ref::new("ExpressionSegment"),
                            Ref::keyword("MINVALUE"),
                            Ref::keyword("MAXVALUE"),
                        ]
                    ),]),]),
                    Ref::keyword("TO"),
                    Bracketed::new(vec_of_erased![Delimited::new(vec_of_erased![one_of(
                        vec_of_erased![
                            Ref::new("ExpressionSegment"),
                            Ref::keyword("MINVALUE"),
                            Ref::keyword("MAXVALUE"),
                        ]
                    ),]),]),
                ]),
                Sequence::new(vec_of_erased![
                    Ref::keyword("WITH"),
                    Bracketed::new(vec_of_erased![Sequence::new(vec_of_erased![
                        Ref::keyword("MODULUS"),
                        Ref::new("NumericLiteralSegment"),
                        Ref::new("CommaSegment"),
                        Ref::keyword("REMAINDER"),
                        Ref::new("NumericLiteralSegment"),
                    ]),]),
                ]),
            ])
            .to_matchable(),
        )
        .to_matchable()
        .into(),
    )]);

    postgres.add([(
        "TableConstraintSegment".into(),
        NodeMatcher::new(
            SyntaxKind::TableConstraint,
            Sequence::new(vec_of_erased![
                Sequence::new(vec_of_erased![
                    Ref::keyword("CONSTRAINT"),
                    Ref::new("ObjectReferenceSegment"),
                ])
                .config(|this| this.optional()),
                one_of(vec_of_erased![
                    Sequence::new(vec_of_erased![
                        Ref::keyword("CHECK"),
                        Bracketed::new(vec_of_erased![Ref::new("ExpressionSegment")]),
                        Sequence::new(vec_of_erased![Ref::keyword("NO"), Ref::keyword("INHERIT"),])
                            .config(|this| this.optional()),
                    ]),
                    Sequence::new(vec_of_erased![
                        Ref::keyword("UNIQUE"),
                        Sequence::new(vec_of_erased![
                            Ref::keyword("NULLS"),
                            Ref::keyword("NOT").optional(),
                            Ref::keyword("DISTINCT"),
                        ])
                        .config(|this| this.optional()),
                        Ref::new("BracketedColumnReferenceListGrammar"),
                        Ref::new("IndexParametersSegment").optional(),
                    ]),
                    Sequence::new(vec_of_erased![
                        Ref::new("PrimaryKeyGrammar"),
                        Ref::new("BracketedColumnReferenceListGrammar"),
                        Ref::new("IndexParametersSegment").optional(),
                    ]),
                    Sequence::new(vec_of_erased![
                        Ref::keyword("EXCLUDE"),
                        Sequence::new(vec_of_erased![
                            Ref::keyword("USING"),
                            Ref::new("IndexAccessMethodSegment"),
                        ])
                        .config(|this| this.optional()),
                        Bracketed::new(vec_of_erased![Delimited::new(vec_of_erased![Ref::new(
                            "ExclusionConstraintElementSegment"
                        )])]),
                        Ref::new("IndexParametersSegment").optional(),
                        Sequence::new(vec_of_erased![
                            Ref::keyword("WHERE"),
                            Bracketed::new(vec_of_erased![Ref::new("ExpressionSegment")]),
                        ])
                        .config(|this| this.optional()),
                    ]),
                    Sequence::new(vec_of_erased![
                        Ref::keyword("FOREIGN"),
                        Ref::keyword("KEY"),
                        Ref::new("BracketedColumnReferenceListGrammar"),
                        Ref::new("ReferenceDefinitionGrammar"),
                    ]),
                ]),
                AnyNumberOf::new(vec_of_erased![
                    one_of(vec_of_erased![
                        Ref::keyword("DEFERRABLE"),
                        Sequence::new(vec_of_erased![
                            Ref::keyword("NOT"),
                            Ref::keyword("DEFERRABLE"),
                        ]),
                    ]),
                    one_of(vec_of_erased![
                        Sequence::new(vec_of_erased![
                            Ref::keyword("INITIALLY"),
                            Ref::keyword("DEFERRED"),
                        ]),
                        Sequence::new(vec_of_erased![
                            Ref::keyword("INITIALLY"),
                            Ref::keyword("IMMEDIATE"),
                        ]),
                    ]),
                    Sequence::new(vec_of_erased![Ref::keyword("NOT"), Ref::keyword("VALID"),]),
                    Sequence::new(vec_of_erased![Ref::keyword("NO"), Ref::keyword("INHERIT"),]),
                ]),
            ])
            .to_matchable(),
        )
        .to_matchable()
        .into(),
    )]);

    postgres.add([(
        "TableConstraintUsingIndexSegment".into(),
        NodeMatcher::new(
            SyntaxKind::TableConstraint,
            Sequence::new(vec_of_erased![
                Sequence::new(vec_of_erased![
                    Ref::keyword("CONSTRAINT"),
                    Ref::new("ObjectReferenceSegment"),
                ])
                .config(|this| this.optional()),
                Sequence::new(vec_of_erased![
                    one_of(vec_of_erased![
                        Ref::keyword("UNIQUE"),
                        Ref::new("PrimaryKeyGrammar")
                    ]),
                    Ref::keyword("USING"),
                    Ref::keyword("INDEX"),
                    Ref::new("IndexReferenceSegment"),
                ]),
                one_of(vec_of_erased![
                    Ref::keyword("DEFERRABLE"),
                    Sequence::new(vec_of_erased![
                        Ref::keyword("NOT"),
                        Ref::keyword("DEFERRABLE")
                    ]),
                ])
                .config(|this| this.optional()),
                one_of(vec_of_erased![
                    Sequence::new(vec_of_erased![
                        Ref::keyword("INITIALLY"),
                        Ref::keyword("DEFERRED")
                    ]),
                    Sequence::new(vec_of_erased![
                        Ref::keyword("INITIALLY"),
                        Ref::keyword("IMMEDIATE")
                    ]),
                ])
                .config(|this| this.optional()),
            ])
            .to_matchable(),
        )
        .to_matchable()
        .into(),
    )]);

    postgres.add([
        (
            "IndexParametersSegment".into(),
            NodeMatcher::new(
                SyntaxKind::IndexParameters,
                Sequence::new(vec_of_erased![
                    Sequence::new(vec_of_erased![
                        Ref::keyword("INCLUDE"),
                        Ref::new("BracketedColumnReferenceListGrammar"),
                    ])
                    .config(|this| this.optional()),
                    Sequence::new(vec_of_erased![
                        Ref::keyword("WITH"),
                        Ref::new("DefinitionParametersSegment"),
                    ])
                    .config(|this| this.optional()),
                    Sequence::new(vec_of_erased![
                        Ref::keyword("USING"),
                        Ref::keyword("INDEX"),
                        Ref::keyword("TABLESPACE"),
                        Ref::new("TablespaceReferenceSegment"),
                    ])
                    .config(|this| this.optional()),
                ])
                .to_matchable(),
            )
            .to_matchable()
            .into(),
        ),
        (
            "ReferentialActionSegment".into(),
            NodeMatcher::new(
                SyntaxKind::ReferentialActionSegment,
                one_of(vec_of_erased![
                    Ref::keyword("CASCADE"),
                    Sequence::new(vec_of_erased![Ref::keyword("SET"), Ref::keyword("NULL")]),
                    Sequence::new(vec_of_erased![Ref::keyword("SET"), Ref::keyword("DEFAULT")]),
                    Ref::keyword("RESTRICT"),
                    Sequence::new(vec_of_erased![Ref::keyword("NO"), Ref::keyword("ACTION")]),
                ])
                .to_matchable(),
            )
            .to_matchable()
            .into(),
        ),
        (
            "IndexElementOptionsSegment".into(),
            NodeMatcher::new(
                SyntaxKind::IndexElementOptions,
                Sequence::new(vec_of_erased![
                    Sequence::new(vec_of_erased![
                        Ref::keyword("COLLATE"),
                        Ref::new("CollationReferenceSegment"),
                    ])
                    .config(|this| this.optional()),
                    Sequence::new(vec_of_erased![
                        Ref::new("OperatorClassReferenceSegment").config(|this| {
                            this.exclude = Some(
                                Sequence::new(vec_of_erased![
                                    Ref::keyword("NULLS"),
                                    one_of(vec_of_erased![
                                        Ref::keyword("FIRST"),
                                        Ref::keyword("LAST")
                                    ]),
                                ])
                                .to_matchable(),
                            );
                        }),
                        Ref::new("RelationOptionsSegment").optional(),
                    ])
                    .config(|this| this.optional()),
                    one_of(vec_of_erased![Ref::keyword("ASC"), Ref::keyword("DESC")])
                        .config(|this| this.optional()),
                    Sequence::new(vec_of_erased![
                        Ref::keyword("NULLS"),
                        one_of(vec_of_erased![Ref::keyword("FIRST"), Ref::keyword("LAST")]),
                    ])
                    .config(|this| this.optional()),
                ])
                .to_matchable(),
            )
            .to_matchable()
            .into(),
        ),
        (
            "IndexElementSegment".into(),
            NodeMatcher::new(
                SyntaxKind::IndexElement,
                Sequence::new(vec_of_erased![
                    one_of(vec_of_erased![
                        Ref::new("ColumnReferenceSegment"),
                        Ref::new("FunctionSegment"),
                        Bracketed::new(vec_of_erased![Ref::new("ExpressionSegment")]),
                    ]),
                    Ref::new("IndexElementOptionsSegment").optional(),
                ])
                .to_matchable(),
            )
            .to_matchable()
            .into(),
        ),
        (
            "ExclusionConstraintElementSegment".into(),
            NodeMatcher::new(
                SyntaxKind::ExclusionConstraintElement,
                Sequence::new(vec_of_erased![
                    Ref::new("IndexElementSegment"),
                    Ref::keyword("WITH"),
                    Ref::new("ComparisonOperatorGrammar"),
                ])
                .to_matchable(),
            )
            .to_matchable()
            .into(),
        ),
        (
            "AlterDefaultPrivilegesStatementSegment".into(),
            NodeMatcher::new(
                SyntaxKind::AlterDefaultPrivilegesStatement,
                Sequence::new(vec_of_erased![
                    Ref::keyword("ALTER"),
                    Ref::keyword("DEFAULT"),
                    Ref::keyword("PRIVILEGES"),
                    Sequence::new(vec_of_erased![
                        Ref::keyword("FOR"),
                        one_of(vec_of_erased![Ref::keyword("ROLE"), Ref::keyword("USER")]),
                        Delimited::new(vec_of_erased![Ref::new("ObjectReferenceSegment")]).config(
                            |this| {
                                this.terminators = vec_of_erased![
                                    Ref::keyword("IN"),
                                    Ref::keyword("GRANT"),
                                    Ref::keyword("REVOKE"),
                                ];
                            }
                        ),
                    ])
                    .config(|this| this.optional()),
                    Sequence::new(vec_of_erased![
                        Ref::keyword("IN"),
                        Ref::keyword("SCHEMA"),
                        Delimited::new(vec_of_erased![Ref::new("SchemaReferenceSegment")]).config(
                            |this| {
                                this.terminators =
                                    vec_of_erased![Ref::keyword("GRANT"), Ref::keyword("REVOKE")];
                            }
                        ),
                    ])
                    .config(|this| this.optional()),
                    one_of(vec_of_erased![
                        Ref::new("AlterDefaultPrivilegesGrantSegment"),
                        Ref::new("AlterDefaultPrivilegesRevokeSegment"),
                    ]),
                ])
                .to_matchable(),
            )
            .to_matchable()
            .into(),
        ),
        (
            "AlterDefaultPrivilegesObjectPrivilegesSegment".into(),
            NodeMatcher::new(
                SyntaxKind::AlterDefaultPrivilegesObjectPrivilege,
                one_of(vec_of_erased![
                    Sequence::new(vec_of_erased![
                        Ref::keyword("ALL"),
                        Ref::keyword("PRIVILEGES").optional(),
                    ]),
                    Delimited::new(vec_of_erased![
                        Ref::keyword("CREATE"),
                        Ref::keyword("DELETE"),
                        Ref::keyword("EXECUTE"),
                        Ref::keyword("INSERT"),
                        Ref::keyword("REFERENCES"),
                        Ref::keyword("SELECT"),
                        Ref::keyword("TRIGGER"),
                        Ref::keyword("TRUNCATE"),
                        Ref::keyword("UPDATE"),
                        Ref::keyword("USAGE"),
                    ])
                    .config(|this| {
                        this.terminators = vec_of_erased![Ref::keyword("ON")];
                    }),
                ])
                .to_matchable(),
            )
            .to_matchable()
            .into(),
        ),
        (
            "AlterDefaultPrivilegesSchemaObjectsSegment".into(),
            NodeMatcher::new(
                SyntaxKind::AlterDefaultPrivilegesSchemaObject,
                one_of(vec_of_erased![
                    Ref::keyword("TABLES"),
                    Ref::keyword("FUNCTIONS"),
                    Ref::keyword("ROUTINES"),
                    Ref::keyword("SEQUENCES"),
                    Ref::keyword("TYPES"),
                    Ref::keyword("SCHEMAS"),
                ])
                .to_matchable(),
            )
            .to_matchable()
            .into(),
        ),
        (
            "AlterDefaultPrivilegesToFromRolesSegment".into(),
            NodeMatcher::new(
                SyntaxKind::AlterDefaultPrivilegesToFromRoles,
                one_of(vec_of_erased![
                    Sequence::new(vec_of_erased![
                        Ref::keyword("GROUP").optional(),
                        Ref::new("RoleReferenceSegment"),
                    ]),
                    Ref::keyword("PUBLIC"),
                ])
                .to_matchable(),
            )
            .to_matchable()
            .into(),
        ),
        (
            "AlterDefaultPrivilegesGrantSegment".into(),
            NodeMatcher::new(
                SyntaxKind::AlterDefaultPrivilegesGrant,
                Sequence::new(vec_of_erased![
                    Ref::keyword("GRANT"),
                    Ref::new("AlterDefaultPrivilegesObjectPrivilegesSegment"),
                    Ref::keyword("ON"),
                    Ref::new("AlterDefaultPrivilegesSchemaObjectsSegment"),
                    Ref::keyword("TO"),
                    Delimited::new(vec_of_erased![Ref::new(
                        "AlterDefaultPrivilegesToFromRolesSegment"
                    )])
                    .config(|this| {
                        this.terminators = vec_of_erased![Ref::keyword("WITH")];
                    }),
                    Sequence::new(vec_of_erased![
                        Ref::keyword("WITH"),
                        Ref::keyword("GRANT"),
                        Ref::keyword("OPTION"),
                    ])
                    .config(|this| this.optional()),
                ])
                .to_matchable(),
            )
            .to_matchable()
            .into(),
        ),
        (
            "AlterDefaultPrivilegesRevokeSegment".into(),
            NodeMatcher::new(
                SyntaxKind::AlterDefaultPrivilegesRevoke,
                Sequence::new(vec_of_erased![
                    Ref::keyword("REVOKE"),
                    Sequence::new(vec_of_erased![
                        Ref::keyword("GRANT"),
                        Ref::keyword("OPTION"),
                        Ref::keyword("FOR"),
                    ])
                    .config(|this| this.optional()),
                    Ref::new("AlterDefaultPrivilegesObjectPrivilegesSegment"),
                    Ref::keyword("ON"),
                    Ref::new("AlterDefaultPrivilegesSchemaObjectsSegment"),
                    Ref::keyword("FROM"),
                    Delimited::new(vec_of_erased![Ref::new(
                        "AlterDefaultPrivilegesToFromRolesSegment"
                    )])
                    .config(|this| {
                        this.terminators =
                            vec_of_erased![Ref::keyword("RESTRICT"), Ref::keyword("CASCADE")];
                    }),
                    Ref::new("DropBehaviorGrammar").optional(),
                ])
                .to_matchable(),
            )
            .to_matchable()
            .into(),
        ),
        (
            "DropOwnedStatementSegment".into(),
            NodeMatcher::new(
                SyntaxKind::DropOwnedStatement,
                Sequence::new(vec_of_erased![
                    Ref::keyword("DROP"),
                    Ref::keyword("OWNED"),
                    Ref::keyword("BY"),
                    Delimited::new(vec_of_erased![one_of(vec_of_erased![
                        Ref::keyword("CURRENT_ROLE"),
                        Ref::keyword("CURRENT_USER"),
                        Ref::keyword("SESSION_USER"),
                        Ref::new("RoleReferenceSegment"),
                    ])]),
                    Ref::new("DropBehaviorGrammar").optional(),
                ])
                .to_matchable(),
            )
            .to_matchable()
            .into(),
        ),
        (
            "ReassignOwnedStatementSegment".into(),
            NodeMatcher::new(
                SyntaxKind::ReassignOwnedStatement,
                Sequence::new(vec_of_erased![
                    Ref::keyword("REASSIGN"),
                    Ref::keyword("OWNED"),
                    Ref::keyword("BY"),
                    Delimited::new(vec_of_erased![one_of(vec_of_erased![
                        Ref::keyword("CURRENT_ROLE"),
                        Ref::keyword("CURRENT_USER"),
                        Ref::keyword("SESSION_USER"),
                        Ref::new("RoleReferenceSegment"),
                    ])]),
                    Ref::keyword("TO"),
                    one_of(vec_of_erased![
                        Ref::keyword("CURRENT_ROLE"),
                        Ref::keyword("CURRENT_USER"),
                        Ref::keyword("SESSION_USER"),
                        Ref::new("RoleReferenceSegment"),
                    ]),
                ])
                .to_matchable(),
            )
            .to_matchable()
            .into(),
        ),
        (
            "CommentOnStatementSegment".into(),
            NodeMatcher::new(
                SyntaxKind::CommentClause,
                Sequence::new(vec_of_erased![
                    Ref::keyword("COMMENT"),
                    Ref::keyword("ON"),
                    Sequence::new(vec_of_erased![
                        one_of(vec_of_erased![
                            Sequence::new(vec_of_erased![
                                one_of(vec_of_erased![Ref::keyword("TABLE"), Ref::keyword("VIEW")]),
                                Ref::new("TableReferenceSegment"),
                            ]),
                            Sequence::new(vec_of_erased![
                                Ref::keyword("CAST"),
                                Bracketed::new(vec_of_erased![Sequence::new(vec_of_erased![
                                    Ref::new("ObjectReferenceSegment"),
                                    Ref::keyword("AS"),
                                    Ref::new("ObjectReferenceSegment"),
                                ])]),
                            ]),
                            Sequence::new(vec_of_erased![
                                Ref::keyword("COLUMN"),
                                Ref::new("ColumnReferenceSegment"),
                            ]),
                            Sequence::new(vec_of_erased![
                                Ref::keyword("CONSTRAINT"),
                                Ref::new("ObjectReferenceSegment"),
                                Sequence::new(vec_of_erased![
                                    Ref::keyword("ON"),
                                    Ref::keyword("DOMAIN").optional(),
                                    Ref::new("ObjectReferenceSegment"),
                                ]),
                            ]),
                            Sequence::new(vec_of_erased![
                                Ref::keyword("DATABASE"),
                                Ref::new("DatabaseReferenceSegment"),
                            ]),
                            Sequence::new(vec_of_erased![
                                Ref::keyword("EXTENSION"),
                                Ref::new("ExtensionReferenceSegment"),
                            ]),
                            Sequence::new(vec_of_erased![
                                Ref::keyword("FUNCTION"),
                                Ref::new("FunctionNameSegment"),
                                Sequence::new(vec_of_erased![Ref::new(
                                    "FunctionParameterListGrammar"
                                )])
                                .config(|this| this.optional()),
                            ]),
                            Sequence::new(vec_of_erased![
                                Ref::keyword("INDEX"),
                                Ref::new("IndexReferenceSegment"),
                            ]),
                            Sequence::new(vec_of_erased![
                                Ref::keyword("SCHEMA"),
                                Ref::new("SchemaReferenceSegment"),
                            ]),
                            Sequence::new(vec_of_erased![
                                one_of(vec_of_erased![
                                    Ref::keyword("COLLATION"),
                                    Ref::keyword("CONVERSION"),
                                    Ref::keyword("DOMAIN"),
                                    Ref::keyword("LANGUAGE"),
                                    Ref::keyword("POLICY"),
                                    Ref::keyword("PUBLICATION"),
                                    Ref::keyword("ROLE"),
                                    Ref::keyword("RULE"),
                                    Ref::keyword("SEQUENCE"),
                                    Ref::keyword("SERVER"),
                                    Ref::keyword("STATISTICS"),
                                    Ref::keyword("SUBSCRIPTION"),
                                    Ref::keyword("TABLESPACE"),
                                    Ref::keyword("TRIGGER"),
                                    Ref::keyword("TYPE"),
                                    Sequence::new(vec_of_erased![
                                        Ref::keyword("ACCESS"),
                                        Ref::keyword("METHOD"),
                                    ]),
                                    Sequence::new(vec_of_erased![
                                        Ref::keyword("EVENT"),
                                        Ref::keyword("TRIGGER"),
                                    ]),
                                    Sequence::new(vec_of_erased![
                                        Ref::keyword("FOREIGN"),
                                        Ref::keyword("DATA"),
                                        Ref::keyword("WRAPPER"),
                                    ]),
                                    Sequence::new(vec_of_erased![
                                        Ref::keyword("FOREIGN"),
                                        Ref::keyword("TABLE"),
                                    ]),
                                    Sequence::new(vec_of_erased![
                                        Ref::keyword("MATERIALIZED"),
                                        Ref::keyword("VIEW"),
                                    ]),
                                    Sequence::new(vec_of_erased![
                                        Ref::keyword("TEXT"),
                                        Ref::keyword("SEARCH"),
                                        Ref::keyword("CONFIGURATION"),
                                    ]),
                                    Sequence::new(vec_of_erased![
                                        Ref::keyword("TEXT"),
                                        Ref::keyword("SEARCH"),
                                        Ref::keyword("DICTIONARY"),
                                    ]),
                                    Sequence::new(vec_of_erased![
                                        Ref::keyword("TEXT"),
                                        Ref::keyword("SEARCH"),
                                        Ref::keyword("PARSER"),
                                    ]),
                                    Sequence::new(vec_of_erased![
                                        Ref::keyword("TEXT"),
                                        Ref::keyword("SEARCH"),
                                        Ref::keyword("TEMPLATE"),
                                    ]),
                                ]),
                                Ref::new("ObjectReferenceSegment"),
                                Sequence::new(vec_of_erased![
                                    Ref::keyword("ON"),
                                    Ref::new("ObjectReferenceSegment"),
                                ])
                                .config(|this| this.optional()),
                            ]),
                            Sequence::new(vec_of_erased![
                                one_of(vec_of_erased![
                                    Ref::keyword("AGGREGATE"),
                                    Ref::keyword("PROCEDURE"),
                                    Ref::keyword("ROUTINE"),
                                ]),
                                Ref::new("ObjectReferenceSegment"),
                                Bracketed::new(vec_of_erased![Sequence::new(vec_of_erased![
                                    Anything::new()
                                ])
                                .config(|this| this.optional()),])
                                .config(|this| this.optional()),
                            ]),
                        ]),
                        Sequence::new(vec_of_erased![
                            Ref::keyword("IS"),
                            one_of(vec_of_erased![
                                Ref::new("QuotedLiteralSegment"),
                                Ref::keyword("NULL")
                            ]),
                        ]),
                    ]),
                ])
                .to_matchable(),
            )
            .to_matchable()
            .into(),
        ),
    ]);

    postgres.replace_grammar(
        "CreateIndexStatementSegment",
        Sequence::new(vec_of_erased![
            Ref::keyword("CREATE"),
            Ref::keyword("UNIQUE").optional(),
            Ref::keyword("INDEX"),
            Ref::keyword("CONCURRENTLY").optional(),
            Sequence::new(vec_of_erased![
                Ref::new("IfNotExistsGrammar").optional(),
                Ref::new("IndexReferenceSegment"),
            ])
            .config(|this| this.optional()),
            Ref::keyword("ON"),
            Ref::keyword("ONLY").optional(),
            Ref::new("TableReferenceSegment"),
            Sequence::new(vec_of_erased![
                Ref::keyword("USING"),
                Ref::new("IndexAccessMethodSegment"),
            ])
            .config(|this| this.optional()),
            Bracketed::new(vec_of_erased![Delimited::new(vec_of_erased![Ref::new(
                "IndexElementSegment"
            )])]),
            Sequence::new(vec_of_erased![
                Ref::keyword("INCLUDE"),
                Bracketed::new(vec_of_erased![Delimited::new(vec_of_erased![Ref::new(
                    "IndexElementSegment"
                )])]),
            ])
            .config(|this| this.optional()),
            Sequence::new(vec_of_erased![
                Ref::keyword("NULLS"),
                Ref::keyword("NOT").optional(),
                Ref::keyword("DISTINCT"),
            ])
            .config(|this| this.optional()),
            Sequence::new(vec_of_erased![
                Ref::keyword("WITH"),
                Ref::new("RelationOptionsSegment"),
            ])
            .config(|this| this.optional()),
            Sequence::new(vec_of_erased![
                Ref::keyword("TABLESPACE"),
                Ref::new("TablespaceReferenceSegment"),
            ])
            .config(|this| this.optional()),
            Sequence::new(vec_of_erased![
                Ref::keyword("WHERE"),
                Ref::new("ExpressionSegment")
            ])
            .config(|this| this.optional()),
        ])
        .to_matchable(),
    );

    postgres.add([(
        "AlterIndexStatementSegment".into(),
        NodeMatcher::new(
            SyntaxKind::AlterIndexStatement,
            Sequence::new(vec_of_erased![
                Ref::keyword("ALTER"),
                Ref::keyword("INDEX"),
                one_of(vec_of_erased![
                    Sequence::new(vec_of_erased![
                        Ref::new("IfExistsGrammar").optional(),
                        Ref::new("IndexReferenceSegment"),
                        one_of(vec_of_erased![
                            Sequence::new(vec_of_erased![
                                Ref::keyword("RENAME"),
                                Ref::keyword("TO"),
                                Ref::new("IndexReferenceSegment"),
                            ]),
                            Sequence::new(vec_of_erased![
                                Ref::keyword("SET"),
                                Ref::keyword("TABLESPACE"),
                                Ref::new("TablespaceReferenceSegment"),
                            ]),
                            Sequence::new(vec_of_erased![
                                Ref::keyword("ATTACH"),
                                Ref::keyword("PARTITION"),
                                Ref::new("IndexReferenceSegment"),
                            ]),
                            Sequence::new(vec_of_erased![
                                Ref::keyword("NO").optional(),
                                Ref::keyword("DEPENDS"),
                                Ref::keyword("ON"),
                                Ref::keyword("EXTENSION"),
                                Ref::new("ExtensionReferenceSegment"),
                            ]),
                            Sequence::new(vec_of_erased![
                                Ref::keyword("SET"),
                                Bracketed::new(vec_of_erased![Delimited::new(vec_of_erased![
                                    Sequence::new(vec_of_erased![
                                        Ref::new("ParameterNameSegment"),
                                        Sequence::new(vec_of_erased![
                                            Ref::new("EqualsSegment"),
                                            Ref::new("LiteralGrammar"),
                                        ])
                                        .config(|this| this.optional()),
                                    ]),
                                ]),]),
                            ]),
                            Sequence::new(vec_of_erased![
                                Ref::keyword("RESET"),
                                Bracketed::new(vec_of_erased![Delimited::new(vec_of_erased![
                                    Ref::new("ParameterNameSegment"),
                                ]),]),
                            ]),
                            Sequence::new(vec_of_erased![
                                Ref::keyword("ALTER"),
                                Ref::keyword("COLUMN").optional(),
                                Ref::new("NumericLiteralSegment"),
                                Ref::keyword("SET"),
                                Ref::keyword("STATISTICS"),
                                Ref::new("NumericLiteralSegment"),
                            ]),
                        ]),
                    ]),
                    Sequence::new(vec_of_erased![
                        Ref::keyword("ALL"),
                        Ref::keyword("IN"),
                        Ref::keyword("TABLESPACE"),
                        Ref::new("TablespaceReferenceSegment"),
                        Sequence::new(vec_of_erased![
                            Ref::keyword("OWNED"),
                            Ref::keyword("BY"),
                            Delimited::new(vec_of_erased![Ref::new("RoleReferenceSegment")]),
                        ])
                        .config(|this| this.optional()),
                        Ref::keyword("SET"),
                        Ref::keyword("TABLESPACE"),
                        Ref::new("TablespaceReferenceSegment"),
                        Ref::keyword("NOWAIT").optional(),
                    ]),
                ]),
            ])
            .to_matchable(),
        )
        .to_matchable()
        .into(),
    )]);

    postgres.add([(
        "ReindexStatementSegment".into(),
        NodeMatcher::new(
            SyntaxKind::ReindexStatementSegment,
            Sequence::new(vec_of_erased![
                Ref::keyword("REINDEX"),
                Bracketed::new(vec_of_erased![Delimited::new(vec_of_erased![
                    Sequence::new(vec_of_erased![
                        Ref::keyword("CONCURRENTLY"),
                        Ref::new("BooleanLiteralGrammar").optional(),
                    ]),
                    Sequence::new(vec_of_erased![
                        Ref::keyword("TABLESPACE"),
                        Ref::new("TablespaceReferenceSegment"),
                    ]),
                    Sequence::new(vec_of_erased![
                        Ref::keyword("VERBOSE"),
                        Ref::new("BooleanLiteralGrammar").optional(),
                    ]),
                ]),])
                .config(|this| this.optional()),
                one_of(vec_of_erased![
                    Sequence::new(vec_of_erased![
                        Ref::keyword("INDEX"),
                        Ref::keyword("CONCURRENTLY").optional(),
                        Ref::new("IndexReferenceSegment"),
                    ]),
                    Sequence::new(vec_of_erased![
                        Ref::keyword("TABLE"),
                        Ref::keyword("CONCURRENTLY").optional(),
                        Ref::new("TableReferenceSegment"),
                    ]),
                    Sequence::new(vec_of_erased![
                        Ref::keyword("SCHEMA"),
                        Ref::keyword("CONCURRENTLY").optional(),
                        Ref::new("SchemaReferenceSegment"),
                    ]),
                    Sequence::new(vec_of_erased![
                        one_of(vec_of_erased![
                            Ref::keyword("DATABASE"),
                            Ref::keyword("SYSTEM"),
                        ]),
                        Ref::keyword("CONCURRENTLY").optional(),
                        Ref::new("DatabaseReferenceSegment"),
                    ]),
                ]),
            ])
            .to_matchable(),
        )
        .to_matchable()
        .into(),
    )]);

    postgres.replace_grammar(
        "DropIndexStatementSegment",
        Sequence::new(vec_of_erased![
            Ref::keyword("DROP"),
            Ref::keyword("INDEX"),
            Ref::keyword("CONCURRENTLY").optional(),
            Ref::new("IfExistsGrammar").optional(),
            Delimited::new(vec_of_erased![Ref::new("IndexReferenceSegment")]),
            Ref::new("DropBehaviorGrammar").optional(),
        ])
        .to_matchable(),
    );

    postgres.replace_grammar(
        "FrameClauseSegment",
        {
            let frame_extent = ansi::frame_extent();

            let frame_exclusion = Sequence::new(vec_of_erased![
                Ref::keyword("EXCLUDE"),
                one_of(vec_of_erased![
                    Sequence::new(vec_of_erased![Ref::keyword("CURRENT"), Ref::keyword("ROW")]),
                    Ref::keyword("GROUP"),
                    Ref::keyword("TIES"),
                    Sequence::new(vec_of_erased![Ref::keyword("NO"), Ref::keyword("OTHERS")]),
                ])
            ])
            .config(|this| this.optional());

            Sequence::new(vec_of_erased![
                Ref::new("FrameClauseUnitGrammar"),
                one_of(vec_of_erased![
                    frame_extent.clone(),
                    Sequence::new(vec_of_erased![
                        Ref::keyword("BETWEEN"),
                        frame_extent.clone(),
                        Ref::keyword("AND"),
                        frame_extent.clone(),
                    ]),
                ]),
                frame_exclusion,
            ])
        }
        .to_matchable(),
    );

    postgres.replace_grammar(
        "CreateSequenceOptionsSegment",
        one_of(vec_of_erased![
            Sequence::new(vec_of_erased![
                Ref::keyword("AS"),
                Ref::new("DatatypeSegment")
            ]),
            Sequence::new(vec_of_erased![
                Ref::keyword("INCREMENT"),
                Ref::keyword("BY").optional(),
                Ref::new("NumericLiteralSegment"),
            ]),
            one_of(vec_of_erased![
                Sequence::new(vec_of_erased![
                    Ref::keyword("MINVALUE"),
                    Ref::new("NumericLiteralSegment"),
                ]),
                Sequence::new(vec_of_erased![Ref::keyword("NO"), Ref::keyword("MINVALUE")]),
            ]),
            one_of(vec_of_erased![
                Sequence::new(vec_of_erased![
                    Ref::keyword("MAXVALUE"),
                    Ref::new("NumericLiteralSegment"),
                ]),
                Sequence::new(vec_of_erased![Ref::keyword("NO"), Ref::keyword("MAXVALUE")]),
            ]),
            Sequence::new(vec_of_erased![
                Ref::keyword("START"),
                Ref::keyword("WITH").optional(),
                Ref::new("NumericLiteralSegment"),
            ]),
            Sequence::new(vec_of_erased![
                Ref::keyword("CACHE"),
                Ref::new("NumericLiteralSegment")
            ]),
            one_of(vec_of_erased![
                Ref::keyword("CYCLE"),
                Sequence::new(vec_of_erased![Ref::keyword("NO"), Ref::keyword("CYCLE")]),
            ]),
            Sequence::new(vec_of_erased![
                Ref::keyword("OWNED"),
                Ref::keyword("BY"),
                one_of(vec_of_erased![
                    Ref::keyword("NONE"),
                    Ref::new("ColumnReferenceSegment")
                ]),
            ]),
        ])
        .to_matchable(),
    );

    postgres.add([(
        "CreateSequenceStatementSegment".into(),
        NodeMatcher::new(
            SyntaxKind::CreateSequenceStatement,
            Sequence::new(vec_of_erased![
                Ref::keyword("CREATE"),
                Ref::new("TemporaryGrammar").optional(),
                Ref::keyword("SEQUENCE"),
                Ref::new("IfNotExistsGrammar").optional(),
                Ref::new("SequenceReferenceSegment"),
                AnyNumberOf::new(vec_of_erased![Ref::new("CreateSequenceOptionsSegment")])
                    .config(|this| this.optional()),
            ])
            .to_matchable(),
        )
        .to_matchable()
        .into(),
    )]);

    postgres.replace_grammar(
        "AlterSequenceOptionsSegment",
        one_of(vec_of_erased![
            Sequence::new(vec_of_erased![
                Ref::keyword("AS"),
                Ref::new("DatatypeSegment")
            ]),
            Sequence::new(vec_of_erased![
                Ref::keyword("INCREMENT"),
                Ref::keyword("BY").optional(),
                Ref::new("NumericLiteralSegment"),
            ]),
            one_of(vec_of_erased![
                Sequence::new(vec_of_erased![
                    Ref::keyword("MINVALUE"),
                    Ref::new("NumericLiteralSegment"),
                ]),
                Sequence::new(vec_of_erased![Ref::keyword("NO"), Ref::keyword("MINVALUE")]),
            ]),
            one_of(vec_of_erased![
                Sequence::new(vec_of_erased![
                    Ref::keyword("MAXVALUE"),
                    Ref::new("NumericLiteralSegment"),
                ]),
                Sequence::new(vec_of_erased![Ref::keyword("NO"), Ref::keyword("MAXVALUE")]),
            ]),
            Sequence::new(vec_of_erased![
                Ref::keyword("SEQUENCE"),
                Ref::keyword("NAME"),
                Ref::new("SequenceReferenceSegment"),
            ]),
            Sequence::new(vec_of_erased![
                Ref::keyword("START"),
                Ref::keyword("WITH").optional(),
                Ref::new("NumericLiteralSegment"),
            ]),
            Sequence::new(vec_of_erased![
                Ref::keyword("RESTART"),
                Ref::keyword("WITH").optional(),
                Ref::new("NumericLiteralSegment"),
            ]),
            Sequence::new(vec_of_erased![
                Ref::keyword("CACHE"),
                Ref::new("NumericLiteralSegment")
            ]),
            Sequence::new(vec_of_erased![
                Ref::keyword("NO").optional(),
                Ref::keyword("CYCLE")
            ]),
            Sequence::new(vec_of_erased![
                Ref::keyword("OWNED"),
                Ref::keyword("BY"),
                one_of(vec_of_erased![
                    Ref::keyword("NONE"),
                    Ref::new("ColumnReferenceSegment")
                ]),
            ]),
        ])
        .to_matchable(),
    );

    postgres.replace_grammar(
        "AlterSequenceStatementSegment",
        Sequence::new(vec_of_erased![
            Ref::keyword("ALTER"),
            Ref::keyword("SEQUENCE"),
            Ref::new("IfExistsGrammar").optional(),
            Ref::new("SequenceReferenceSegment"),
            one_of(vec_of_erased![
                AnyNumberOf::new(vec_of_erased![Ref::new("AlterSequenceOptionsSegment")])
                    .config(|this| this.optional()),
                Sequence::new(vec_of_erased![
                    Ref::keyword("OWNER"),
                    Ref::keyword("TO"),
                    one_of(vec_of_erased![
                        Ref::new("ParameterNameSegment"),
                        Ref::keyword("CURRENT_USER"),
                        Ref::keyword("SESSION_USER"),
                    ])
                ]),
                Sequence::new(vec_of_erased![
                    Ref::keyword("RENAME"),
                    Ref::keyword("TO"),
                    Ref::new("SequenceReferenceSegment"),
                ]),
                Sequence::new(vec_of_erased![
                    Ref::keyword("SET"),
                    Ref::keyword("SCHEMA"),
                    Ref::new("SchemaReferenceSegment"),
                ]),
            ])
        ])
        .to_matchable(),
    );

    postgres.replace_grammar(
        "DropSequenceStatementSegment",
        Sequence::new(vec_of_erased![
            Ref::keyword("DROP"),
            Ref::keyword("SEQUENCE"),
            Ref::new("IfExistsGrammar").optional(),
            Delimited::new(vec_of_erased![Ref::new("SequenceReferenceSegment")]),
            Ref::new("DropBehaviorGrammar").optional(),
        ])
        .to_matchable(),
    );

    postgres.add([(
        "AnalyzeStatementSegment".into(),
        NodeMatcher::new(
            SyntaxKind::AnalyzeStatement,
            {
                let option = Sequence::new(vec_of_erased![
                    one_of(vec_of_erased![
                        Ref::keyword("VERBOSE"),
                        Ref::keyword("SKIP_LOCKED")
                    ]),
                    Ref::new("BooleanLiteralGrammar").optional(),
                ]);

                let tables_and_columns = Sequence::new(vec_of_erased![
                    Ref::new("TableReferenceSegment"),
                    Bracketed::new(vec_of_erased![Delimited::new(vec_of_erased![Ref::new(
                        "ColumnReferenceSegment"
                    )])])
                    .config(|this| this.optional()),
                ]);

                Sequence::new(vec_of_erased![
                    one_of(vec_of_erased![
                        Ref::keyword("ANALYZE"),
                        Ref::keyword("ANALYSE")
                    ]),
                    one_of(vec_of_erased![
                        Bracketed::new(vec_of_erased![Delimited::new(vec_of_erased![option])]),
                        Ref::keyword("VERBOSE")
                    ])
                    .config(|this| this.optional()),
                    Delimited::new(vec_of_erased![tables_and_columns])
                        .config(|this| this.optional()),
                ])
            }
            .to_matchable(),
        )
        .to_matchable()
        .into(),
    )]);

    postgres.replace_grammar("StatementSegment", statement_segment());

    postgres.replace_grammar(
        "CreateTriggerStatementSegment",
        Sequence::new(vec_of_erased![
            Ref::keyword("CREATE"),
            Sequence::new(vec_of_erased![Ref::keyword("OR"), Ref::keyword("REPLACE")])
                .config(|this| this.optional()),
            Ref::keyword("CONSTRAINT").optional(),
            Ref::keyword("TRIGGER"),
            Ref::new("TriggerReferenceSegment"),
            one_of(vec_of_erased![
                Ref::keyword("BEFORE"),
                Ref::keyword("AFTER"),
                Sequence::new(vec_of_erased![Ref::keyword("INSTEAD"), Ref::keyword("OF")]),
            ]),
            Delimited::new(vec_of_erased![
                Ref::keyword("INSERT"),
                Ref::keyword("DELETE"),
                Ref::keyword("TRUNCATE"),
                Sequence::new(vec_of_erased![
                    Ref::keyword("UPDATE"),
                    Sequence::new(vec_of_erased![
                        Ref::keyword("OF"),
                        Delimited::new(vec_of_erased![Ref::new("ColumnReferenceSegment")]).config(
                            |this| {
                                this.terminators =
                                    vec_of_erased![Ref::keyword("OR"), Ref::keyword("ON")];
                                this.optional();
                            }
                        ),
                    ])
                    .config(|this| this.optional()),
                ]),
            ])
            .config(|this| this.delimiter(Ref::keyword("OR"))),
            Ref::keyword("ON"),
            Ref::new("TableReferenceSegment"),
            AnyNumberOf::new(vec_of_erased![
                Sequence::new(vec_of_erased![
                    Ref::keyword("FROM"),
                    Ref::new("TableReferenceSegment"),
                ]),
                one_of(vec_of_erased![
                    Sequence::new(vec_of_erased![
                        Ref::keyword("NOT"),
                        Ref::keyword("DEFERRABLE")
                    ]),
                    Sequence::new(vec_of_erased![
                        Ref::keyword("DEFERRABLE").optional(),
                        one_of(vec_of_erased![
                            Sequence::new(vec_of_erased![
                                Ref::keyword("INITIALLY"),
                                Ref::keyword("IMMEDIATE"),
                            ]),
                            Sequence::new(vec_of_erased![
                                Ref::keyword("INITIALLY"),
                                Ref::keyword("DEFERRED"),
                            ]),
                        ]),
                    ]),
                ]),
                Sequence::new(vec_of_erased![
                    Ref::keyword("REFERENCING"),
                    one_of(vec_of_erased![Ref::keyword("OLD"), Ref::keyword("NEW")]),
                    Ref::keyword("TABLE"),
                    Ref::keyword("AS"),
                    Ref::new("TableReferenceSegment"),
                    Sequence::new(vec_of_erased![
                        one_of(vec_of_erased![Ref::keyword("OLD"), Ref::keyword("NEW")]),
                        Ref::keyword("TABLE"),
                        Ref::keyword("AS"),
                        Ref::new("TableReferenceSegment"),
                    ])
                    .config(|this| this.optional()),
                ]),
                Sequence::new(vec_of_erased![
                    Ref::keyword("FOR"),
                    Ref::keyword("EACH").optional(),
                    one_of(vec_of_erased![
                        Ref::keyword("ROW"),
                        Ref::keyword("STATEMENT")
                    ]),
                ]),
                Sequence::new(vec_of_erased![
                    Ref::keyword("WHEN"),
                    Bracketed::new(vec_of_erased![Ref::new("ExpressionSegment")]),
                ]),
            ]),
            Sequence::new(vec_of_erased![
                Ref::keyword("EXECUTE"),
                one_of(vec_of_erased![
                    Ref::keyword("FUNCTION"),
                    Ref::keyword("PROCEDURE")
                ]),
                Ref::new("FunctionSegment"),
            ]),
        ])
        .to_matchable(),
    );

    postgres.add([(
        "AlterTriggerStatementSegment".into(),
        NodeMatcher::new(
            SyntaxKind::AlterTrigger,
            Sequence::new(vec_of_erased![
                Ref::keyword("ALTER"),
                Ref::keyword("TRIGGER"),
                Ref::new("TriggerReferenceSegment"),
                Ref::keyword("ON"),
                Ref::new("TableReferenceSegment"),
                one_of(vec_of_erased![
                    Sequence::new(vec_of_erased![
                        Ref::keyword("RENAME"),
                        Ref::keyword("TO"),
                        Ref::new("TriggerReferenceSegment"),
                    ]),
                    Sequence::new(vec_of_erased![
                        Ref::keyword("NO").optional(),
                        Ref::keyword("DEPENDS"),
                        Ref::keyword("ON"),
                        Ref::keyword("EXTENSION"),
                        Ref::new("ExtensionReferenceSegment"),
                    ]),
                ]),
            ])
            .to_matchable(),
        )
        .to_matchable()
        .into(),
    )]);

    postgres.replace_grammar(
        "DropTriggerStatementSegment",
        Sequence::new(vec_of_erased![
            Ref::keyword("DROP"),
            Ref::keyword("TRIGGER"),
            Ref::new("IfExistsGrammar").optional(),
            Ref::new("TriggerReferenceSegment"),
            Ref::keyword("ON"),
            Ref::new("TableReferenceSegment"),
            Ref::new("DropBehaviorGrammar").optional(),
        ])
        .to_matchable(),
    );

    postgres.replace_grammar(
        "AliasExpressionSegment",
        Sequence::new(vec_of_erased![
            Ref::keyword("AS").optional(),
            one_of(vec_of_erased![
                Sequence::new(vec_of_erased![
                    Ref::new("SingleIdentifierGrammar"),
                    Bracketed::new(vec_of_erased![Ref::new("SingleIdentifierListSegment")])
                        .config(|this| this.optional()),
                ]),
                Sequence::new(vec_of_erased![
                    Ref::new("SingleIdentifierGrammar").optional(),
                    Bracketed::new(vec_of_erased![Delimited::new(vec_of_erased![
                        Sequence::new(vec_of_erased![
                            Ref::new("ParameterNameSegment"),
                            Ref::new("DatatypeSegment"),
                        ])
                    ])]),
                ]),
            ]),
        ])
        .to_matchable(),
    );

    postgres.add([(
        "AsAliasExpressionSegment".into(),
        NodeMatcher::new(
            SyntaxKind::AliasExpression,
            Sequence::new(vec_of_erased![
                MetaSegment::indent(),
                Ref::keyword("AS"),
                Ref::new("SingleIdentifierGrammar"),
                MetaSegment::dedent(),
            ])
            .to_matchable(),
        )
        .to_matchable()
        .into(),
    )]);

    postgres.add([(
        "OperationClassReferenceSegment".into(),
        NodeMatcher::new(
            SyntaxKind::OperationClassReference,
            postgres
                .grammar("ObjectReferenceSegment")
                .match_grammar()
                .unwrap(),
        )
        .to_matchable()
        .into(),
    )]);

    postgres.add([
        (
            "ConflictActionSegment".into(),
            NodeMatcher::new(
                SyntaxKind::ConflictAction,
                Sequence::new(vec_of_erased![
                    Ref::keyword("DO"),
                    one_of(vec_of_erased![
                        Ref::keyword("NOTHING"),
                        Sequence::new(vec_of_erased![
                            Ref::keyword("UPDATE"),
                            Ref::keyword("SET"),
                            Delimited::new(vec_of_erased![one_of(vec_of_erased![
                                Sequence::new(vec_of_erased![
                                    Ref::new("ColumnReferenceSegment"),
                                    Ref::new("EqualsSegment"),
                                    one_of(vec_of_erased![
                                        Ref::new("ExpressionSegment"),
                                        Ref::keyword("DEFAULT")
                                    ])
                                ]),
                                Sequence::new(vec_of_erased![
                                    Bracketed::new(vec_of_erased![Delimited::new(vec_of_erased![
                                        Ref::new("ColumnReferenceSegment")
                                    ])]),
                                    Ref::new("EqualsSegment"),
                                    Ref::keyword("ROW").optional(),
                                    Bracketed::new(vec_of_erased![Delimited::new(vec_of_erased![
                                        one_of(vec_of_erased![
                                            Ref::new("ExpressionSegment"),
                                            Ref::keyword("DEFAULT")
                                        ])
                                    ])])
                                ]),
                                Sequence::new(vec_of_erased![
                                    Bracketed::new(vec_of_erased![Delimited::new(vec_of_erased![
                                        Ref::new("ColumnReferenceSegment")
                                    ])]),
                                    Ref::new("EqualsSegment"),
                                    Bracketed::new(vec_of_erased![Ref::new("SelectableGrammar")])
                                ])
                            ])]),
                            Sequence::new(vec_of_erased![
                                Ref::keyword("WHERE"),
                                Ref::new("ExpressionSegment")
                            ])
                            .config(|this| this.optional()),
                        ])
                    ])
                ])
                .to_matchable(),
            )
            .to_matchable()
            .into(),
        ),
        (
            "ConflictTargetSegment".into(),
            NodeMatcher::new(
                SyntaxKind::ConflictTarget,
                one_of(vec_of_erased![
                    Sequence::new(vec_of_erased![
                        Bracketed::new(vec_of_erased![Delimited::new(vec_of_erased![
                            Sequence::new(vec_of_erased![
                                one_of(vec_of_erased![
                                    Ref::new("ColumnReferenceSegment"),
                                    Bracketed::new(vec_of_erased![Ref::new("ExpressionSegment")])
                                ]),
                                Sequence::new(vec_of_erased![
                                    Ref::keyword("COLLATE"),
                                    Ref::new("CollationReferenceSegment")
                                ])
                                .config(|this| this.optional()),
                                Ref::new("OperationClassReferenceSegment").optional()
                            ])
                        ])]),
                        Sequence::new(vec_of_erased![
                            Ref::keyword("WHERE"),
                            Ref::new("ExpressionSegment")
                        ])
                        .config(|this| this.optional()),
                    ]),
                    Sequence::new(vec_of_erased![
                        Ref::keyword("ON"),
                        Ref::keyword("CONSTRAINT"),
                        Ref::new("ParameterNameSegment")
                    ])
                ])
                .to_matchable(),
            )
            .to_matchable()
            .into(),
        ),
    ]);

    postgres.replace_grammar(
        "InsertStatementSegment",
        Sequence::new(vec_of_erased![
            Ref::keyword("INSERT"),
            Ref::keyword("INTO"),
            Ref::new("TableReferenceSegment"),
            Ref::new("AsAliasExpressionSegment").optional(),
            Ref::new("BracketedColumnReferenceListGrammar").optional(),
            Sequence::new(vec_of_erased![
                Ref::keyword("OVERRIDING"),
                one_of(vec_of_erased![Ref::keyword("SYSTEM"), Ref::keyword("USER")]),
                Ref::keyword("VALUE")
            ])
            .config(|this| this.optional()),
            one_of(vec_of_erased![
                Sequence::new(vec_of_erased![
                    Ref::keyword("DEFAULT"),
                    Ref::keyword("VALUES")
                ]),
                Ref::new("SelectableGrammar"),
            ]),
            Sequence::new(vec_of_erased![
                Ref::keyword("ON"),
                Ref::keyword("CONFLICT"),
                Ref::new("ConflictTargetSegment").optional(),
                Ref::new("ConflictActionSegment")
            ])
            .config(|this| this.optional()),
            Sequence::new(vec_of_erased![
                Ref::keyword("RETURNING"),
                one_of(vec_of_erased![
                    Ref::new("StarSegment"),
                    Delimited::new(vec_of_erased![Sequence::new(vec_of_erased![
                        Ref::new("ExpressionSegment"),
                        Ref::new("AsAliasExpressionSegment").optional(),
                    ])])
                ])
            ])
            .config(|this| this.optional()),
        ])
        .to_matchable(),
    );

    postgres.replace_grammar(
        "DropTypeStatementSegment",
        Sequence::new(vec_of_erased![
            Ref::keyword("DROP"),
            Ref::keyword("TYPE"),
            Ref::new("IfExistsGrammar").optional(),
            Delimited::new(vec_of_erased![Ref::new("DatatypeSegment")]),
            Ref::new("DropBehaviorGrammar").optional(),
        ])
        .to_matchable(),
    );

    postgres.add([
        (
            "SetStatementSegment".into(),
            NodeMatcher::new(
                SyntaxKind::SetStatement,
                Sequence::new(vec_of_erased![
                    Ref::keyword("SET"),
                    one_of(vec_of_erased![
                        Ref::keyword("SESSION"),
                        Ref::keyword("LOCAL")
                    ])
                    .config(|this| this.optional()),
                    one_of(vec_of_erased![
                        Sequence::new(vec_of_erased![
                            Ref::new("ParameterNameSegment"),
                            one_of(vec_of_erased![
                                Ref::keyword("TO"),
                                Ref::new("EqualsSegment")
                            ]),
                            one_of(vec_of_erased![
                                Ref::keyword("DEFAULT"),
                                Delimited::new(vec_of_erased![
                                    Ref::new("LiteralGrammar"),
                                    Ref::new("NakedIdentifierSegment"),
                                    Ref::new("OnKeywordAsIdentifierSegment"),
                                ]),
                            ]),
                        ]),
                        Sequence::new(vec_of_erased![
                            Ref::keyword("TIME"),
                            Ref::keyword("ZONE"),
                            one_of(vec_of_erased![
                                Ref::new("QuotedLiteralSegment"),
                                Ref::keyword("LOCAL"),
                                Ref::keyword("DEFAULT")
                            ]),
                        ]),
                        Sequence::new(vec_of_erased![
                            Ref::keyword("SCHEMA"),
                            Ref::new("QuotedLiteralSegment"),
                        ]),
                        Sequence::new(vec_of_erased![
                            Ref::keyword("ROLE"),
                            one_of(vec_of_erased![
                                Ref::keyword("NONE"),
                                Ref::new("RoleReferenceSegment"),
                            ]),
                        ]),
                    ]),
                ])
                .to_matchable(),
            )
            .to_matchable()
            .into(),
        ),
        (
            "CreatePolicyStatementSegment".into(),
            NodeMatcher::new(
                SyntaxKind::CreatePolicyStatement,
                Sequence::new(vec_of_erased![
                    Ref::keyword("CREATE"),
                    Ref::keyword("POLICY"),
                    Ref::new("ObjectReferenceSegment"),
                    Ref::keyword("ON"),
                    Ref::new("TableReferenceSegment"),
                    Sequence::new(vec_of_erased![
                        Ref::keyword("AS"),
                        one_of(vec_of_erased![
                            Ref::keyword("PERMISSIVE"),
                            Ref::keyword("RESTRICTIVE")
                        ])
                    ])
                    .config(|this| this.optional()),
                    Sequence::new(vec_of_erased![
                        Ref::keyword("FOR"),
                        one_of(vec_of_erased![
                            Ref::keyword("ALL"),
                            Ref::keyword("SELECT"),
                            Ref::keyword("INSERT"),
                            Ref::keyword("UPDATE"),
                            Ref::keyword("DELETE")
                        ])
                    ])
                    .config(|this| this.optional()),
                    Sequence::new(vec_of_erased![
                        Ref::keyword("TO"),
                        Delimited::new(vec_of_erased![one_of(vec_of_erased![
                            Ref::new("ObjectReferenceSegment"),
                            Ref::keyword("PUBLIC"),
                            Ref::keyword("CURRENT_ROLE"),
                            Ref::keyword("CURRENT_USER"),
                            Ref::keyword("SESSION_USER")
                        ])])
                    ])
                    .config(|this| this.optional()),
                    Sequence::new(vec_of_erased![
                        Ref::keyword("USING"),
                        Bracketed::new(vec_of_erased![Ref::new("ExpressionSegment")])
                    ])
                    .config(|this| this.optional()),
                    Sequence::new(vec_of_erased![
                        Ref::keyword("WITH"),
                        Ref::keyword("CHECK"),
                        Bracketed::new(vec_of_erased![Ref::new("ExpressionSegment")])
                    ])
                    .config(|this| this.optional())
                ])
                .to_matchable(),
            )
            .to_matchable()
            .into(),
        ),
        (
            "CallStoredProcedureSegment".into(),
            NodeMatcher::new(
                SyntaxKind::CallStatement,
                Sequence::new(vec_of_erased![
                    Ref::keyword("CALL"),
                    Ref::new("FunctionSegment")
                ])
                .to_matchable(),
            )
            .to_matchable()
            .into(),
        ),
        (
            "CreateDomainStatementSegment".into(),
            NodeMatcher::new(
                SyntaxKind::CreateDomainStatement,
                Sequence::new(vec_of_erased![
                    Ref::keyword("CREATE"),
                    Ref::keyword("DOMAIN"),
                    Ref::new("ObjectReferenceSegment"),
                    Sequence::new(vec_of_erased![Ref::keyword("AS"),])
                        .config(|this| this.optional()),
                    Ref::new("DatatypeSegment"),
                    Sequence::new(vec_of_erased![
                        Ref::keyword("COLLATE"),
                        Ref::new("CollationReferenceSegment"),
                    ])
                    .config(|this| this.optional()),
                    Sequence::new(vec_of_erased![
                        Ref::keyword("DEFAULT"),
                        Ref::new("ExpressionSegment"),
                    ])
                    .config(|this| this.optional()),
                    AnyNumberOf::new(vec_of_erased![Sequence::new(vec_of_erased![
                        Sequence::new(vec_of_erased![
                            Ref::keyword("CONSTRAINT"),
                            Ref::new("ObjectReferenceSegment"),
                        ])
                        .config(|this| this.optional()),
                        one_of(vec_of_erased![
                            Sequence::new(vec_of_erased![
                                Ref::keyword("NOT").optional(),
                                Ref::keyword("NULL"),
                            ]),
                            Sequence::new(vec_of_erased![
                                Ref::keyword("CHECK"),
                                Ref::new("ExpressionSegment"),
                            ]),
                        ]),
                    ])]),
                ])
                .to_matchable(),
            )
            .to_matchable()
            .into(),
        ),
        (
            "AlterDomainStatementSegment".into(),
            NodeMatcher::new(
                SyntaxKind::AlterDomainStatement,
                Sequence::new(vec_of_erased![
                    Ref::keyword("ALTER"),
                    Ref::keyword("DOMAIN"),
                    Ref::new("ObjectReferenceSegment"),
                    one_of(vec_of_erased![
                        Sequence::new(vec_of_erased![
                            Ref::keyword("SET"),
                            Ref::keyword("DEFAULT"),
                            Ref::new("ExpressionSegment"),
                        ]),
                        Sequence::new(vec_of_erased![
                            Ref::keyword("DROP"),
                            Ref::keyword("DEFAULT"),
                        ]),
                        Sequence::new(vec_of_erased![
                            one_of(vec_of_erased![Ref::keyword("SET"), Ref::keyword("DROP"),]),
                            Ref::keyword("NOT"),
                            Ref::keyword("NULL"),
                        ]),
                        Sequence::new(vec_of_erased![
                            Ref::keyword("ADD"),
                            Sequence::new(vec_of_erased![
                                Ref::keyword("CONSTRAINT"),
                                Ref::new("ObjectReferenceSegment"),
                            ])
                            .config(|this| this.optional()),
                            one_of(vec_of_erased![
                                Sequence::new(vec_of_erased![
                                    Ref::keyword("NOT").optional(),
                                    Ref::keyword("NULL"),
                                ]),
                                Sequence::new(vec_of_erased![
                                    Ref::keyword("CHECK"),
                                    Ref::new("ExpressionSegment"),
                                ]),
                            ]),
                            Sequence::new(vec_of_erased![
                                Ref::keyword("NOT"),
                                Ref::keyword("VALID"),
                            ])
                            .config(|this| this.optional()),
                        ]),
                        Sequence::new(vec_of_erased![
                            Ref::keyword("DROP"),
                            Ref::keyword("CONSTRAINT"),
                            Ref::new("IfExistsGrammar").optional(),
                            Ref::new("ObjectReferenceSegment"),
                            one_of(vec_of_erased![
                                Ref::keyword("RESTRICT"),
                                Ref::keyword("CASCADE"),
                            ])
                            .config(|this| this.optional()),
                        ]),
                        Sequence::new(vec_of_erased![
                            Ref::keyword("RENAME"),
                            Ref::keyword("CONSTRAINT"),
                            Ref::new("ObjectReferenceSegment"),
                            Ref::keyword("TO"),
                            Ref::new("ObjectReferenceSegment"),
                        ]),
                        Sequence::new(vec_of_erased![
                            Ref::keyword("VALIDATE"),
                            Ref::keyword("CONSTRAINT"),
                            Ref::new("ObjectReferenceSegment"),
                        ]),
                        Sequence::new(vec_of_erased![
                            Ref::keyword("OWNER"),
                            Ref::keyword("TO"),
                            one_of(vec_of_erased![
                                Ref::new("ObjectReferenceSegment"),
                                Ref::keyword("CURRENT_ROLE"),
                                Ref::keyword("CURRENT_USER"),
                                Ref::keyword("SESSION_USER"),
                            ]),
                        ]),
                        Sequence::new(vec_of_erased![
                            Ref::keyword("RENAME"),
                            Ref::keyword("TO"),
                            Ref::new("ObjectReferenceSegment"),
                        ]),
                        Sequence::new(vec_of_erased![
                            Ref::keyword("SET"),
                            Ref::keyword("SCHEMA"),
                            Ref::new("ObjectReferenceSegment"),
                        ]),
                    ]),
                ])
                .to_matchable(),
            )
            .to_matchable()
            .into(),
        ),
        (
            "DropDomainStatementSegment".into(),
            NodeMatcher::new(
                SyntaxKind::DropDomainStatement,
                Sequence::new(vec_of_erased![
                    Ref::keyword("DROP"),
                    Ref::keyword("DOMAIN"),
                    Ref::new("IfExistsGrammar").optional(),
                    Delimited::new(vec_of_erased![Ref::new("ObjectReferenceSegment")]),
                    Ref::new("DropBehaviorGrammar").optional(),
                ])
                .to_matchable(),
            )
            .to_matchable()
            .into(),
        ),
        (
            "DropPolicyStatementSegment".into(),
            NodeMatcher::new(
                SyntaxKind::DropPolicyStatement,
                Sequence::new(vec_of_erased![
                    Ref::keyword("DROP"),
                    Ref::keyword("POLICY"),
                    Ref::new("IfExistsGrammar").optional(),
                    Ref::new("ObjectReferenceSegment"),
                    Ref::keyword("ON"),
                    Ref::new("TableReferenceSegment"),
                    Ref::new("DropBehaviorGrammar").optional(),
                ])
                .to_matchable(),
            )
            .to_matchable()
            .into(),
        ),
        (
            "LoadStatementSegment".into(),
            NodeMatcher::new(
                SyntaxKind::LoadStatement,
                Sequence::new(vec_of_erased![
                    Ref::keyword("LOAD"),
                    Ref::new("QuotedLiteralSegment"),
                ])
                .to_matchable(),
            )
            .to_matchable()
            .into(),
        ),
        (
            "ResetStatementSegment".into(),
            NodeMatcher::new(
                SyntaxKind::ResetStatement,
                Sequence::new(vec_of_erased![
                    Ref::keyword("RESET"),
                    one_of(vec_of_erased![
                        Ref::keyword("ALL"),
                        Ref::keyword("ROLE"),
                        Ref::new("ParameterNameSegment"),
                    ]),
                ])
                .to_matchable(),
            )
            .to_matchable()
            .into(),
        ),
        (
            "DiscardStatementSegment".into(),
            NodeMatcher::new(
                SyntaxKind::DiscardStatement,
                Sequence::new(vec_of_erased![
                    Ref::keyword("DISCARD"),
                    one_of(vec_of_erased![
                        Ref::keyword("ALL"),
                        Ref::keyword("PLANS"),
                        Ref::keyword("SEQUENCES"),
                        Ref::keyword("TEMPORARY"),
                        Ref::keyword("TEMP"),
                    ]),
                ])
                .to_matchable(),
            )
            .to_matchable()
            .into(),
        ),
        (
            "ListenStatementSegment".into(),
            NodeMatcher::new(
                SyntaxKind::ListenStatement,
                Sequence::new(vec_of_erased![
                    Ref::keyword("LISTEN"),
                    Ref::new("SingleIdentifierGrammar"),
                ])
                .to_matchable(),
            )
            .to_matchable()
            .into(),
        ),
        (
            "NotifyStatementSegment".into(),
            NodeMatcher::new(
                SyntaxKind::NotifyStatement,
                Sequence::new(vec_of_erased![
                    Ref::keyword("NOTIFY"),
                    Ref::new("SingleIdentifierGrammar"),
                    Sequence::new(vec_of_erased![
                        Ref::new("CommaSegment"),
                        Ref::new("QuotedLiteralSegment"),
                    ])
                    .config(|this| this.optional()),
                ])
                .to_matchable(),
            )
            .to_matchable()
            .into(),
        ),
        (
            "UnlistenStatementSegment".into(),
            NodeMatcher::new(
                SyntaxKind::UnlistenStatement,
                Sequence::new(vec_of_erased![
                    Ref::keyword("UNLISTEN"),
                    one_of(vec_of_erased![
                        Ref::new("SingleIdentifierGrammar"),
                        Ref::new("StarSegment"),
                    ]),
                ])
                .to_matchable(),
            )
            .to_matchable()
            .into(),
        ),
    ]);

    postgres.replace_grammar(
        "TruncateStatementSegment",
        Sequence::new(vec_of_erased![
            Ref::keyword("TRUNCATE"),
            Ref::keyword("TABLE").optional(),
            Delimited::new(vec_of_erased![one_of(vec_of_erased![
                Sequence::new(vec_of_erased![
                    Ref::keyword("ONLY").optional(),
                    Ref::new("TableReferenceSegment"),
                ]),
                Sequence::new(vec_of_erased![
                    Ref::new("TableReferenceSegment"),
                    Ref::new("StarSegment").optional(),
                ]),
            ])]),
            Sequence::new(vec_of_erased![
                one_of(vec_of_erased![
                    Ref::keyword("RESTART"),
                    Ref::keyword("CONTINUE")
                ]),
                Ref::keyword("IDENTITY")
            ])
            .config(|this| this.optional()),
            Ref::new("DropBehaviorGrammar").optional(),
        ])
        .to_matchable(),
    );

    postgres.add([
        (
            "CopyStatementSegment".into(),
            NodeMatcher::new(SyntaxKind::CopyStatement, {
                let _target_subset = one_of(vec_of_erased![
                    Ref::new("QuotedLiteralSegment"),
                    Sequence::new(vec_of_erased![
                        Ref::keyword("PROGRAM"),
                        Ref::new("QuotedLiteralSegment")
                    ])
                ]);

                let _table_definition = Sequence::new(vec_of_erased![
                    Ref::new("TableReferenceSegment"),
                    Bracketed::new(vec_of_erased![Delimited::new(vec_of_erased![Ref::new(
                        "ColumnReferenceSegment"
                    )])])
                    .config(|this| this.optional()),
                ]);

                let _option = Sequence::new(vec_of_erased![
                    Ref::keyword("WITH").optional(),
                    Bracketed::new(vec_of_erased![Delimited::new(vec_of_erased![any_set_of(
                        vec_of_erased![
                            Sequence::new(vec_of_erased![
                                Ref::keyword("FORMAT"),
                                Ref::new("SingleIdentifierGrammar")
                            ]),
                            Sequence::new(vec_of_erased![
                                Ref::keyword("FREEZE"),
                                Ref::new("BooleanLiteralGrammar").optional()
                            ]),
                            Sequence::new(vec_of_erased![
                                Ref::keyword("DELIMITER"),
                                Ref::new("QuotedLiteralSegment")
                            ]),
                            Sequence::new(vec_of_erased![
                                Ref::keyword("NULL"),
                                Ref::new("QuotedLiteralSegment")
                            ]),
                            Sequence::new(vec_of_erased![
                                Ref::keyword("HEADER"),
                                Ref::new("BooleanLiteralGrammar").optional()
                            ]),
                            Sequence::new(vec_of_erased![
                                Ref::keyword("QUOTE"),
                                Ref::new("QuotedLiteralSegment")
                            ]),
                            Sequence::new(vec_of_erased![
                                Ref::keyword("ESCAPE"),
                                Ref::new("QuotedLiteralSegment")
                            ]),
                            Sequence::new(vec_of_erased![
                                Ref::keyword("FORCE_QUOTE"),
                                one_of(vec_of_erased![
                                    Bracketed::new(vec_of_erased![Delimited::new(vec_of_erased![
                                        Ref::new("ColumnReferenceSegment")
                                    ])]),
                                    Ref::new("StarSegment")
                                ])
                            ]),
                            Sequence::new(vec_of_erased![
                                Ref::keyword("FORCE_NOT_NULL"),
                                Bracketed::new(vec_of_erased![Delimited::new(vec_of_erased![
                                    Ref::new("ColumnReferenceSegment")
                                ])])
                            ]),
                            Sequence::new(vec_of_erased![
                                Ref::keyword("FORCE_NULL"),
                                Bracketed::new(vec_of_erased![Delimited::new(vec_of_erased![
                                    Ref::new("ColumnReferenceSegment")
                                ])])
                            ]),
                            Sequence::new(vec_of_erased![
                                Ref::keyword("ENCODING"),
                                Ref::new("QuotedLiteralSegment")
                            ])
                        ]
                    )])])
                ])
                .config(|this| this.optional());

                Sequence::new(vec_of_erased![
                    Ref::keyword("COPY"),
                    one_of(vec_of_erased![
                        Sequence::new(vec_of_erased![
                            _table_definition.clone(),
                            Ref::keyword("FROM"),
                            one_of(vec_of_erased![
                                _target_subset.clone(),
                                Ref::keyword("STDIN")
                            ]),
                            _option.clone(),
                            Sequence::new(vec_of_erased![
                                Ref::keyword("WHERE"),
                                Ref::new("ExpressionSegment")
                            ])
                            .config(|this| this.optional())
                        ]),
                        Sequence::new(vec_of_erased![
                            one_of(vec_of_erased![
                                _table_definition.clone(),
                                Bracketed::new(vec_of_erased![Ref::new(
                                    "UnorderedSelectStatementSegment"
                                )])
                            ]),
                            Ref::keyword("TO"),
                            one_of(vec_of_erased![_target_subset, Ref::keyword("STDOUT")]),
                            _option
                        ])
                    ])
                ])
                .to_matchable()
            })
            .to_matchable()
            .into(),
        ),
        (
            "AlterSchemaStatementSegment".into(),
            NodeMatcher::new(
                SyntaxKind::AlterSchemaStatement,
                Sequence::new(vec_of_erased![
                    Ref::keyword("ALTER"),
                    Ref::keyword("SCHEMA"),
                    Ref::new("SchemaReferenceSegment"),
                    one_of(vec_of_erased![
                        Sequence::new(vec_of_erased![
                            Ref::keyword("RENAME"),
                            Ref::keyword("TO"),
                            Ref::new("SchemaReferenceSegment"),
                        ]),
                        Sequence::new(vec_of_erased![
                            Ref::keyword("OWNER"),
                            Ref::keyword("TO"),
                            Ref::new("RoleReferenceSegment"),
                        ]),
                    ]),
                ])
                .to_matchable(),
            )
            .to_matchable()
            .into(),
        ),
        (
            "LockTableStatementSegment".into(),
            NodeMatcher::new(
                SyntaxKind::LockTableStatement,
                Sequence::new(vec_of_erased![
                    Ref::keyword("LOCK"),
                    Ref::keyword("TABLE").optional(),
                    Ref::keyword("ONLY").optional(),
                    one_of(vec_of_erased![
                        Delimited::new(vec_of_erased![Ref::new("TableReferenceSegment")]),
                        Ref::new("StarSegment"),
                    ]),
                    Sequence::new(vec_of_erased![
                        Ref::keyword("IN"),
                        one_of(vec_of_erased![
                            Sequence::new(vec_of_erased![
                                Ref::keyword("ACCESS"),
                                Ref::keyword("SHARE")
                            ]),
                            Sequence::new(vec_of_erased![
                                Ref::keyword("ROW"),
                                Ref::keyword("SHARE")
                            ]),
                            Sequence::new(vec_of_erased![
                                Ref::keyword("ROW"),
                                Ref::keyword("EXCLUSIVE")
                            ]),
                            Sequence::new(vec_of_erased![
                                Ref::keyword("SHARE"),
                                Ref::keyword("UPDATE"),
                                Ref::keyword("EXCLUSIVE")
                            ]),
                            Ref::keyword("SHARE"),
                            Sequence::new(vec_of_erased![
                                Ref::keyword("SHARE"),
                                Ref::keyword("ROW"),
                                Ref::keyword("EXCLUSIVE")
                            ]),
                            Ref::keyword("EXCLUSIVE"),
                            Sequence::new(vec_of_erased![
                                Ref::keyword("ACCESS"),
                                Ref::keyword("EXCLUSIVE")
                            ]),
                        ]),
                        Ref::keyword("MODE"),
                    ])
                    .config(|this| this.optional()),
                    Ref::keyword("NOWAIT").optional(),
                ])
                .to_matchable(),
            )
            .to_matchable()
            .into(),
        ),
        (
            "ClusterStatementSegment".into(),
            NodeMatcher::new(
                SyntaxKind::ClusterStatement,
                Sequence::new(vec_of_erased![
                    Ref::keyword("CLUSTER"),
                    Ref::keyword("VERBOSE").optional(),
                    one_of(vec_of_erased![
                        Sequence::new(vec_of_erased![
                            Ref::new("TableReferenceSegment"),
                            Sequence::new(vec_of_erased![
                                Ref::keyword("USING"),
                                Ref::new("IndexReferenceSegment"),
                            ])
                            .config(|this| this.optional()),
                        ]),
                        Sequence::new(vec_of_erased![
                            Ref::new("IndexReferenceSegment"),
                            Ref::keyword("ON"),
                            Ref::new("TableReferenceSegment"),
                        ]),
                    ])
                    .config(|this| this.optional()),
                ])
                .to_matchable(),
            )
            .to_matchable()
            .into(),
        ),
        (
            "LanguageClauseSegment".into(),
            NodeMatcher::new(
                SyntaxKind::LanguageClause,
                Sequence::new(vec_of_erased![
                    Ref::keyword("LANGUAGE"),
                    one_of(vec_of_erased![
                        Ref::new("NakedIdentifierSegment"),
                        Ref::new("SingleQuotedIdentifierSegment"),
                    ]),
                ])
                .to_matchable(),
            )
            .to_matchable()
            .into(),
        ),
        (
            "DoStatementSegment".into(),
            NodeMatcher::new(
                SyntaxKind::DoStatement,
                Sequence::new(vec_of_erased![
                    Ref::keyword("DO"),
                    one_of(vec_of_erased![
                        Sequence::new(vec_of_erased![
                            Ref::new("LanguageClauseSegment").optional(),
                            Ref::new("QuotedLiteralSegment"),
                        ]),
                        Sequence::new(vec_of_erased![
                            Ref::new("QuotedLiteralSegment"),
                            Ref::new("LanguageClauseSegment").optional(),
                        ]),
                    ]),
                ])
                .to_matchable(),
            )
            .to_matchable()
            .into(),
        ),
    ]);

    postgres.replace_grammar(
        "CTEDefinitionSegment",
        Sequence::new(vec_of_erased![
            Ref::new("SingleIdentifierGrammar"),
            Ref::new("CTEColumnList").optional(),
            Ref::keyword("AS"),
            Sequence::new(vec_of_erased![
                Ref::keyword("NOT").optional(),
                Ref::keyword("MATERIALIZED"),
            ])
            .config(|this| this.optional()),
            Bracketed::new(vec_of_erased![Ref::new("SelectableGrammar"),])
                .config(|this| this.parse_mode = ParseMode::Greedy),
            one_of(vec_of_erased![
                Sequence::new(vec_of_erased![
                    Ref::keyword("SEARCH"),
                    one_of(vec_of_erased![
                        Ref::keyword("BREADTH"),
                        Ref::keyword("DEPTH"),
                    ]),
                    Ref::keyword("FIRST"),
                    Ref::keyword("BY"),
                    Ref::new("ColumnReferenceSegment"),
                    Ref::keyword("SET"),
                    Ref::new("ColumnReferenceSegment"),
                ]),
                Sequence::new(vec_of_erased![
                    Ref::keyword("CYCLE"),
                    Ref::new("ColumnReferenceSegment"),
                    Ref::keyword("SET"),
                    Ref::new("ColumnReferenceSegment"),
                    Ref::keyword("USING"),
                    Ref::new("ColumnReferenceSegment"),
                ]),
            ])
            .config(|this| this.optional()),
        ])
        .to_matchable(),
    );

    postgres.replace_grammar(
        "ValuesClauseSegment",
        Sequence::new(vec_of_erased![
            Ref::keyword("VALUES"),
            Delimited::new(vec_of_erased![Bracketed::new(vec_of_erased![
                Delimited::new(vec_of_erased![
                    Ref::new("ExpressionSegment"),
                    Ref::keyword("DEFAULT")
                ])
                .config(|this| this.parse_mode = ParseMode::Greedy),
            ])]),
            Ref::new("AliasExpressionSegment").optional(),
            Ref::new("OrderByClauseSegment").optional(),
            Ref::new("LimitClauseSegment").optional(),
        ])
        .to_matchable(),
    );

    postgres.replace_grammar(
        "DeleteStatementSegment",
        Sequence::new(vec_of_erased![
            Ref::keyword("DELETE"),
            Ref::keyword("FROM"),
            Ref::keyword("ONLY").optional(),
            Ref::new("TableReferenceSegment"),
            Ref::new("StarSegment").optional(),
            Ref::new("AliasExpressionSegment").optional(),
            Sequence::new(vec_of_erased![
                Ref::keyword("USING"),
                MetaSegment::indent(),
                Delimited::new(vec_of_erased![Sequence::new(vec_of_erased![
                    Ref::new("TableExpressionSegment"),
                    Ref::new("AliasExpressionSegment").optional(),
                ])]),
                MetaSegment::dedent(),
            ])
            .config(|this| this.optional()),
            one_of(vec_of_erased![
                Sequence::new(vec_of_erased![
                    Ref::keyword("WHERE"),
                    Ref::keyword("CURRENT"),
                    Ref::keyword("OF"),
                    Ref::new("ObjectReferenceSegment"),
                ]),
                Ref::new("WhereClauseSegment"),
            ])
            .config(|this| this.optional()),
            Sequence::new(vec_of_erased![
                Ref::keyword("RETURNING"),
                one_of(vec_of_erased![
                    Ref::new("StarSegment"),
                    Delimited::new(vec_of_erased![Sequence::new(vec_of_erased![
                        Ref::new("ExpressionSegment"),
                        Ref::new("AliasExpressionSegment").optional(),
                    ])]),
                ]),
            ])
            .config(|this| this.optional()),
        ])
        .to_matchable(),
    );

    postgres.add([
        (
            "SetClauseSegment".into(),
            NodeMatcher::new(
                SyntaxKind::SetClause,
                Sequence::new(vec_of_erased![one_of(vec_of_erased![
                    Sequence::new(vec_of_erased![
                        Ref::new("ColumnReferenceSegment"),
                        Ref::new("ArrayAccessorSegment").optional(),
                        Ref::new("EqualsSegment"),
                        one_of(vec_of_erased![
                            Ref::new("LiteralGrammar"),
                            Ref::new("BareFunctionSegment"),
                            Ref::new("FunctionSegment"),
                            Ref::new("ColumnReferenceSegment"),
                            Ref::new("ExpressionSegment"),
                            Ref::keyword("DEFAULT"),
                        ]),
                        AnyNumberOf::new(vec_of_erased![Ref::new("ShorthandCastSegment")]),
                    ]),
                    Sequence::new(vec_of_erased![
                        Bracketed::new(vec_of_erased![Delimited::new(vec_of_erased![Ref::new(
                            "ColumnReferenceSegment"
                        ),])]),
                        Ref::new("EqualsSegment"),
                        Bracketed::new(vec_of_erased![one_of(vec_of_erased![
                            Ref::new("SelectableGrammar"),
                            Delimited::new(vec_of_erased![Sequence::new(vec_of_erased![
                                one_of(vec_of_erased![
                                    Ref::new("LiteralGrammar"),
                                    Ref::new("BareFunctionSegment"),
                                    Ref::new("FunctionSegment"),
                                    Ref::new("ColumnReferenceSegment"),
                                    Ref::new("ExpressionSegment"),
                                    Ref::keyword("DEFAULT"),
                                ]),
                                AnyNumberOf::new(vec_of_erased![Ref::new("ShorthandCastSegment")]),
                            ])])
                        ])]),
                    ]),
                ]),])
                .to_matchable(),
            )
            .to_matchable()
            .into(),
        ),
        (
            "UpdateStatementSegment".into(),
            NodeMatcher::new(
                SyntaxKind::UpdateStatement,
                Sequence::new(vec_of_erased![
                    Ref::keyword("UPDATE"),
                    Ref::keyword("ONLY").optional(),
                    Ref::new("TableReferenceSegment"),
                    Ref::new("AliasExpressionSegment")
                        .exclude(Ref::keyword("SET"))
                        .optional(),
                    Ref::new("SetClauseListSegment"),
                    Ref::new("FromClauseSegment").optional(),
                    one_of(vec_of_erased![
                        Sequence::new(vec_of_erased![
                            Ref::keyword("WHERE"),
                            Ref::keyword("CURRENT"),
                            Ref::keyword("OF"),
                            Ref::new("ObjectReferenceSegment"),
                        ]),
                        Ref::new("WhereClauseSegment"),
                    ])
                    .config(|this| this.optional()),
                    Sequence::new(vec_of_erased![
                        Ref::keyword("RETURNING"),
                        one_of(vec_of_erased![
                            Ref::new("StarSegment"),
                            Delimited::new(vec_of_erased![Sequence::new(vec_of_erased![
                                Ref::new("ExpressionSegment"),
                                Ref::new("AliasExpressionSegment").optional(),
                            ])])
                        ]),
                    ])
                    .config(|this| this.optional()),
                ])
                .to_matchable(),
            )
            .to_matchable()
            .into(),
        ),
        (
            "CreateTypeStatementSegment".into(),
            NodeMatcher::new(
                SyntaxKind::CreateTypeStatement,
                Sequence::new(vec_of_erased![
                    Ref::keyword("CREATE"),
                    Ref::keyword("TYPE"),
                    Ref::new("ObjectReferenceSegment"),
                    Sequence::new(vec_of_erased![
                        Ref::keyword("AS"),
                        one_of(vec_of_erased![Ref::keyword("ENUM"), Ref::keyword("RANGE"),])
                            .config(|this| this.optional()),
                    ])
                    .config(|this| this.optional()),
                    Bracketed::new(vec_of_erased![Delimited::new(vec_of_erased![
                        Anything::new()
                    ])
                    .config(|this| this.optional())])
                    .config(|this| this.optional()),
                ])
                .to_matchable(),
            )
            .to_matchable()
            .into(),
        ),
        (
            "AlterTypeStatementSegment".into(),
            NodeMatcher::new(
                SyntaxKind::AlterTypeStatement,
                Sequence::new(vec_of_erased![
                    Ref::keyword("ALTER"),
                    Ref::keyword("TYPE"),
                    Ref::new("ObjectReferenceSegment"),
                    one_of(vec_of_erased![
                        Sequence::new(vec_of_erased![
                            Ref::keyword("OWNER"),
                            Ref::keyword("TO"),
                            one_of(vec_of_erased![
                                Ref::keyword("CURRENT_USER"),
                                Ref::keyword("SESSION_USER"),
                                Ref::keyword("CURRENT_ROLE"),
                                Ref::new("ObjectReferenceSegment"),
                            ]),
                        ]),
                        Sequence::new(vec_of_erased![
                            Ref::keyword("RENAME"),
                            Ref::keyword("VALUE"),
                            Ref::new("QuotedLiteralSegment"),
                            Ref::keyword("TO"),
                            Ref::new("QuotedLiteralSegment"),
                        ]),
                        Sequence::new(vec_of_erased![
                            Ref::keyword("RENAME"),
                            Ref::keyword("TO"),
                            Ref::new("ObjectReferenceSegment"),
                        ]),
                        Sequence::new(vec_of_erased![
                            Ref::keyword("SET"),
                            Ref::keyword("SCHEMA"),
                            Ref::new("SchemaReferenceSegment"),
                        ]),
                        Delimited::new(vec_of_erased![
                            Sequence::new(vec_of_erased![
                                Ref::keyword("ADD"),
                                Ref::keyword("ATTRIBUTE"),
                                Ref::new("ColumnReferenceSegment"),
                                Ref::new("DatatypeSegment"),
                                Sequence::new(vec_of_erased![
                                    Ref::keyword("COLLATE"),
                                    Ref::new("CollationReferenceSegment"),
                                ])
                                .config(|this| this.optional()),
                                Ref::new("CascadeRestrictGrammar").optional(),
                            ]),
                            Sequence::new(vec_of_erased![
                                Ref::keyword("ALTER"),
                                Ref::keyword("ATTRIBUTE"),
                                Ref::new("ColumnReferenceSegment"),
                                Sequence::new(vec_of_erased![
                                    Ref::keyword("SET"),
                                    Ref::keyword("DATA"),
                                ])
                                .config(|this| this.optional()),
                                Ref::keyword("TYPE"),
                                Ref::new("DatatypeSegment"),
                                Sequence::new(vec_of_erased![
                                    Ref::keyword("COLLATE"),
                                    Ref::new("CollationReferenceSegment"),
                                ])
                                .config(|this| this.optional()),
                                Ref::new("CascadeRestrictGrammar").optional(),
                            ]),
                            Sequence::new(vec_of_erased![
                                Ref::keyword("DROP"),
                                Ref::keyword("ATTRIBUTE"),
                                Ref::new("IfExistsGrammar").optional(),
                                Ref::new("ColumnReferenceSegment"),
                                Ref::new("CascadeRestrictGrammar").optional(),
                            ]),
                            Sequence::new(vec_of_erased![
                                Ref::keyword("RENAME"),
                                Ref::keyword("ATTRIBUTE"),
                                Ref::new("ColumnReferenceSegment"),
                                Ref::keyword("TO"),
                                Ref::new("ColumnReferenceSegment"),
                                Ref::new("CascadeRestrictGrammar").optional(),
                            ]),
                        ]),
                        Sequence::new(vec_of_erased![
                            Ref::keyword("ADD"),
                            Ref::keyword("VALUE"),
                            Ref::new("IfNotExistsGrammar").optional(),
                            Ref::new("QuotedLiteralSegment"),
                            Sequence::new(vec_of_erased![
                                one_of(vec_of_erased![
                                    Ref::keyword("BEFORE"),
                                    Ref::keyword("AFTER")
                                ]),
                                Ref::new("QuotedLiteralSegment"),
                            ])
                            .config(|this| this.optional()),
                        ]),
                    ]),
                ])
                .to_matchable(),
            )
            .to_matchable()
            .into(),
        ),
        (
            "CreateCollationStatementSegment".into(),
            NodeMatcher::new(
                SyntaxKind::CreateCollationStatement,
                Sequence::new(vec_of_erased![
                    Ref::keyword("CREATE"),
                    Ref::keyword("COLLATION"),
                    Ref::new("IfNotExistsGrammar").optional(),
                    Ref::new("ObjectReferenceSegment"),
                    one_of(vec_of_erased![
                        Bracketed::new(vec_of_erased![Delimited::new(vec_of_erased![
                            Sequence::new(vec_of_erased![
                                Ref::keyword("LOCALE"),
                                Ref::new("EqualsSegment"),
                                Ref::new("QuotedLiteralSegment"),
                            ]),
                            Sequence::new(vec_of_erased![
                                Ref::keyword("LC_COLLATE"),
                                Ref::new("EqualsSegment"),
                                Ref::new("QuotedLiteralSegment"),
                            ]),
                            Sequence::new(vec_of_erased![
                                Ref::keyword("LC_CTYPE"),
                                Ref::new("EqualsSegment"),
                                Ref::new("QuotedLiteralSegment"),
                            ]),
                            Sequence::new(vec_of_erased![
                                Ref::keyword("PROVIDER"),
                                Ref::new("EqualsSegment"),
                                one_of(vec_of_erased![Ref::keyword("ICU"), Ref::keyword("LIBC")]),
                            ]),
                            Sequence::new(vec_of_erased![
                                Ref::keyword("DETERMINISTIC"),
                                Ref::new("EqualsSegment"),
                                Ref::new("BooleanLiteralGrammar"),
                            ]),
                            Sequence::new(vec_of_erased![
                                Ref::keyword("VERSION"),
                                Ref::new("EqualsSegment"),
                                Ref::new("QuotedLiteralSegment"),
                            ]),
                        ])]),
                        Sequence::new(vec_of_erased![
                            Ref::keyword("FROM"),
                            Ref::new("ObjectReferenceSegment"),
                        ]),
                    ]),
                ])
                .to_matchable(),
            )
            .to_matchable()
            .into(),
        ),
    ]);

    postgres.replace_grammar(
        "ColumnReferenceSegment",
        Sequence::new(vec_of_erased![
            Ref::new("SingleIdentifierGrammar"),
            Sequence::new(vec_of_erased![
                one_of(vec_of_erased![
                    Ref::new("DotSegment"),
                    Sequence::new(vec_of_erased![
                        Ref::new("DotSegment"),
                        Ref::new("DotSegment"),
                    ]),
                ]),
                Delimited::new(vec_of_erased![Ref::new("SingleIdentifierFullGrammar"),]).config(
                    |this| {
                        this.delimiter(one_of(vec_of_erased![
                            Ref::new("DotSegment"),
                            Sequence::new(vec_of_erased![
                                Ref::new("DotSegment"),
                                Ref::new("DotSegment"),
                            ]),
                        ]));
                        this.terminators = vec_of_erased![
                            Ref::keyword("ON"),
                            Ref::keyword("AS"),
                            Ref::keyword("USING"),
                            Ref::new("CommaSegment"),
                            Ref::new("CastOperatorSegment"),
                            Ref::new("StartSquareBracketSegment"),
                            Ref::new("StartBracketSegment"),
                            Ref::new("BinaryOperatorGrammar"),
                            Ref::new("ColonSegment"),
                            Ref::new("DelimiterGrammar"),
                            Ref::new("JoinLikeClauseGrammar"),
                            Bracketed::new(vec![]),
                        ];
                        this.allow_gaps = false;
                    }
                ),
            ])
            .config(|this| {
                this.optional();
                this.allow_gaps = false
            }),
        ])
        .config(|this| this.allow_gaps = false)
        .to_matchable(),
    );

    postgres.add([(
        "NamedArgumentSegment".into(),
        NodeMatcher::new(
            SyntaxKind::NamedArgument,
            Sequence::new(vec_of_erased![
                Ref::new("NakedIdentifierSegment"),
                Ref::new("RightArrowSegment"),
                Ref::new("ExpressionSegment"),
            ])
            .to_matchable(),
        )
        .to_matchable()
        .into(),
    )]);

    postgres.replace_grammar(
        "TableExpressionSegment",
        one_of(vec_of_erased![
            Ref::new("ValuesClauseSegment"),
            Ref::new("BareFunctionSegment"),
            Sequence::new(vec_of_erased![
                Ref::new("FunctionSegment"),
                Sequence::new(vec_of_erased![
                    Ref::keyword("WITH"),
                    Ref::keyword("ORDINALITY"),
                ])
                .config(|this| this.optional()),
            ]),
            Ref::new("TableReferenceSegment"),
            Bracketed::new(vec_of_erased![Ref::new("SelectableGrammar"),]),
            Bracketed::new(vec_of_erased![Ref::new("MergeStatementSegment"),]),
        ])
        .to_matchable(),
    );

    postgres.add([(
        "ServerReferenceSegment".into(),
        NodeMatcher::new(
            SyntaxKind::ServerReference,
            postgres
                .grammar("ObjectReferenceSegment")
                .match_grammar()
                .unwrap(),
        )
        .to_matchable()
        .into(),
    )]);

    postgres.add([
        (
            "CreateServerStatementSegment".into(),
            NodeMatcher::new(
                SyntaxKind::CreateServerStatement,
                Sequence::new(vec_of_erased![
                    Ref::keyword("CREATE"),
                    Ref::keyword("SERVER"),
                    Ref::new("IfNotExistsGrammar").optional(),
                    Ref::new("ServerReferenceSegment"),
                    Sequence::new(vec_of_erased![
                        Ref::keyword("TYPE"),
                        Ref::new("QuotedLiteralSegment"),
                    ])
                    .config(|this| this.optional()),
                    Sequence::new(vec_of_erased![
                        Ref::keyword("VERSION"),
                        Ref::new("VersionIdentifierSegment"),
                    ])
                    .config(|this| this.optional()),
                    Ref::new("ForeignDataWrapperGrammar"),
                    Ref::new("ObjectReferenceSegment"),
                    Ref::new("OptionsGrammar").optional(),
                ])
                .to_matchable(),
            )
            .to_matchable()
            .into(),
        ),
        (
            "CreateUserMappingStatementSegment".into(),
            NodeMatcher::new(
                SyntaxKind::CreateUserMappingStatement,
                Sequence::new(vec_of_erased![
                    Ref::new("CreateUserMappingGrammar"),
                    Ref::new("IfNotExistsGrammar").optional(),
                    Ref::keyword("FOR"),
                    one_of(vec_of_erased![
                        Ref::new("SingleIdentifierGrammar"),
                        Ref::new("SessionInformationUserFunctionsGrammar"),
                        Ref::keyword("PUBLIC"),
                    ]),
                    Ref::keyword("SERVER"),
                    Ref::new("ServerReferenceSegment"),
                    Ref::new("OptionsGrammar").optional(),
                ])
                .to_matchable(),
            )
            .to_matchable()
            .into(),
        ),
        (
            "ImportForeignSchemaStatementSegment".into(),
            NodeMatcher::new(
                SyntaxKind::ImportForeignSchemaStatement,
                Sequence::new(vec_of_erased![
                    Ref::new("ImportForeignSchemaGrammar"),
                    Ref::new("SchemaReferenceSegment"),
                    Sequence::new(vec_of_erased![
                        one_of(vec_of_erased![
                            Sequence::new(vec_of_erased![
                                Ref::keyword("LIMIT"),
                                Ref::keyword("TO"),
                            ]),
                            Ref::keyword("EXCEPT"),
                        ]),
                        Bracketed::new(vec_of_erased![Delimited::new(vec_of_erased![Ref::new(
                            "NakedIdentifierFullSegment"
                        ),]),]),
                    ])
                    .config(|this| this.optional()),
                    Ref::keyword("FROM"),
                    Ref::keyword("SERVER"),
                    Ref::new("ServerReferenceSegment"),
                    Ref::keyword("INTO"),
                    Ref::new("SchemaReferenceSegment"),
                    Ref::new("OptionsGrammar").optional(),
                ])
                .to_matchable(),
            )
            .to_matchable()
            .into(),
        ),
        (
            // Statics Reference
            "StatisticsReferenceSegment".into(),
            Ref::new("ObjectReferenceSegment").to_matchable().into(),
        ),
        (
            // Create Statistics Segment.
            // As specified in https://www.postgresql.org/docs/16/sql-createstatistics.html
            "CreateStatisticsStatementSegment".into(),
            Sequence::new(vec_of_erased![
                Ref::keyword("CREATE"),
                Ref::keyword("STATISTICS"),
                Sequence::new(vec_of_erased![
                    Ref::new("IfNotExistsGrammar").optional(),
                    Ref::new("StatisticsReferenceSegment"),
                ])
                .config(|this| this.optional()),
                Bracketed::new(vec_of_erased![Delimited::new(vec_of_erased![
                    Ref::keyword("DEPENDENCIES"),
                    Ref::keyword("MCV"),
                    Ref::keyword("NDISTINCT"),
                ])])
                .config(|this| this.optional()),
                Ref::keyword("ON"),
                Delimited::new(vec_of_erased![
                    Ref::new("ColumnReferenceSegment"),
                    Ref::new("ExpressionSegment"),
                ]),
                Ref::keyword("FROM"),
                Ref::new("TableReferenceSegment"),
            ])
            .to_matchable()
            .into(),
        ),
        (
            // Alter Statistics Segment.
            // As specified in https://www.postgresql.org/docs/16/sql-alterstatistics.html
            "AlterStatisticsStatementSegment".into(),
            Sequence::new(vec_of_erased![
                Ref::keyword("ALTER"),
                Ref::keyword("STATISTICS"),
                Ref::new("StatisticsReferenceSegment"),
                one_of(vec_of_erased![
                    Sequence::new(vec_of_erased![
                        Ref::keyword("OWNER"),
                        Ref::keyword("TO"),
                        one_of(vec_of_erased![
                            one_of(vec_of_erased![
                                Ref::new("ParameterNameSegment"),
                                Ref::new("QuotedIdentifierSegment")
                            ]),
                            Ref::keyword("CURRENT_ROLE"),
                            Ref::keyword("CURRENT_USER"),
                            Ref::keyword("SESSION_USER")
                        ])
                    ]),
                    Sequence::new(vec_of_erased![
                        Ref::keyword("RENAME"),
                        Ref::keyword("TO"),
                        Ref::new("StatisticsReferenceSegment")
                    ]),
                    Sequence::new(vec_of_erased![
                        Ref::keyword("SET"),
                        one_of(vec_of_erased![
                            Sequence::new(vec_of_erased![
                                Ref::keyword("SCHEMA"),
                                Ref::new("SchemaReferenceSegment")
                            ]),
                            Sequence::new(vec_of_erased![
                                Ref::keyword("STATISTICS"),
                                Ref::new("NumericLiteralSegment")
                            ])
                        ])
                    ])
                ])
            ])
            .to_matchable()
            .into(),
        ),
        (
            // Drop Statistics Segment.
            // As specified in https://www.postgresql.org/docs/16/sql-dropstatistics.html
            "DropStatisticsStatementSegment".into(),
            Sequence::new(vec_of_erased![
                Ref::keyword("DROP"),
                Ref::keyword("STATISTICS"),
                Ref::new("IfExistsGrammar").optional(),
                Delimited::new(vec_of_erased![Ref::new("StatisticsReferenceSegment")]),
                one_of(vec_of_erased![
                    Ref::keyword("CASCADE"),
                    Ref::keyword("RESTRICT"),
                ])
                .config(|this| this.optional()),
            ])
            .to_matchable()
            .into(),
        ),
    ]);

    postgres
}

pub fn statement_segment() -> Matchable {
    ansi::statement_segment().copy(
        Some(vec_of_erased![
            Ref::new("CreateStatisticsStatementSegment"),
            Ref::new("AlterStatisticsStatementSegment"),
            Ref::new("DropStatisticsStatementSegment"),
            Ref::new("AlterDefaultPrivilegesStatementSegment"),
            Ref::new("DropOwnedStatementSegment"),
            Ref::new("ReassignOwnedStatementSegment"),
            Ref::new("CommentOnStatementSegment"),
            Ref::new("AnalyzeStatementSegment"),
            Ref::new("CreateTableAsStatementSegment"),
            Ref::new("AlterTriggerStatementSegment"),
            Ref::new("AlterAggregateStatementSegment"),
            Ref::new("SetStatementSegment"),
            Ref::new("AlterPolicyStatementSegment"),
            Ref::new("CreatePolicyStatementSegment"),
            Ref::new("DropPolicyStatementSegment"),
            Ref::new("CreateDomainStatementSegment"),
            Ref::new("AlterDomainStatementSegment"),
            Ref::new("DropDomainStatementSegment"),
            Ref::new("CreateMaterializedViewStatementSegment"),
            Ref::new("AlterMaterializedViewStatementSegment"),
            Ref::new("DropMaterializedViewStatementSegment"),
            Ref::new("RefreshMaterializedViewStatementSegment"),
            Ref::new("AlterDatabaseStatementSegment"),
            Ref::new("DropDatabaseStatementSegment"),
            Ref::new("VacuumStatementSegment"),
            Ref::new("AlterFunctionStatementSegment"),
            Ref::new("CreateViewStatementSegment"),
            Ref::new("AlterViewStatementSegment"),
            Ref::new("ListenStatementSegment"),
            Ref::new("NotifyStatementSegment"),
            Ref::new("UnlistenStatementSegment"),
            Ref::new("LoadStatementSegment"),
            Ref::new("ResetStatementSegment"),
            Ref::new("DiscardStatementSegment"),
            Ref::new("AlterProcedureStatementSegment"),
            Ref::new("CreateProcedureStatementSegment"),
            Ref::new("DropProcedureStatementSegment"),
            Ref::new("CopyStatementSegment"),
            Ref::new("DoStatementSegment"),
            Ref::new("AlterIndexStatementSegment"),
            Ref::new("ReindexStatementSegment"),
            Ref::new("AlterRoleStatementSegment"),
            Ref::new("CreateExtensionStatementSegment"),
            Ref::new("DropExtensionStatementSegment"),
            Ref::new("CreatePublicationStatementSegment"),
            Ref::new("AlterPublicationStatementSegment"),
            Ref::new("DropPublicationStatementSegment"),
            Ref::new("CreateTypeStatementSegment"),
            Ref::new("AlterTypeStatementSegment"),
            Ref::new("AlterSchemaStatementSegment"),
            Ref::new("LockTableStatementSegment"),
            Ref::new("ClusterStatementSegment"),
            Ref::new("CreateCollationStatementSegment"),
            Ref::new("CallStoredProcedureSegment"),
            Ref::new("CreateServerStatementSegment"),
            Ref::new("CreateUserMappingStatementSegment"),
            Ref::new("ImportForeignSchemaStatementSegment"),
        ]),
        None,
        None,
        None,
        vec![],
        false,
    )
}
