use itertools::Itertools;
use sqruff_lib_core::dialects::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::{
    AnyNumberOf, any_set_of, one_of, optionally_bracketed,
};
use sqruff_lib_core::parser::grammar::conditional::Conditional;
use sqruff_lib_core::parser::grammar::delimited::Delimited;
use sqruff_lib_core::parser::grammar::sequence::{Bracketed, Sequence};
use sqruff_lib_core::parser::grammar::{Nothing, Ref};
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::{MultiStringParser, 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 super::ansi::{self, raw_dialect};
use super::snowflake_keywords::{SNOWFLAKE_RESERVED_KEYWORDS, SNOWFLAKE_UNRESERVED_KEYWORDS};
use sqruff_lib_core::dialects::init::DialectConfig;
use sqruff_lib_core::value::Value;

sqruff_lib_core::dialect_config!(SnowflakeDialectConfig {});

pub fn dialect(config: Option<&Value>) -> Dialect {
    // Parse and validate dialect configuration, falling back to defaults on failure
    let _dialect_config: SnowflakeDialectConfig = config
        .map(SnowflakeDialectConfig::from_value)
        .unwrap_or_default();
    let mut snowflake_dialect = raw_dialect();
    snowflake_dialect.name = DialectKind::Snowflake;

    snowflake_dialect.replace_grammar(
        "SelectClauseElementSegment",
        ansi::select_clause_element().copy(
            Some(vec![
                Sequence::new(vec![
                    Ref::new("SystemFunctionName").to_matchable(),
                    Bracketed::new(vec![Ref::new("QuotedLiteralSegment").to_matchable()])
                        .to_matchable(),
                ])
                .to_matchable(),
            ]),
            None,
            Some(Ref::new("WildcardExpressionSegment").to_matchable()),
            None,
            Vec::new(),
            false,
        ),
    );

    snowflake_dialect.replace_grammar(
        "FromExpressionElementSegment",
        Sequence::new(vec![
            Ref::new("PreTableFunctionKeywordsGrammar")
                .optional()
                .to_matchable(),
            optionally_bracketed(vec![Ref::new("TableExpressionSegment").to_matchable()])
                .to_matchable(),
            Ref::new("AliasExpressionSegment")
                .exclude(one_of(vec![
                    Ref::new("FromClauseTerminatorGrammar").to_matchable(),
                    Ref::new("SamplingExpressionSegment").to_matchable(),
                    Ref::new("ChangesClauseSegment").to_matchable(),
                    Ref::new("JoinLikeClauseGrammar").to_matchable(),
                    Ref::keyword("CROSS").to_matchable(),
                ]))
                .optional()
                .to_matchable(),
            Sequence::new(vec![
                Ref::keyword("WITH").to_matchable(),
                Ref::keyword("OFFSET").to_matchable(),
                Ref::new("AliasExpressionSegment").to_matchable(),
            ])
            .config(|this| this.optional())
            .to_matchable(),
            Ref::new("SamplingExpressionSegment")
                .optional()
                .to_matchable(),
            Ref::new("PostTableExpressionGrammar")
                .optional()
                .to_matchable(),
        ])
        .to_matchable(),
    );

    snowflake_dialect.replace_grammar(
        "JoinClauseSegment",
        one_of(vec![
            Sequence::new(vec![
                Ref::new("JoinTypeKeywordsGrammar")
                    .optional()
                    .to_matchable(),
                Ref::new("JoinKeywordsGrammar").to_matchable(),
                MetaSegment::indent().to_matchable(),
                Ref::new("FromExpressionElementSegment").to_matchable(),
                AnyNumberOf::new(vec![Ref::new("NestedJoinGrammar").to_matchable()]).to_matchable(),
                MetaSegment::dedent().to_matchable(),
                Sequence::new(vec![
                    Conditional::new(MetaSegment::indent())
                        .indented_using_on()
                        .to_matchable(),
                    one_of(vec![
                        Ref::new("JoinOnConditionSegment").to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("USING").to_matchable(),
                            MetaSegment::indent().to_matchable(),
                            Bracketed::new(vec![
                                Delimited::new(vec![
                                    Ref::new("SingleIdentifierGrammar").to_matchable(),
                                ])
                                .to_matchable(),
                            ])
                            .config(|this| this.parse_mode = ParseMode::Greedy)
                            .to_matchable(),
                            MetaSegment::dedent().to_matchable(),
                        ])
                        .to_matchable(),
                    ])
                    .to_matchable(),
                    Conditional::new(MetaSegment::dedent())
                        .indented_using_on()
                        .to_matchable(),
                ])
                .config(|this| this.optional())
                .to_matchable(),
            ])
            .to_matchable(),
            Sequence::new(vec![
                Ref::new("NaturalJoinKeywordsGrammar").to_matchable(),
                Ref::new("JoinKeywordsGrammar").to_matchable(),
                MetaSegment::indent().to_matchable(),
                Ref::new("FromExpressionElementSegment").to_matchable(),
                MetaSegment::dedent().to_matchable(),
            ])
            .to_matchable(),
            Sequence::new(vec![
                Ref::new("ExtendedNaturalJoinKeywordsGrammar").to_matchable(),
                MetaSegment::indent().to_matchable(),
                Ref::new("FromExpressionElementSegment").to_matchable(),
                MetaSegment::dedent().to_matchable(),
            ])
            .to_matchable(),
            Sequence::new(vec![
                Ref::keyword("ASOF").to_matchable(),
                Ref::keyword("JOIN").to_matchable(),
                MetaSegment::indent().to_matchable(),
                Ref::new("FromExpressionElementSegment").to_matchable(),
                AnyNumberOf::new(vec![Ref::new("NestedJoinGrammar").to_matchable()]).to_matchable(),
                MetaSegment::dedent().to_matchable(),
                MetaSegment::indent().to_matchable(),
                Ref::new("MatchConditionSegment").to_matchable(),
                MetaSegment::dedent().to_matchable(),
                Sequence::new(vec![
                    Conditional::new(MetaSegment::indent())
                        .indented_using_on()
                        .to_matchable(),
                    one_of(vec![
                        Ref::new("JoinOnConditionSegment").to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("USING").to_matchable(),
                            MetaSegment::indent().to_matchable(),
                            Bracketed::new(vec![
                                Delimited::new(vec![
                                    Ref::new("SingleIdentifierGrammar").to_matchable(),
                                ])
                                .to_matchable(),
                            ])
                            .config(|this| this.parse_mode = ParseMode::Greedy)
                            .to_matchable(),
                            MetaSegment::dedent().to_matchable(),
                        ])
                        .to_matchable(),
                    ])
                    .to_matchable(),
                    Conditional::new(MetaSegment::dedent())
                        .indented_using_on()
                        .to_matchable(),
                ])
                .config(|this| this.optional())
                .to_matchable(),
            ])
            .to_matchable(),
        ])
        .to_matchable(),
    );

    snowflake_dialect.patch_lexer_matchers(vec![
        Matcher::regex(
            "single_quote",
            r"'([^'\\]|\\.|'')*'",
            SyntaxKind::SingleQuote,
        ),
        Matcher::regex(
            "inline_comment",
            r"(--|#|//)[^\n]*",
            SyntaxKind::InlineComment,
        ),
    ]);

    snowflake_dialect.insert_lexer_matchers(
        vec![
            Matcher::string("parameter_assigner", "=>", SyntaxKind::ParameterAssigner),
            Matcher::string("function_assigner", "->", SyntaxKind::FunctionAssigner),
            Matcher::regex(
                "stage_path",
                r"(?:@[^\s;)]+|'@[^']+')",
                SyntaxKind::StagePath,
            ),
            Matcher::regex("column_selector", r"\$[0-9]+", SyntaxKind::ColumnSelector),
            Matcher::regex("dollar_quote", r"\$\$.*\$\$", SyntaxKind::DollarQuote),
            Matcher::regex(
                "dollar_literal",
                r"[$][a-zA-Z0-9_.]*",
                SyntaxKind::DollarLiteral,
            ),
            Matcher::regex(
                "inline_dollar_sign",
                r"[a-zA-Z_][a-zA-Z0-9_$]*\$[a-zA-Z0-9_$]*",
                SyntaxKind::Raw,
            ),
            Matcher::regex(
                "unquoted_file_path",
                r"file://(?:[a-zA-Z]+:|/)+(?:[0-9a-zA-Z\\/_*?-]+)(?:\.[0-9a-zA-Z]+)?",
                SyntaxKind::UnquotedFilePath,
            ),
            Matcher::string("question_mark", "?", SyntaxKind::QuestionMark),
            Matcher::string("exclude_bracket_open", "{-", SyntaxKind::ExcludeBracketOpen),
            Matcher::string(
                "exclude_bracket_close",
                "-}",
                SyntaxKind::ExcludeBracketClose,
            ),
        ],
        "like_operator",
    );

    snowflake_dialect.insert_lexer_matchers(
        vec![Matcher::string(
            "walrus_operator",
            ":=",
            SyntaxKind::WalrusOperator,
        )],
        "equals",
    );

    snowflake_dialect.bracket_sets_mut("bracket_pairs").insert((
        "exclude",
        "StartExcludeBracketSegment",
        "EndExcludeBracketSegment",
        true,
    ));

    snowflake_dialect.sets_mut("bare_functions").clear();
    snowflake_dialect.sets_mut("bare_functions").extend([
        "CURRENT_DATE",
        "CURRENT_TIME",
        "CURRENT_TIMESTAMP",
        "CURRENT_USER",
        "LOCALTIME",
        "LOCALTIMESTAMP",
    ]);

    snowflake_dialect.sets_mut("compression_types").clear();
    snowflake_dialect.sets_mut("compression_types").extend([
        "AUTO",
        "AUTO_DETECT",
        "GZIP",
        "BZ2",
        "BROTLI",
        "ZSTD",
        "DEFLATE",
        "RAW_DEFLATE",
        "LZO",
        "NONE",
        "SNAPPY",
    ]);

    snowflake_dialect.sets_mut("files_types").clear();
    snowflake_dialect
        .sets_mut("files_types")
        .extend(["CSV", "JSON", "AVRO", "ORC", "PARQUET", "XML"]);

    snowflake_dialect.sets_mut("warehouse_types").clear();
    snowflake_dialect
        .sets_mut("warehouse_types")
        .extend(["STANDARD", "SNOWPARK-OPTIMIZED"]);

    snowflake_dialect.sets_mut("warehouse_sizes").clear();
    snowflake_dialect.sets_mut("warehouse_sizes").extend([
        "XSMALL", "SMALL", "MEDIUM", "LARGE", "XLARGE", "XXLARGE", "X2LARGE", "XXXLARGE",
        "X3LARGE", "X4LARGE", "X5LARGE", "X6LARGE", "X-SMALL", "X-LARGE", "2X-LARGE", "3X-LARGE",
        "4X-LARGE", "5X-LARGE", "6X-LARGE",
    ]);

    snowflake_dialect
        .sets_mut("warehouse_scaling_policies")
        .clear();
    snowflake_dialect
        .sets_mut("warehouse_scaling_policies")
        .extend(["STANDARD", "ECONOMY"]);

    // Snowflake supports CTEs with DML statements (INSERT, UPDATE, DELETE, MERGE)
    // We add these to NonWithSelectableGrammar so WithCompoundStatementSegment can use them
    snowflake_dialect.add([(
        "NonWithSelectableGrammar".into(),
        one_of(vec![
            Ref::new("SetExpressionSegment").to_matchable(),
            optionally_bracketed(vec![Ref::new("SelectStatementSegment").to_matchable()])
                .to_matchable(),
            Ref::new("NonSetSelectableGrammar").to_matchable(),
            Ref::new("UpdateStatementSegment").to_matchable(),
            Ref::new("InsertStatementSegment").to_matchable(),
            Ref::new("DeleteStatementSegment").to_matchable(),
            Ref::new("MergeStatementSegment").to_matchable(),
        ])
        .to_matchable()
        .into(),
    )]);

    snowflake_dialect.add([
        (
            "ParameterAssignerSegment".into(),
            StringParser::new(
                "=>",
                SyntaxKind::ParameterAssigner
            )
            .to_matchable()
            .into(),
        ),
        (
            "FunctionAssignerSegment".into(),
            StringParser::new(
                "->",
                SyntaxKind::FunctionAssigner
            )
            .to_matchable()
            .into(),
        ),
        (
            "WalrusOperatorSegment".into(),
            StringParser::new(
                ":=",
                SyntaxKind::AssignmentOperator
            )
            .to_matchable()
            .into(),
        ),
        (
            "QuotedStarSegment".into(),
            StringParser::new(
                "'*'",
                SyntaxKind::QuotedStar
            )
            .to_matchable()
            .into(),
        ),
        (
            "NakedSemiStructuredElementSegment".into(),
            RegexParser::new(
                "[A-Z0-9_]*",
                SyntaxKind::SemiStructuredElement
            )
            .to_matchable()
            .into(),
        ),
        (
            "QuotedSemiStructuredElementSegment".into(),
            TypedParser::new(
                SyntaxKind::DoubleQuote,
                SyntaxKind::SemiStructuredElement,
            )
            .to_matchable()
            .into(),
        ),
        (
            "ColumnIndexIdentifierSegment".into(),
            RegexParser::new(
                r"\$[0-9]+",
                SyntaxKind::ColumnIndexIdentifierSegment
            )
            .to_matchable()
            .into(),
        ),
        (
            "LocalVariableNameSegment".into(),
            RegexParser::new(
                r"[a-zA-Z0-9_]*",
                SyntaxKind::Variable
            )
            .to_matchable()
            .into(),
        ),
        (
            "ReferencedVariableNameSegment".into(),
            RegexParser::new(
                r"\$[A-Z_][A-Z0-9_]*",
                SyntaxKind::Variable
            )
            .to_matchable()
            .into(),
        ),
        (
            "WarehouseType".into(),
            one_of(vec![
                MultiStringParser::new(
                    snowflake_dialect
                        .sets("warehouse_types")
                        .into_iter()
                        .filter(|it| !it.contains('-'))
                        .map_into()
                        .collect_vec(),
                    SyntaxKind::WarehouseSize
                ).to_matchable(),
                MultiStringParser::new(
                    snowflake_dialect
                        .sets("warehouse_types")
                        .into_iter()
                        .map(|it| format!("'{it}'"))
                        .collect_vec(),
                    SyntaxKind::WarehouseSize
                ).to_matchable()
            ])
            .to_matchable()
            .into(),
        ),
        (
            "WarehouseSize".into(),
            one_of(vec![
                MultiStringParser::new(
                    snowflake_dialect
                        .sets("warehouse_sizes")
                        .into_iter()
                        .filter(|it| !it.contains('-'))
                        .map_into()
                        .collect_vec(),
                   SyntaxKind::WarehouseSize
                ).to_matchable(),
                MultiStringParser::new(
                    snowflake_dialect
                        .sets("warehouse_sizes")
                        .into_iter()
                        .map(|it| format!("'{it}'"))
                        .collect_vec(),
                    SyntaxKind::WarehouseSize
                ).to_matchable()
            ])
            .to_matchable()
            .into(),
        ),
        (
            "CompressionType".into(),
            one_of(vec![
                MultiStringParser::new(
                    snowflake_dialect
                        .sets("compression_types")
                        .into_iter()
                        .map_into()
                        .collect_vec(),
                   SyntaxKind::CompressionType

                ).to_matchable(),
                MultiStringParser::new(
                    snowflake_dialect
                        .sets("compression_types")
                        .into_iter()
                        .map(|it| format!("'{it}'"))
                        .collect_vec(),
                   SyntaxKind::CompressionType
                ).to_matchable()
            ])
            .to_matchable()
            .into(),
        ),
        (
            "ScalingPolicy".into(),
            one_of(vec![
                MultiStringParser::new(
                    snowflake_dialect
                        .sets("warehouse_scaling_policies")
                        .into_iter()
                        .filter(|it| !it.contains('-'))
                        .map_into()
                        .collect_vec(),
                   SyntaxKind::ScalingPolicy
                ).to_matchable(),
                MultiStringParser::new(
                    snowflake_dialect
                        .sets("warehouse_scaling_policies")
                        .into_iter()
                        .map(|it| format!("'{it}'"))
                        .collect_vec(),
                   SyntaxKind::ScalingPolicy
                ).to_matchable()
            ])
            .to_matchable()
            .into(),
        ),
        (
            "ValidationModeOptionSegment".into(),
            RegexParser::new(
                r"'?RETURN_(?:\d+_ROWS|ERRORS|ALL_ERRORS)'?",
                SyntaxKind::ValidationModeOption
            )
            .to_matchable()
            .into(),
        ),
        (
            "CopyOptionOnErrorSegment".into(),
            RegexParser::new(
                r"'?CONTINUE'?|'?SKIP_FILE(?:_[0-9]+%?)?'?|'?ABORT_STATEMENT'?",
                SyntaxKind::CopyOnErrorOption
            )
            .to_matchable()
            .into(),
        ),
        (
            "DoubleQuotedUDFBody".into(),
            TypedParser::new(
                SyntaxKind::DoubleQuote,
                SyntaxKind::UdfBody,
            )
            .to_matchable()
            .into(),
        ),
        (
            "SingleQuotedUDFBody".into(),
            TypedParser::new(
                SyntaxKind::SingleQuote,
                SyntaxKind::UdfBody,
            )
            .to_matchable()
            .into(),
        ),
        (
            "DollarQuotedUDFBody".into(),
            TypedParser::new(
                SyntaxKind::DollarQuote,
                SyntaxKind::UdfBody,
            )
            .to_matchable()
            .into(),
        ),
        (
            "StagePath".into(),
            RegexParser::new(
                r"(?:@[^\s;)]+|'@[^']+')",
                SyntaxKind::StagePath
            )
            .to_matchable()
            .into(),
        ),
        (
            "S3Path".into(),
            RegexParser::new(
                r"'s3://[a-z0-9][a-z0-9\.-]{1,61}[a-z0-9](?:/.*)?'",
                SyntaxKind::BucketPath
            )
            .to_matchable()
            .into(),
        ),
        (
            "GCSPath".into(),
            RegexParser::new(
                r"'gcs://[a-z0-9][\w\.-]{1,61}[a-z0-9](?:/.+)?'",
                SyntaxKind::BucketPath
            )
            .to_matchable()
            .into(),
        ),
        (
            "AzureBlobStoragePath".into(),
            RegexParser::new(
                r"'azure://[a-z0-9][a-z0-9-]{1,61}[a-z0-9]\.blob\.core\.windows\.net/[a-z0-9][a-z0-9\.-]{1,61}[a-z0-9](?:/.+)?'",
                SyntaxKind::BucketPath
            )
            .to_matchable()
            .into(),
        ),
        (
            "UnquotedFilePath".into(),
            TypedParser::new(
                SyntaxKind::UnquotedFilePath,
                SyntaxKind::UnquotedFilePath,
            )
            .to_matchable()
            .into(),
        ),
        (
            "SnowflakeEncryptionOption".into(),
            MultiStringParser::new(
                vec!["'SNOWFLAKE_FULL'".into(), "'SNOWFLAKE_SSE'".into()],
                SyntaxKind::StageEncryptionOption
            ).to_matchable().into(),
        ),
        (
            "S3EncryptionOption".into(),
            MultiStringParser::new(
                vec!["'AWS_CSE'".into(), "'AWS_SSE_S3'".into(), "'AWS_SSE_KMS'".into()],
                SyntaxKind::StageEncryptionOption
            ).to_matchable().into(),
        ),
        (
            "GCSEncryptionOption".into(),
            MultiStringParser::new(
                vec!["'GCS_SSE_KMS'".into()],
                SyntaxKind::StageEncryptionOption
            ).to_matchable().into(),
        ),
        (
            "AzureBlobStorageEncryptionOption".into(),
            MultiStringParser::new(
                vec!["'AZURE_CSE'".into()],
                SyntaxKind::StageEncryptionOption
            ).to_matchable().into(),
        ),
        (
            "FileType".into(),
            one_of(vec![
                MultiStringParser::new(
                    snowflake_dialect
                        .sets("file_types")
                        .into_iter()
                        .filter(|it| !it.contains('-'))
                        .map_into()
                        .collect_vec(),
                   SyntaxKind::FileType
                ).to_matchable(),
                MultiStringParser::new(
                    snowflake_dialect
                        .sets("file_types")
                        .into_iter()
                        .map(|it| format!("'{it}'"))
                        .collect_vec(),
                  SyntaxKind::FileType
                ).to_matchable()
            ])
            .to_matchable()
            .into(),
        ),
        (
            "IntegerSegment".into(),
            RegexParser::new(
                r"[0-9]+",
                SyntaxKind::IntegerLiteral
            )
            .to_matchable()
            .into(),
        ),
        (
            "SystemFunctionName".into(),
            RegexParser::new(
                r"SYSTEM\$([A-Za-z0-9_]*)",
                SyntaxKind::SystemFunctionName
            )
            .to_matchable()
            .into(),
        ),
        (
            "GroupByContentsGrammar".into(),
            Delimited::new(vec![
                one_of(vec![
                    Ref::new("ColumnReferenceSegment").to_matchable(),
                    // Can `GROUP BY 1`
                    Ref::new("NumericLiteralSegment").to_matchable(),
                    // Can `GROUP BY coalesce(col, 1)`
                    Ref::new("ExpressionSegment").to_matchable(),]).to_matchable(),]).config(|this|this.terminators = vec![
                Ref::keyword("ORDER").to_matchable(),
                Ref::keyword("LIMIT").to_matchable(),
                Ref::keyword("FETCH").to_matchable(),
                Ref::keyword("OFFSET").to_matchable(),
                Ref::keyword("HAVING").to_matchable(),
                Ref::keyword("QUALIFY").to_matchable(),
                Ref::keyword("WINDOW").to_matchable(),]).to_matchable().into()
        ),
        (
            "LimitLiteralGrammar".into(),
            one_of(vec![
                Ref::new("NumericLiteralSegment").to_matchable(),
                Ref::keyword("NULL").to_matchable(),
                Ref::new("QuotedLiteralSegment").to_matchable()
            ]).to_matchable().into()
        ),
        (
            "StartExcludeBracketSegment".into(),
            StringParser::new(
                "{-",
                SyntaxKind::StartExcludeBracket
            )
            .to_matchable()
            .into(),
        ),
        (
            "EndExcludeBracketSegment".into(),
            StringParser::new(
                "-}",
                SyntaxKind::EndExcludeBracket
            )
            .to_matchable()
            .into(),
        ),
        (
            "QuestionMarkSegment".into(),
            StringParser::new(
                "?",
                SyntaxKind::QuestionMark
            )
            .to_matchable()
            .into(),
        ),
        (
            "CaretSegment".into(),
            StringParser::new(
                "^",
                SyntaxKind::Caret
            )
            .to_matchable()
            .into(),
        ),
        (
            "DollarSegment".into(),
            StringParser::new(
                "$",
                SyntaxKind::Dollar
            )
            .to_matchable()
            .into(),
        ),
        (
            "PatternQuantifierGrammar".into(),
            Sequence::new(vec![
                one_of(vec![
                    Ref::new("PositiveSegment").to_matchable(),
                    Ref::new("StarSegment").to_matchable(),
                    Ref::new("QuestionMarkSegment").to_matchable(),
                    Bracketed::new(vec![
                        one_of(vec![
                            Ref::new("NumericLiteralSegment").to_matchable(),
                            Sequence::new(vec![
                                Ref::new("NumericLiteralSegment").to_matchable(),
                                Ref::new("CommaSegment").to_matchable(),]).to_matchable(),
                            Sequence::new(vec![
                                Ref::new("CommaSegment").to_matchable(),
                                Ref::new("NumericLiteralSegment").to_matchable(),]).to_matchable(),
                            Sequence::new(vec![
                                Ref::new("NumericLiteralSegment").to_matchable(),
                                Ref::new("CommaSegment").to_matchable(),
                                Ref::new("NumericLiteralSegment").to_matchable(),]).to_matchable(),]).to_matchable(),]).config(|this| {
                        this.bracket_type = "curly";
                        this.bracket_pairs_set = "bracket_pairs";
                    }).to_matchable()
                ]).to_matchable(),
                Ref::new("QuestionMarkSegment").optional().to_matchable()
            ]).config(|this| {
                this.allow_gaps = false;
            }).to_matchable().into()
        ),
        (
            "PatternSymbolGrammar".into(),
            Sequence::new(vec![
                Ref::new("SingleIdentifierGrammar").to_matchable(),
                Ref::new("PatternQuantifierGrammar").optional().to_matchable()
            ]).config(|this| {
                this.allow_gaps = false;
            }).to_matchable().into()
        ),
        (
            "PatternOperatorGrammar".into(),
            one_of(vec![
                Ref::new("PatternSymbolGrammar").to_matchable(),
                Sequence::new(vec![
                    one_of(vec![
                        Bracketed::new(vec![
                            one_of(vec![
                                AnyNumberOf::new(vec![Ref::new("PatternOperatorGrammar").to_matchable(),]).to_matchable(),
                                Delimited::new(
                                    vec![
                                        Ref::new("PatternOperatorGrammar").to_matchable(),]
                                )
                                .config(|this|this.delimiter(Ref::new("BitwiseOrSegment"))).to_matchable(),]).to_matchable(),]).config(|this| {
                            this.bracket_type = "exclude";
                            this.bracket_pairs_set = "bracket_pairs";
                        }).to_matchable(),
                        Bracketed::new(vec![
                            one_of(vec![
                                AnyNumberOf::new(vec![Ref::new("PatternOperatorGrammar").to_matchable(),]).to_matchable(),
                                Delimited::new(
                                    vec![
                                        Ref::new("PatternOperatorGrammar").to_matchable(),]
                                )
                                .config(|this|this.delimiter(Ref::new("BitwiseOrSegment"))).to_matchable(),]).to_matchable(),]).to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("PERMUTE").to_matchable(),
                            Bracketed::new(vec![Delimited::new(
                                vec![
                                    Ref::new("PatternSymbolGrammar").to_matchable(),]
                            ).to_matchable(),]).to_matchable(),]).to_matchable(),]).to_matchable(),
                    Ref::new("PatternQuantifierGrammar").optional().to_matchable()
                ]).config(|this| {
                    this.allow_gaps = false;
                }).to_matchable(),]).to_matchable().into()
        ),
        (
            "ContextHeadersGrammar".into(),
            one_of(vec![
                Ref::keyword("CURRENT_ACCOUNT").to_matchable(),
                Ref::keyword("CURRENT_CLIENT").to_matchable(),
                Ref::keyword("CURRENT_DATABASE").to_matchable(),
                Ref::keyword("CURRENT_DATE").to_matchable(),
                Ref::keyword("CURRENT_IP_ADDRESS").to_matchable(),
                Ref::keyword("CURRENT_REGION").to_matchable(),
                Ref::keyword("CURRENT_ROLE").to_matchable(),
                Ref::keyword("CURRENT_SCHEMA").to_matchable(),
                Ref::keyword("CURRENT_SCHEMAS").to_matchable(),
                Ref::keyword("CURRENT_SESSION").to_matchable(),
                Ref::keyword("CURRENT_STATEMENT").to_matchable(),
                Ref::keyword("CURRENT_TIME").to_matchable(),
                Ref::keyword("CURRENT_TIMESTAMP").to_matchable(),
                Ref::keyword("CURRENT_TRANSACTION").to_matchable(),
                Ref::keyword("CURRENT_USER").to_matchable(),
                Ref::keyword("CURRENT_VERSION").to_matchable(),
                Ref::keyword("CURRENT_WAREHOUSE").to_matchable(),
                Ref::keyword("LAST_QUERY_ID").to_matchable(),
                Ref::keyword("LAST_TRANSACTION").to_matchable(),
                Ref::keyword("LOCALTIME").to_matchable(),
                Ref::keyword("LOCALTIMESTAMP").to_matchable(),]).to_matchable().into()
        )
    ]);

    snowflake_dialect.add([
        (
            "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("[a-zA-Z_][a-zA-Z0-9_$]*", SyntaxKind::NakedIdentifier)
                    .anti_template(&anti_template)
                    .to_matchable()
            })
            .into(),
        ),
        (
            "LiteralGrammar".into(),
            snowflake_dialect
                .grammar("LiteralGrammar")
                .copy(
                    Some(vec![
                        Ref::new("ReferencedVariableNameSegment").to_matchable(),
                    ]),
                    None,
                    None,
                    None,
                    Vec::new(),
                    false,
                )
                .into(),
        ),
        (
            "AccessorGrammar".into(),
            AnyNumberOf::new(vec![
                Ref::new("ArrayAccessorSegment").to_matchable(),
                Ref::new("SemiStructuredAccessorSegment").to_matchable(),
            ])
            .to_matchable()
            .into(),
        ),
        (
            "PreTableFunctionKeywordsGrammar".into(),
            one_of(vec![Ref::keyword("LATERAL").to_matchable()])
                .to_matchable()
                .into(),
        ),
        (
            "FunctionContentsExpressionGrammar".into(),
            one_of(vec![
                Ref::new("DatetimeUnitSegment").to_matchable(),
                Ref::new("NamedParameterExpressionSegment").to_matchable(),
                Ref::new("ReferencedVariableNameSegment").to_matchable(),
                Sequence::new(vec![
                    Ref::new("ExpressionSegment").to_matchable(),
                    Sequence::new(vec![
                        one_of(vec![
                            Ref::keyword("IGNORE").to_matchable(),
                            Ref::keyword("RESPECT").to_matchable(),
                        ])
                        .to_matchable(),
                        Ref::keyword("NULLS").to_matchable(),
                    ])
                    .config(|this| this.optional())
                    .to_matchable(),
                ])
                .to_matchable(),
            ])
            .to_matchable()
            .into(),
        ),
        (
            "JoinLikeClauseGrammar".into(),
            Sequence::new(vec![
                any_set_of(vec![
                    Ref::new("MatchRecognizeClauseSegment").to_matchable(),
                    Ref::new("ChangesClauseSegment").to_matchable(),
                    Ref::new("ConnectByClauseSegment").to_matchable(),
                    Ref::new("FromBeforeExpressionSegment").to_matchable(),
                    Ref::new("FromPivotExpressionSegment").to_matchable(),
                    AnyNumberOf::new(vec![
                        Ref::new("FromUnpivotExpressionSegment").to_matchable(),
                    ])
                    .to_matchable(),
                    Ref::new("SamplingExpressionSegment").to_matchable(),
                ])
                .config(|this| this.min_times = 1)
                .to_matchable(),
                Ref::new("AliasExpressionSegment").optional().to_matchable(),
            ])
            .to_matchable()
            .into(),
        ),
        (
            "SingleIdentifierGrammar".into(),
            one_of(vec![
                Ref::new("NakedIdentifierSegment").to_matchable(),
                Ref::new("QuotedIdentifierSegment").to_matchable(),
                Ref::new("ColumnIndexIdentifierSegment").to_matchable(),
                Ref::new("ReferencedVariableNameSegment").to_matchable(),
                Ref::new("StagePath").to_matchable(),
                Sequence::new(vec![
                    Ref::keyword("IDENTIFIER").to_matchable(),
                    Bracketed::new(vec![
                        one_of(vec![
                            Ref::new("SingleQuotedIdentifierSegment").to_matchable(),
                            Ref::new("ReferencedVariableNameSegment").to_matchable(),
                        ])
                        .to_matchable(),
                    ])
                    .to_matchable(),
                ])
                .to_matchable(),
            ])
            .to_matchable()
            .into(),
        ),
        (
            "PostFunctionGrammar".into(),
            Sequence::new(vec![
                Ref::new("WithinGroupClauseSegment")
                    .optional()
                    .to_matchable(),
                Sequence::new(vec![
                    one_of(vec![
                        Ref::keyword("IGNORE").to_matchable(),
                        Ref::keyword("RESPECT").to_matchable(),
                    ])
                    .to_matchable(),
                    Ref::keyword("NULLS").to_matchable(),
                ])
                .config(|this| this.optional())
                .to_matchable(),
                Ref::new("OverClauseSegment").optional().to_matchable(),
            ])
            .to_matchable()
            .into(),
        ),
        (
            "TemporaryGrammar".into(),
            Sequence::new(vec![
                one_of(vec![
                    Ref::keyword("LOCAL").to_matchable(),
                    Ref::keyword("GLOBAL").to_matchable(),
                ])
                .config(|this| this.optional())
                .to_matchable(),
                one_of(vec![
                    Ref::keyword("TEMP").to_matchable(),
                    Ref::keyword("TEMPORARY").to_matchable(),
                ])
                .config(|this| this.optional())
                .to_matchable(),
                Sequence::new(vec![Ref::keyword("VOLATILE").to_matchable()])
                    .config(|this| this.optional())
                    .to_matchable(),
            ])
            .config(|this| this.optional())
            .to_matchable()
            .into(),
        ),
        (
            "TemporaryTransientGrammar".into(),
            one_of(vec![
                Ref::new("TemporaryGrammar").to_matchable(),
                Ref::keyword("TRANSIENT").to_matchable(),
            ])
            .to_matchable()
            .into(),
        ),
        (
            "BaseExpressionElementGrammar".into(),
            snowflake_dialect
                .grammar("BaseExpressionElementGrammar")
                .copy(
                    Some(vec![
                        Sequence::new(vec![
                            Ref::keyword("CONNECT_BY_ROOT").to_matchable(),
                            Ref::new("ColumnReferenceSegment").to_matchable(),
                        ])
                        .to_matchable(),
                    ]),
                    None,
                    Some(Ref::new("LiteralGrammar").to_matchable()),
                    None,
                    Vec::new(),
                    false,
                )
                .into(),
        ),
        (
            "QuotedLiteralSegment".into(),
            one_of(vec![
                TypedParser::new(SyntaxKind::SingleQuote, SyntaxKind::QuotedLiteral).to_matchable(),
                TypedParser::new(SyntaxKind::DollarQuote, SyntaxKind::QuotedLiteral).to_matchable(),
            ])
            .to_matchable()
            .into(),
        ),
        (
            "LikeGrammar".into(),
            one_of(vec![
                Sequence::new(vec![
                    Ref::keyword("LIKE").to_matchable(),
                    one_of(vec![
                        Ref::keyword("ALL").to_matchable(),
                        Ref::keyword("ANY").to_matchable(),
                    ])
                    .config(|this| this.optional())
                    .to_matchable(),
                ])
                .to_matchable(),
                Ref::keyword("RLIKE").to_matchable(),
                Sequence::new(vec![
                    Ref::keyword("ILIKE").to_matchable(),
                    Ref::keyword("ANY").optional().to_matchable(),
                ])
                .to_matchable(),
                Ref::keyword("REGEXP").to_matchable(),
            ])
            .to_matchable()
            .into(),
        ),
        (
            "SelectClauseTerminatorGrammar".into(),
            one_of(vec![
                Ref::keyword("FROM").to_matchable(),
                Ref::keyword("WHERE").to_matchable(),
                Sequence::new(vec![
                    Ref::keyword("ORDER").to_matchable(),
                    Ref::keyword("BY").to_matchable(),
                ])
                .to_matchable(),
                Ref::keyword("LIMIT").to_matchable(),
                Ref::keyword("FETCH").to_matchable(),
                Ref::keyword("OFFSET").to_matchable(),
                Ref::new("SetOperatorSegment").to_matchable(),
            ])
            .to_matchable()
            .into(),
        ),
        (
            "FromClauseTerminatorGrammar".into(),
            one_of(vec![
                Ref::keyword("WHERE").to_matchable(),
                Ref::keyword("LIMIT").to_matchable(),
                Ref::keyword("FETCH").to_matchable(),
                Ref::keyword("OFFSET").to_matchable(),
                Sequence::new(vec![
                    Ref::keyword("GROUP").to_matchable(),
                    Ref::keyword("BY").to_matchable(),
                ])
                .to_matchable(),
                Sequence::new(vec![
                    Ref::keyword("ORDER").to_matchable(),
                    Ref::keyword("BY").to_matchable(),
                ])
                .to_matchable(),
                Ref::keyword("HAVING").to_matchable(),
                Ref::keyword("QUALIFY").to_matchable(),
                Ref::keyword("WINDOW").to_matchable(),
                Ref::new("SetOperatorSegment").to_matchable(),
                Ref::new("WithNoSchemaBindingClauseSegment").to_matchable(),
                Ref::new("WithDataClauseSegment").to_matchable(),
            ])
            .to_matchable()
            .into(),
        ),
        (
            "WhereClauseTerminatorGrammar".into(),
            one_of(vec![
                Ref::keyword("LIMIT").to_matchable(),
                Ref::keyword("FETCH").to_matchable(),
                Ref::keyword("OFFSET").to_matchable(),
                Sequence::new(vec![
                    Ref::keyword("GROUP").to_matchable(),
                    Ref::keyword("BY").to_matchable(),
                ])
                .to_matchable(),
                Sequence::new(vec![
                    Ref::keyword("ORDER").to_matchable(),
                    Ref::keyword("BY").to_matchable(),
                ])
                .to_matchable(),
                Ref::keyword("HAVING").to_matchable(),
                Ref::keyword("QUALIFY").to_matchable(),
                Ref::keyword("WINDOW").to_matchable(),
                Ref::keyword("OVERLAPS").to_matchable(),
            ])
            .to_matchable()
            .into(),
        ),
        (
            "OrderByClauseTerminators".into(),
            one_of(vec![
                Ref::keyword("LIMIT").to_matchable(),
                Ref::keyword("HAVING").to_matchable(),
                Ref::keyword("QUALIFY").to_matchable(),
                Ref::keyword("WINDOW").to_matchable(),
                Ref::new("FrameClauseUnitGrammar").to_matchable(),
                Ref::keyword("SEPARATOR").to_matchable(),
                Ref::keyword("FETCH").to_matchable(),
                Ref::keyword("OFFSET").to_matchable(),
                Ref::keyword("MEASURES").to_matchable(),
            ])
            .to_matchable()
            .into(),
        ),
        (
            "TrimParametersGrammar".into(),
            Nothing::new().to_matchable().into(),
        ),
        (
            "GroupByClauseTerminatorGrammar".into(),
            one_of(vec![
                Ref::keyword("ORDER").to_matchable(),
                Ref::keyword("LIMIT").to_matchable(),
                Ref::keyword("FETCH").to_matchable(),
                Ref::keyword("OFFSET").to_matchable(),
                Ref::keyword("HAVING").to_matchable(),
                Ref::keyword("QUALIFY").to_matchable(),
                Ref::keyword("WINDOW").to_matchable(),
            ])
            .to_matchable()
            .into(),
        ),
        (
            "HavingClauseTerminatorGrammar".into(),
            one_of(vec![
                Sequence::new(vec![
                    Ref::keyword("ORDER").to_matchable(),
                    Ref::keyword("BY").to_matchable(),
                ])
                .to_matchable(),
                Ref::keyword("LIMIT").to_matchable(),
                Ref::keyword("QUALIFY").to_matchable(),
                Ref::keyword("WINDOW").to_matchable(),
                Ref::keyword("FETCH").to_matchable(),
                Ref::keyword("OFFSET").to_matchable(),
            ])
            .to_matchable()
            .into(),
        ),
    ]);

    snowflake_dialect.sets_mut("unreserved_keywords").clear();
    snowflake_dialect.update_keywords_set_from_multiline_string(
        "unreserved_keywords",
        SNOWFLAKE_UNRESERVED_KEYWORDS,
    );

    snowflake_dialect.sets_mut("reserved_keywords").clear();
    snowflake_dialect.update_keywords_set_from_multiline_string(
        "reserved_keywords",
        SNOWFLAKE_RESERVED_KEYWORDS,
    );

    snowflake_dialect.sets_mut("datetime_units").clear();
    snowflake_dialect.sets_mut("datetime_units").extend([
        "YEAR",
        "Y",
        "YY",
        "YYY",
        "YYYY",
        "YR",
        "YEARS",
        "YRS",
        "MONTH",
        "MM",
        "MON",
        "MONS",
        "MONTHS",
        "DAY",
        "D",
        "DD",
        "DAYS",
        "DAYOFMONTH",
        "DAYOFWEEK",
        "WEEKDAY",
        "DOW",
        "DW",
        "DAYOFWEEKISO",
        "WEEKDAY_ISO",
        "DOW_ISO",
        "DW_ISO",
        "DAYOFYEAR",
        "YEARDAY",
        "DOY",
        "DY",
        "WEEK",
        "W",
        "WK",
        "WEEKOFYEAR",
        "WOY",
        "WY",
        "WEEKISO",
        "WEEK_ISO",
        "WEEKOFYEARISO",
        "WEEKOFYEAR_ISO",
        "QUARTER",
        "Q",
        "QTR",
        "QTRS",
        "QUARTERS",
        "YEAROFWEEK",
        "YEAROFWEEKISO",
        "HOUR",
        "H",
        "HH",
        "HR",
        "HOURS",
        "HRS",
        "MINUTE",
        "M",
        "MI",
        "MIN",
        "MINUTES",
        "MINS",
        "SECOND",
        "S",
        "SEC",
        "SECONDS",
        "SECS",
        "MILLISECOND",
        "MS",
        "MSEC",
        "MILLISECONDS",
        "MICROSECOND",
        "US",
        "USEC",
        "MICROSECONDS",
        "NANOSECOND",
        "NS",
        "NSEC",
        "NANOSEC",
        "NSECOND",
        "NANOSECONDS",
        "NANOSECS",
        "NSECONDS",
        "EPOCH_SECOND",
        "EPOCH",
        "EPOCH_SECONDS",
        "EPOCH_MILLISECOND",
        "EPOCH_MILLISECONDS",
        "EPOCH_MICROSECOND",
        "EPOCH_MICROSECONDS",
        "EPOCH_NANOSECOND",
        "EPOCH_NANOSECONDS",
        "TIMEZONE_HOUR",
        "TZH",
        "TIMEZONE_MINUTE",
        "TZM",
    ]);

    snowflake_dialect.replace_grammar(
        "FunctionNameSegment",
        Sequence::new(vec![
            // Project name, schema identifier, etc.
            AnyNumberOf::new(vec![
                Sequence::new(vec![
                    Ref::new("SingleIdentifierGrammar").to_matchable(),
                    Ref::new("DotSegment").to_matchable(),
                ])
                .to_matchable(),
            ])
            .config(|this| {
                this.terminators = vec![Ref::new("BracketedSegment").to_matchable()];
            })
            .to_matchable(),
            // Base function name
            one_of(vec![
                Ref::new("FunctionNameIdentifierSegment").to_matchable(),
                Ref::new("QuotedIdentifierSegment").to_matchable(),
                // Snowflake's IDENTIFIER pseudo-function
                Sequence::new(vec![
                    Ref::keyword("IDENTIFIER").to_matchable(),
                    Bracketed::new(vec![
                        one_of(vec![
                            Ref::new("SingleQuotedIdentifierSegment").to_matchable(),
                            Ref::new("ReferencedVariableNameSegment").to_matchable(),
                        ])
                        .to_matchable(),
                    ])
                    .to_matchable(),
                ])
                .to_matchable(),
            ])
            .to_matchable(),
        ])
        .config(|this| {
            this.allow_gaps = false;
        })
        .to_matchable(),
    );

    snowflake_dialect.add([(
        "ConnectByClauseSegment".into(),
        NodeMatcher::new(SyntaxKind::ConnectbyClause, |_| {
            Sequence::new(vec![
                Ref::keyword("START").to_matchable(),
                Ref::keyword("WITH").to_matchable(),
                Ref::new("ExpressionSegment").to_matchable(),
                Ref::keyword("CONNECT").to_matchable(),
                Ref::keyword("BY").to_matchable(),
                Delimited::new(vec![
                    Sequence::new(vec![
                        Ref::keyword("PRIOR").optional().to_matchable(),
                        Ref::new("ColumnReferenceSegment").to_matchable(),
                        Ref::new("EqualsSegment").to_matchable(),
                        Ref::keyword("PRIOR").optional().to_matchable(),
                        Ref::new("ColumnReferenceSegment").to_matchable(),
                    ])
                    .to_matchable(),
                ])
                .to_matchable(),
            ])
            .to_matchable()
        })
        .to_matchable()
        .into(),
    )]);

    snowflake_dialect.replace_grammar(
        "GroupByClauseSegment",
        Sequence::new(vec![
            Ref::keyword("GROUP").to_matchable(),
            Ref::keyword("BY").to_matchable(),
            MetaSegment::indent().to_matchable(),
            one_of(vec![
                Sequence::new(vec![
                    one_of(vec![
                        Ref::keyword("CUBE").to_matchable(),
                        Ref::keyword("ROLLUP").to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("GROUPING").to_matchable(),
                            Ref::keyword("SETS").to_matchable(),
                        ])
                        .to_matchable(),
                    ])
                    .to_matchable(),
                    Bracketed::new(vec![Ref::new("GroupByContentsGrammar").to_matchable()])
                        .to_matchable(),
                ])
                .to_matchable(),
                Ref::keyword("ALL").to_matchable(),
                Ref::new("GroupByContentsGrammar").to_matchable(),
            ])
            .to_matchable(),
            MetaSegment::dedent().to_matchable(),
        ])
        .to_matchable(),
    );

    snowflake_dialect.replace_grammar(
        "ValuesClauseSegment",
        Sequence::new(vec![
            Ref::keyword("VALUES").to_matchable(),
            Delimited::new(vec![
                Bracketed::new(vec![
                    Delimited::new(vec![
                        Ref::keyword("DEFAULT").to_matchable(),
                        Ref::keyword("NULL").to_matchable(),
                        Ref::new("ExpressionSegment").to_matchable(),
                    ])
                    .to_matchable(),
                ])
                .config(|this| {
                    this.parse_mode = ParseMode::Greedy;
                })
                .to_matchable(),
            ])
            .to_matchable(),
        ])
        .to_matchable(),
    );

    snowflake_dialect.add([(
        "InsertStatementSegment".into(),
        NodeMatcher::new(SyntaxKind::InsertStatement, |_| {
            Sequence::new(vec![
                Ref::keyword("INSERT").to_matchable(),
                Ref::keyword("OVERWRITE").optional().to_matchable(),
                one_of(vec![
                    // Single table INSERT INTO
                    Sequence::new(vec![
                        Ref::keyword("INTO").to_matchable(),
                        Ref::new("TableReferenceSegment").to_matchable(),
                        Ref::new("BracketedColumnReferenceListGrammar")
                            .optional()
                            .to_matchable(),
                        Ref::new("SelectableGrammar").to_matchable(),
                    ])
                    .to_matchable(),
                    // Unconditional multi-table INSERT INTO
                    Sequence::new(vec![
                        Ref::keyword("ALL").to_matchable(),
                        AnyNumberOf::new(vec![
                            Sequence::new(vec![
                                Ref::keyword("INTO").to_matchable(),
                                Ref::new("TableReferenceSegment").to_matchable(),
                                Ref::new("BracketedColumnReferenceListGrammar")
                                    .optional()
                                    .to_matchable(),
                                Ref::new("ValuesClauseSegment").optional().to_matchable(),
                            ])
                            .to_matchable(),
                        ])
                        .config(|this| {
                            this.min_times = 1;
                        })
                        .to_matchable(),
                        Ref::new("SelectStatementSegment").to_matchable(),
                    ])
                    .to_matchable(),
                    // Conditional multi-table INSERT INTO
                    Sequence::new(vec![
                        one_of(vec![
                            Ref::keyword("FIRST").to_matchable(),
                            Ref::keyword("ALL").to_matchable(),
                        ])
                        .to_matchable(),
                        AnyNumberOf::new(vec![
                            Sequence::new(vec![
                                Ref::keyword("WHEN").to_matchable(),
                                Ref::new("ExpressionSegment").to_matchable(),
                                Ref::keyword("THEN").to_matchable(),
                                AnyNumberOf::new(vec![
                                    Sequence::new(vec![
                                        Ref::keyword("INTO").to_matchable(),
                                        Ref::new("TableReferenceSegment").to_matchable(),
                                        Ref::new("BracketedColumnReferenceListGrammar")
                                            .optional()
                                            .to_matchable(),
                                        Ref::new("ValuesClauseSegment").optional().to_matchable(),
                                    ])
                                    .to_matchable(),
                                ])
                                .config(|this| {
                                    this.min_times = 1;
                                })
                                .to_matchable(),
                            ])
                            .to_matchable(),
                        ])
                        .config(|this| {
                            this.min_times = 1;
                        })
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("ELSE").to_matchable(),
                            Ref::keyword("INTO").to_matchable(),
                            Ref::new("TableReferenceSegment").to_matchable(),
                            Ref::new("BracketedColumnReferenceListGrammar")
                                .optional()
                                .to_matchable(),
                            Ref::new("ValuesClauseSegment").optional().to_matchable(),
                        ])
                        .config(|this| this.optional())
                        .to_matchable(),
                        Ref::new("SelectStatementSegment").to_matchable(),
                    ])
                    .to_matchable(),
                ])
                .to_matchable(),
            ])
            .to_matchable()
        })
        .to_matchable()
        .into(),
    )]);

    snowflake_dialect.replace_grammar(
        "FunctionDefinitionGrammar",
        Sequence::new(vec![
            Ref::keyword("AS").to_matchable(),
            Ref::new("QuotedLiteralSegment").to_matchable(),
            Sequence::new(vec![
                Ref::keyword("LANGUAGE").to_matchable(),
                Ref::new("NakedIdentifierSegment").to_matchable(),
            ])
            .config(|this| this.optional())
            .to_matchable(),
        ])
        .to_matchable(),
    );

    snowflake_dialect.replace_grammar(
        "StatementSegment",
        ansi::statement_segment().copy(
            Some(vec![
                Ref::new("AccessStatementSegment").to_matchable(),
                Ref::new("CreateStatementSegment").to_matchable(),
                Ref::new("CreateTaskSegment").to_matchable(),
                Ref::new("CreateUserSegment").to_matchable(),
                Ref::new("CreateCloneStatementSegment").to_matchable(),
                Ref::new("CreateProcedureStatementSegment").to_matchable(),
                Ref::new("AlterProcedureStatementSegment").to_matchable(),
                Ref::new("ScriptingBlockStatementSegment").to_matchable(),
                Ref::new("ScriptingLetStatementSegment").to_matchable(),
                Ref::new("ReturnStatementSegment").to_matchable(),
                Ref::new("ShowStatementSegment").to_matchable(),
                Ref::new("AlterAccountStatementSegment").to_matchable(),
                Ref::new("AlterUserStatementSegment").to_matchable(),
                Ref::new("AlterSessionStatementSegment").to_matchable(),
                Ref::new("AlterTaskStatementSegment").to_matchable(),
                Ref::new("SetAssignmentStatementSegment").to_matchable(),
                Ref::new("CallStoredProcedureSegment").to_matchable(),
                Ref::new("MergeStatementSegment").to_matchable(),
                Ref::new("CopyIntoTableStatementSegment").to_matchable(),
                Ref::new("CopyIntoLocationStatementSegment").to_matchable(),
                Ref::new("FormatTypeOptions").to_matchable(),
                Ref::new("AlterWarehouseStatementSegment").to_matchable(),
                Ref::new("AlterShareStatementSegment").to_matchable(),
                Ref::new("CreateExternalTableSegment").to_matchable(),
                Ref::new("AlterExternalTableStatementSegment").to_matchable(),
                Ref::new("CreateSchemaStatementSegment").to_matchable(),
                Ref::new("AlterSchemaStatementSegment").to_matchable(),
                Ref::new("CreateFunctionStatementSegment").to_matchable(),
                Ref::new("AlterFunctionStatementSegment").to_matchable(),
                Ref::new("CreateExternalFunctionStatementSegment").to_matchable(),
                Ref::new("CreateStageSegment").to_matchable(),
                Ref::new("AlterStageSegment").to_matchable(),
                Ref::new("CreateStreamStatementSegment").to_matchable(),
                Ref::new("AlterStreamStatementSegment").to_matchable(),
                Ref::new("UnsetStatementSegment").to_matchable(),
                Ref::new("UndropStatementSegment").to_matchable(),
                Ref::new("CommentStatementSegment").to_matchable(),
                Ref::new("CallStatementSegment").to_matchable(),
                Ref::new("AlterViewStatementSegment").to_matchable(),
                Ref::new("AlterMaterializedViewStatementSegment").to_matchable(),
                Ref::new("DropProcedureStatementSegment").to_matchable(),
                Ref::new("DropExternalTableStatementSegment").to_matchable(),
                Ref::new("DropMaterializedViewStatementSegment").to_matchable(),
                Ref::new("DropObjectStatementSegment").to_matchable(),
                Ref::new("CreateFileFormatSegment").to_matchable(),
                Ref::new("AlterFileFormatSegment").to_matchable(),
                Ref::new("AlterPipeSegment").to_matchable(),
                Ref::new("ListStatementSegment").to_matchable(),
                Ref::new("GetStatementSegment").to_matchable(),
                Ref::new("PutStatementSegment").to_matchable(),
                Ref::new("RemoveStatementSegment").to_matchable(),
                Ref::new("CreateDatabaseFromShareStatementSegment").to_matchable(),
                Ref::new("AlterRoleStatementSegment").to_matchable(),
                Ref::new("AlterStorageIntegrationSegment").to_matchable(),
                Ref::new("ExecuteImmediateClauseSegment").to_matchable(),
                Ref::new("ExecuteTaskClauseSegment").to_matchable(),
                Ref::new("CreateSequenceStatementSegment").to_matchable(),
                Ref::new("AlterSequenceStatementSegment").to_matchable(),
                Ref::new("CreateResourceMonitorStatementSegment").to_matchable(),
                Ref::new("AlterResourceMonitorStatementSegment").to_matchable(),
                Ref::new("DropResourceMonitorStatementSegment").to_matchable(),
                Ref::new("AlterDatabaseSegment").to_matchable(),
                Ref::new("AlterMaskingPolicySegment").to_matchable(),
                Ref::new("AlterNetworkPolicyStatementSegment").to_matchable(),
            ]),
            None,
            None,
            Some(vec![
                Ref::new("CreateIndexStatementSegment").to_matchable(),
                Ref::new("DropIndexStatementSegment").to_matchable(),
            ]),
            Vec::new(),
            false,
        ),
    );

    snowflake_dialect.add([
        (
            "SetAssignmentStatementSegment".into(),
            NodeMatcher::new(SyntaxKind::SetStatement, |_| {
                one_of(vec![
                    Sequence::new(vec![
                        Ref::keyword("SET").to_matchable(),
                        Ref::new("LocalVariableNameSegment").to_matchable(),
                        Ref::new("EqualsSegment").to_matchable(),
                        Ref::new("ExpressionSegment").to_matchable(),
                    ])
                    .to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("SET").to_matchable(),
                        Bracketed::new(vec![
                            Delimited::new(vec![
                                Ref::new("LocalVariableNameSegment").to_matchable(),
                            ])
                            .to_matchable(),
                        ])
                        .to_matchable(),
                        Ref::new("EqualsSegment").to_matchable(),
                        Bracketed::new(vec![
                            Delimited::new(vec![Ref::new("ExpressionSegment").to_matchable()])
                                .to_matchable(),
                        ])
                        .to_matchable(),
                    ])
                    .to_matchable(),
                ])
                .to_matchable()
            })
            .to_matchable()
            .into(),
        ),
        (
            "CallStoredProcedureSegment".into(),
            NodeMatcher::new(SyntaxKind::CallSegment, |_| {
                Sequence::new(vec![
                    Ref::keyword("CALL").to_matchable(),
                    Ref::new("FunctionSegment").to_matchable(),
                ])
                .to_matchable()
            })
            .to_matchable()
            .into(),
        ),
        (
            "WithinGroupClauseSegment".into(),
            NodeMatcher::new(SyntaxKind::WithingroupClause, |_| {
                Sequence::new(vec![
                    Ref::keyword("WITHIN").to_matchable(),
                    Ref::keyword("GROUP").to_matchable(),
                    Bracketed::new(vec![
                        Ref::new("OrderByClauseSegment").optional().to_matchable(),
                    ])
                    .config(|this| {
                        this.parse_mode = ParseMode::Greedy;
                    })
                    .to_matchable(),
                ])
                .to_matchable()
            })
            .to_matchable()
            .into(),
        ),
        (
            "PatternSegment".into(),
            NodeMatcher::new(SyntaxKind::PatternExpression, |_| {
                Sequence::new(vec![
                    Ref::new("CaretSegment").optional().to_matchable(),
                    one_of(vec![
                        AnyNumberOf::new(vec![Ref::new("PatternOperatorGrammar").to_matchable()])
                            .to_matchable(),
                        Delimited::new(vec![Ref::new("PatternOperatorGrammar").to_matchable()])
                            .config(|this| this.delimiter(Ref::new("BitwiseOrSegment")))
                            .to_matchable(),
                    ])
                    .to_matchable(),
                    Ref::new("DollarSegment").optional().to_matchable(),
                ])
                .to_matchable()
            })
            .to_matchable()
            .into(),
        ),
        (
            "MatchRecognizeClauseSegment".into(),
            NodeMatcher::new(SyntaxKind::MatchRecognizeClause, |_| {
                Sequence::new(vec![
                    Ref::keyword("MATCH_RECOGNIZE").to_matchable(),
                    Bracketed::new(vec![
                        Ref::new("PartitionClauseSegment").optional().to_matchable(),
                        Ref::new("OrderByClauseSegment").optional().to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("MEASURES").to_matchable(),
                            Delimited::new(vec![
                                Sequence::new(vec![
                                    one_of(vec![
                                        Ref::keyword("FINAL").to_matchable(),
                                        Ref::keyword("RUNNING").to_matchable(),
                                    ])
                                    .config(|this| this.optional())
                                    .to_matchable(),
                                    Ref::new("ExpressionSegment").to_matchable(),
                                    Ref::new("AliasExpressionSegment").to_matchable(),
                                ])
                                .to_matchable(),
                            ])
                            .to_matchable(),
                        ])
                        .config(|this| this.optional())
                        .to_matchable(),
                        one_of(vec![
                            Sequence::new(vec![
                                Ref::keyword("ONE").to_matchable(),
                                Ref::keyword("ROW").to_matchable(),
                                Ref::keyword("PER").to_matchable(),
                                Ref::keyword("MATCH").to_matchable(),
                            ])
                            .to_matchable(),
                            Sequence::new(vec![
                                Ref::keyword("ALL").to_matchable(),
                                Ref::keyword("ROWS").to_matchable(),
                                Ref::keyword("PER").to_matchable(),
                                Ref::keyword("MATCH").to_matchable(),
                                one_of(vec![
                                    Sequence::new(vec![
                                        Ref::keyword("SHOW").to_matchable(),
                                        Ref::keyword("EMPTY").to_matchable(),
                                        Ref::keyword("MATCHES").to_matchable(),
                                    ])
                                    .to_matchable(),
                                    Sequence::new(vec![
                                        Ref::keyword("OMIT").to_matchable(),
                                        Ref::keyword("EMPTY").to_matchable(),
                                        Ref::keyword("MATCHES").to_matchable(),
                                    ])
                                    .to_matchable(),
                                    Sequence::new(vec![
                                        Ref::keyword("WITH").to_matchable(),
                                        Ref::keyword("UNMATCHED").to_matchable(),
                                        Ref::keyword("ROWS").to_matchable(),
                                    ])
                                    .to_matchable(),
                                ])
                                .config(|this| this.optional())
                                .to_matchable(),
                            ])
                            .to_matchable(),
                        ])
                        .config(|this| this.optional())
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("AFTER").to_matchable(),
                            Ref::keyword("MATCH").to_matchable(),
                            Ref::keyword("SKIP").to_matchable(),
                            one_of(vec![
                                Sequence::new(vec![
                                    Ref::keyword("PAST").to_matchable(),
                                    Ref::keyword("LAST").to_matchable(),
                                    Ref::keyword("ROW").to_matchable(),
                                ])
                                .to_matchable(),
                                Sequence::new(vec![
                                    Ref::keyword("TO").to_matchable(),
                                    Ref::keyword("NEXT").to_matchable(),
                                    Ref::keyword("ROW").to_matchable(),
                                ])
                                .to_matchable(),
                                Sequence::new(vec![
                                    Ref::keyword("TO").to_matchable(),
                                    one_of(vec![
                                        Ref::keyword("FIRST").to_matchable(),
                                        Ref::keyword("LAST").to_matchable(),
                                    ])
                                    .config(|this| this.optional())
                                    .to_matchable(),
                                    Ref::new("SingleIdentifierGrammar").to_matchable(),
                                ])
                                .to_matchable(),
                            ])
                            .to_matchable(),
                        ])
                        .config(|this| this.optional())
                        .to_matchable(),
                        Ref::keyword("PATTERN").to_matchable(),
                        Bracketed::new(vec![Ref::new("PatternSegment").to_matchable()])
                            .to_matchable(),
                        Ref::keyword("DEFINE").to_matchable(),
                        Delimited::new(vec![
                            Sequence::new(vec![
                                Ref::new("SingleIdentifierGrammar").to_matchable(),
                                Ref::keyword("AS").to_matchable(),
                                Ref::new("ExpressionSegment").to_matchable(),
                            ])
                            .to_matchable(),
                        ])
                        .to_matchable(),
                    ])
                    .to_matchable(),
                ])
                .to_matchable()
            })
            .to_matchable()
            .into(),
        ),
        (
            "ChangesClauseSegment".into(),
            NodeMatcher::new(SyntaxKind::ChangesClause, |_| {
                Sequence::new(vec![
                    Ref::keyword("CHANGES").to_matchable(),
                    Bracketed::new(vec![
                        Ref::keyword("INFORMATION").to_matchable(),
                        Ref::new("ParameterAssignerSegment").to_matchable(),
                        one_of(vec![
                            Ref::keyword("DEFAULT").to_matchable(),
                            Ref::keyword("APPEND_ONLY").to_matchable(),
                        ])
                        .to_matchable(),
                    ])
                    .to_matchable(),
                    one_of(vec![
                        Sequence::new(vec![
                            Ref::keyword("AT").to_matchable(),
                            Bracketed::new(vec![
                                one_of(vec![
                                    Ref::keyword("TIMESTAMP").to_matchable(),
                                    Ref::keyword("OFFSET").to_matchable(),
                                    Ref::keyword("STATEMENT").to_matchable(),
                                ])
                                .to_matchable(),
                                Ref::new("ParameterAssignerSegment").to_matchable(),
                                Ref::new("ExpressionSegment").to_matchable(),
                            ])
                            .to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("BEFORE").to_matchable(),
                            Bracketed::new(vec![
                                Ref::keyword("STATEMENT").to_matchable(),
                                Ref::new("ParameterAssignerSegment").to_matchable(),
                                Ref::new("ExpressionSegment").to_matchable(),
                            ])
                            .to_matchable(),
                        ])
                        .to_matchable(),
                    ])
                    .to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("END").to_matchable(),
                        Bracketed::new(vec![
                            one_of(vec![
                                Ref::keyword("TIMESTAMP").to_matchable(),
                                Ref::keyword("OFFSET").to_matchable(),
                                Ref::keyword("STATEMENT").to_matchable(),
                            ])
                            .to_matchable(),
                            Ref::new("ParameterAssignerSegment").to_matchable(),
                            Ref::new("ExpressionSegment").to_matchable(),
                        ])
                        .to_matchable(),
                    ])
                    .config(|this| this.optional())
                    .to_matchable(),
                ])
                .to_matchable()
            })
            .to_matchable()
            .into(),
        ),
        (
            "MatchConditionSegment".into(),
            NodeMatcher::new(SyntaxKind::MatchConditionClause, |_| {
                Sequence::new(vec![
                    Ref::keyword("MATCH_CONDITION").to_matchable(),
                    Bracketed::new(vec![Ref::new("ExpressionSegment").to_matchable()])
                        .to_matchable(),
                ])
                .to_matchable()
            })
            .to_matchable()
            .into(),
        ),
        (
            "FromAtExpressionSegment".into(),
            NodeMatcher::new(SyntaxKind::FromAtExpression, |_| {
                Sequence::new(vec![
                    Ref::keyword("AT").to_matchable(),
                    Bracketed::new(vec![
                        one_of(vec![
                            Ref::keyword("TIMESTAMP").to_matchable(),
                            Ref::keyword("OFFSET").to_matchable(),
                            Ref::keyword("STATEMENT").to_matchable(),
                        ])
                        .to_matchable(),
                        Ref::new("ParameterAssignerSegment").to_matchable(),
                        Ref::new("ExpressionSegment").to_matchable(),
                    ])
                    .to_matchable(),
                ])
                .to_matchable()
            })
            .to_matchable()
            .into(),
        ),
        (
            "FromBeforeExpressionSegment".into(),
            NodeMatcher::new(SyntaxKind::FromBeforeExpression, |_| {
                Sequence::new(vec![
                    Ref::keyword("BEFORE").to_matchable(),
                    Bracketed::new(vec![
                        one_of(vec![
                            Ref::keyword("TIMESTAMP").to_matchable(),
                            Ref::keyword("OFFSET").to_matchable(),
                            Ref::keyword("STATEMENT").to_matchable(),
                        ])
                        .to_matchable(),
                        Ref::new("ParameterAssignerSegment").to_matchable(),
                        Ref::new("ExpressionSegment").to_matchable(),
                    ])
                    .config(|this| {
                        this.parse_mode = ParseMode::Greedy;
                    })
                    .to_matchable(),
                ])
                .to_matchable()
            })
            .to_matchable()
            .into(),
        ),
        (
            "FromPivotExpressionSegment".into(),
            NodeMatcher::new(SyntaxKind::FromPivotExpression, |_| {
                Sequence::new(vec![
                    Ref::keyword("PIVOT").to_matchable(),
                    Bracketed::new(vec![
                        Ref::new("FunctionSegment").to_matchable(),
                        Ref::keyword("FOR").to_matchable(),
                        Ref::new("SingleIdentifierGrammar").to_matchable(),
                        Ref::keyword("IN").to_matchable(),
                        Bracketed::new(vec![
                            Delimited::new(vec![Ref::new("LiteralGrammar").to_matchable()])
                                .to_matchable(),
                        ])
                        .to_matchable(),
                    ])
                    .to_matchable(),
                ])
                .to_matchable()
            })
            .to_matchable()
            .into(),
        ),
        (
            "FromUnpivotExpressionSegment".into(),
            NodeMatcher::new(SyntaxKind::FromUnpivotExpression, |_| {
                Sequence::new(vec![
                    Ref::keyword("UNPIVOT").to_matchable(),
                    Bracketed::new(vec![
                        Ref::new("SingleIdentifierGrammar").to_matchable(),
                        Ref::keyword("FOR").to_matchable(),
                        Ref::new("SingleIdentifierGrammar").to_matchable(),
                        Ref::keyword("IN").to_matchable(),
                        Bracketed::new(vec![
                            Delimited::new(vec![
                                Ref::new("SingleIdentifierGrammar").to_matchable(),
                            ])
                            .to_matchable(),
                        ])
                        .to_matchable(),
                    ])
                    .to_matchable(),
                ])
                .to_matchable()
            })
            .to_matchable()
            .into(),
        ),
    ]);

    snowflake_dialect.replace_grammar(
        "SamplingExpressionSegment",
        Sequence::new(vec![
            one_of(vec![
                Ref::keyword("SAMPLE").to_matchable(),
                Ref::keyword("TABLESAMPLE").to_matchable(),
            ])
            .to_matchable(),
            one_of(vec![
                Ref::keyword("BERNOULLI").to_matchable(),
                Ref::keyword("ROW").to_matchable(),
                Ref::keyword("SYSTEM").to_matchable(),
                Ref::keyword("BLOCK").to_matchable(),
            ])
            .config(|this| this.optional())
            .to_matchable(),
            Bracketed::new(vec![
                one_of(vec![
                    Ref::new("NumericLiteralSegment").to_matchable(),
                    Ref::new("ReferencedVariableNameSegment").to_matchable(),
                ])
                .to_matchable(),
                Ref::keyword("ROWS").optional().to_matchable(),
            ])
            .to_matchable(),
            Sequence::new(vec![
                one_of(vec![
                    Ref::keyword("REPEATABLE").to_matchable(),
                    Ref::keyword("SEED").to_matchable(),
                ])
                .to_matchable(),
                Bracketed::new(vec![Ref::new("NumericLiteralSegment").to_matchable()])
                    .to_matchable(),
            ])
            .config(|this| this.optional())
            .to_matchable(),
        ])
        .to_matchable(),
    );

    snowflake_dialect.add([
        (
            "NamedParameterExpressionSegment".into(),
            NodeMatcher::new(SyntaxKind::SnowflakeKeywordExpression, |_| {
                Sequence::new(vec![
                    Ref::new("ParameterNameSegment").to_matchable(),
                    Ref::new("ParameterAssignerSegment").to_matchable(),
                    one_of(vec![
                        Ref::new("LiteralGrammar").to_matchable(),
                        Ref::new("ColumnReferenceSegment").to_matchable(),
                        Ref::new("ExpressionSegment").to_matchable(),
                    ])
                    .to_matchable(),
                ])
                .to_matchable()
            })
            .to_matchable()
            .into(),
        ),
        (
            "SemiStructuredAccessorSegment".into(),
            NodeMatcher::new(SyntaxKind::SemiStructuredExpression, |_| {
                Sequence::new(vec![
                    one_of(vec![
                        Ref::new("DotSegment").to_matchable(),
                        Ref::new("ColonSegment").to_matchable(),
                    ])
                    .to_matchable(),
                    one_of(vec![
                        Ref::new("NakedSemiStructuredElementSegment").to_matchable(),
                        Ref::new("QuotedSemiStructuredElementSegment").to_matchable(),
                    ])
                    .to_matchable(),
                    Ref::new("ArrayAccessorSegment").optional().to_matchable(),
                    AnyNumberOf::new(vec![
                        Sequence::new(vec![
                            one_of(vec![
                                Ref::new("DotSegment").to_matchable(),
                                Ref::new("ColonSegment").to_matchable(),
                            ])
                            .to_matchable(),
                            one_of(vec![
                                Ref::new("NakedSemiStructuredElementSegment").to_matchable(),
                                Ref::new("QuotedSemiStructuredElementSegment").to_matchable(),
                            ])
                            .to_matchable(),
                        ])
                        .config(|this| {
                            this.allow_gaps = true;
                        })
                        .to_matchable(),
                        Ref::new("ArrayAccessorSegment").optional().to_matchable(),
                    ])
                    .config(|this| {
                        this.allow_gaps = true;
                    })
                    .to_matchable(),
                ])
                .config(|this| {
                    this.allow_gaps = true;
                })
                .to_matchable()
            })
            .to_matchable()
            .into(),
        ),
        (
            "QualifyClauseSegment".into(),
            NodeMatcher::new(SyntaxKind::QualifyClause, |_| {
                Sequence::new(vec![
                    Ref::keyword("QUALIFY").to_matchable(),
                    MetaSegment::indent().to_matchable(),
                    one_of(vec![
                        Bracketed::new(vec![Ref::new("ExpressionSegment").to_matchable()])
                            .to_matchable(),
                        Ref::new("ExpressionSegment").to_matchable(),
                    ])
                    .to_matchable(),
                    MetaSegment::dedent().to_matchable(),
                ])
                .to_matchable()
            })
            .to_matchable()
            .into(),
        ),
    ]);

    snowflake_dialect.replace_grammar(
        "SelectStatementSegment",
        ansi::select_statement().copy(
            Some(vec![
                Ref::new("QualifyClauseSegment").optional().to_matchable(),
            ]),
            None,
            Some(Ref::new("OrderByClauseSegment").optional().to_matchable()),
            None,
            Vec::new(),
            false,
        ),
    );

    snowflake_dialect.replace_grammar(
        "WildcardExpressionSegment",
        ansi::wildcard_expression_segment().copy(
            Some(vec![
                Ref::new("ExcludeClauseSegment").optional().to_matchable(),
                Ref::new("ReplaceClauseSegment").optional().to_matchable(),
                Ref::new("RenameClauseSegment").optional().to_matchable(),
            ]),
            None,
            None,
            None,
            Vec::new(),
            false,
        ),
    );

    snowflake_dialect.add([
        (
            "ExcludeClauseSegment".into(),
            NodeMatcher::new(SyntaxKind::SelectExcludeClause, |_| {
                Sequence::new(vec![
                    Ref::keyword("EXCLUDE").to_matchable(),
                    one_of(vec![
                        Bracketed::new(vec![
                            Delimited::new(vec![
                                Ref::new("SingleIdentifierGrammar").to_matchable(),
                            ])
                            .to_matchable(),
                        ])
                        .to_matchable(),
                        Ref::new("SingleIdentifierGrammar").to_matchable(),
                    ])
                    .to_matchable(),
                ])
                .to_matchable()
            })
            .to_matchable()
            .into(),
        ),
        (
            "RenameClauseSegment".into(),
            NodeMatcher::new(SyntaxKind::SelectRenameClause, |_| {
                Sequence::new(vec![
                    Ref::keyword("RENAME").to_matchable(),
                    one_of(vec![
                        Sequence::new(vec![
                            Ref::new("SingleIdentifierGrammar").to_matchable(),
                            Ref::keyword("AS").to_matchable(),
                            Ref::new("SingleIdentifierGrammar").to_matchable(),
                        ])
                        .to_matchable(),
                        Bracketed::new(vec![
                            Delimited::new(vec![
                                Sequence::new(vec![
                                    Ref::new("SingleIdentifierGrammar").to_matchable(),
                                    Ref::keyword("AS").to_matchable(),
                                    Ref::new("SingleIdentifierGrammar").to_matchable(),
                                ])
                                .to_matchable(),
                            ])
                            .to_matchable(),
                        ])
                        .to_matchable(),
                    ])
                    .to_matchable(),
                ])
                .to_matchable()
            })
            .to_matchable()
            .into(),
        ),
        (
            "ReplaceClauseSegment".into(),
            NodeMatcher::new(SyntaxKind::SelectReplaceClause, |_| {
                Sequence::new(vec![
                    Ref::keyword("REPLACE").to_matchable(),
                    Bracketed::new(vec![
                        Delimited::new(vec![
                            Sequence::new(vec![
                                Ref::new("ExpressionSegment").to_matchable(),
                                Ref::keyword("AS").to_matchable(),
                                Ref::new("SingleIdentifierGrammar").to_matchable(),
                            ])
                            .to_matchable(),
                        ])
                        .to_matchable(),
                    ])
                    .to_matchable(),
                ])
                .to_matchable()
            })
            .to_matchable()
            .into(),
        ),
    ]);

    snowflake_dialect.replace_grammar(
        "SelectClauseModifierSegment",
        Sequence::new(vec![
            one_of(vec![
                Ref::keyword("DISTINCT").to_matchable(),
                Ref::keyword("ALL").to_matchable(),
            ])
            .config(|this| this.optional())
            .to_matchable(),
            Sequence::new(vec![
                Ref::keyword("TOP").to_matchable(),
                Ref::new("NumericLiteralSegment").to_matchable(),
            ])
            .config(|this| this.optional())
            .to_matchable(),
        ])
        .to_matchable(),
    );

    snowflake_dialect.replace_grammar(
        "AlterTableStatementSegment",
        Sequence::new(vec![
            Ref::keyword("ALTER").to_matchable(),
            Ref::keyword("TABLE").to_matchable(),
            Ref::new("IfExistsGrammar").optional().to_matchable(),
            Ref::new("TableReferenceSegment").to_matchable(),
            one_of(vec![
                // Rename
                Sequence::new(vec![
                    Ref::keyword("RENAME").to_matchable(),
                    Ref::keyword("TO").to_matchable(),
                    Ref::new("TableReferenceSegment").to_matchable(),
                ])
                .to_matchable(),
                // Swap With
                Sequence::new(vec![
                    Ref::keyword("SWAP").to_matchable(),
                    Ref::keyword("WITH").to_matchable(),
                    Ref::new("TableReferenceSegment").to_matchable(),
                ])
                .to_matchable(),
                // searchOptimizationAction
                Sequence::new(vec![
                    one_of(vec![
                        Ref::keyword("ADD").to_matchable(),
                        Ref::keyword("DROP").to_matchable(),
                    ])
                    .to_matchable(),
                    Ref::keyword("SEARCH").to_matchable(),
                    Ref::keyword("OPTIMIZATION").to_matchable(),
                ])
                .to_matchable(),
                Ref::new("AlterTableClusteringActionSegment").to_matchable(),
                Ref::new("AlterTableConstraintActionSegment").to_matchable(),
                // SET Table options
                Sequence::new(vec![
                    Ref::keyword("SET").to_matchable(),
                    one_of(vec![
                        Ref::new("ParameterNameSegment").to_matchable(),
                        Ref::keyword("COMMENT").to_matchable(),
                    ])
                    .to_matchable(),
                    Ref::new("EqualsSegment").optional().to_matchable(),
                    one_of(vec![
                        Ref::new("LiteralGrammar").to_matchable(),
                        Ref::new("NakedIdentifierSegment").to_matchable(),
                        Ref::new("QuotedLiteralSegment").to_matchable(),
                    ])
                    .to_matchable(),
                ])
                .to_matchable(),
                // Drop primary key
                Sequence::new(vec![
                    Ref::keyword("DROP").to_matchable(),
                    Ref::new("PrimaryKeyGrammar").to_matchable(),
                ])
                .to_matchable(),
                // Add primary key
                Sequence::new(vec![
                    Ref::keyword("ADD").to_matchable(),
                    Ref::new("PrimaryKeyGrammar").to_matchable(),
                    Bracketed::new(vec![
                        Delimited::new(vec![Ref::new("ColumnReferenceSegment").to_matchable()])
                            .config(|this| this.optional())
                            .to_matchable(),
                    ])
                    .to_matchable(),
                ])
                .to_matchable(),
                Ref::new("AlterTableTableColumnActionSegment").to_matchable(),
            ])
            .to_matchable(),
        ])
        .to_matchable(),
    );

    snowflake_dialect.add([
        (
            "AlterTableTableColumnActionSegment".into(),
            NodeMatcher::new(SyntaxKind::AlterTableTableColumnAction, |_| {
                one_of(vec![
                    // Add Column
                    Sequence::new(vec![
                        Ref::keyword("ADD").to_matchable(),
                        Ref::keyword("COLUMN").optional().to_matchable(),
                        Delimited::new(vec![
                            Sequence::new(vec![
                                Ref::new("ColumnReferenceSegment").to_matchable(),
                                Ref::new("DatatypeSegment").to_matchable(),
                                one_of(vec![
                                    // Default
                                    Sequence::new(vec![
                                        Ref::keyword("DEFAULT").to_matchable(),
                                        Ref::new("ExpressionSegment").to_matchable(),
                                    ])
                                    .to_matchable(),
                                    // Auto-increment/identity column
                                    Sequence::new(vec![
                                        one_of(vec![
                                            Ref::keyword("AUTOINCREMENT").to_matchable(),
                                            Ref::keyword("IDENTITY").to_matchable(),
                                        ])
                                        .to_matchable(),
                                        one_of(vec![
                                            // ( <start_num>, <step_num> )
                                            Bracketed::new(vec![
                                                Ref::new("NumericLiteralSegment").to_matchable(),
                                                Ref::new("CommaSegment").to_matchable(),
                                                Ref::new("NumericLiteralSegment").to_matchable(),
                                            ])
                                            .to_matchable(),
                                            // START <num> INCREMENT <num>
                                            Sequence::new(vec![
                                                Ref::keyword("START").to_matchable(),
                                                Ref::new("NumericLiteralSegment").to_matchable(),
                                                Ref::keyword("INCREMENT").to_matchable(),
                                                Ref::new("NumericLiteralSegment").to_matchable(),
                                            ])
                                            .to_matchable(),
                                        ])
                                        .config(|this| this.optional())
                                        .to_matchable(),
                                    ])
                                    .config(|this| this.optional())
                                    .to_matchable(),
                                ])
                                .config(|this| this.optional())
                                .to_matchable(),
                                // Masking Policy
                                Sequence::new(vec![
                                    Ref::keyword("WITH").optional().to_matchable(),
                                    Ref::keyword("MASKING").to_matchable(),
                                    Ref::keyword("POLICY").to_matchable(),
                                    Ref::new("FunctionNameSegment").to_matchable(),
                                    Sequence::new(vec![
                                        Ref::keyword("USING").to_matchable(),
                                        Bracketed::new(vec![
                                            Delimited::new(vec![
                                                one_of(vec![
                                                    Ref::new("ColumnReferenceSegment")
                                                        .to_matchable(),
                                                    Ref::new("ExpressionSegment").to_matchable(),
                                                ])
                                                .to_matchable(),
                                            ])
                                            .to_matchable(),
                                        ])
                                        .to_matchable(),
                                    ])
                                    .config(|this| this.optional())
                                    .to_matchable(),
                                ])
                                .config(|this| this.optional())
                                .to_matchable(),
                                Ref::new("CommentClauseSegment").optional().to_matchable(),
                            ])
                            .to_matchable(),
                        ])
                        .to_matchable(),
                    ])
                    .to_matchable(),
                    // Rename column
                    Sequence::new(vec![
                        Ref::keyword("RENAME").to_matchable(),
                        Ref::keyword("COLUMN").to_matchable(),
                        Ref::new("ColumnReferenceSegment").to_matchable(),
                        Ref::keyword("TO").to_matchable(),
                        Ref::new("ColumnReferenceSegment").to_matchable(),
                    ])
                    .to_matchable(),
                    // Alter/Modify column(s)
                    Sequence::new(vec![
                        one_of(vec![
                            Ref::keyword("ALTER").to_matchable(),
                            Ref::keyword("MODIFY").to_matchable(),
                        ])
                        .to_matchable(),
                        optionally_bracketed(vec![
                            Delimited::new(vec![
                                // Add things
                                Sequence::new(vec![
                                    Ref::keyword("COLUMN").optional().to_matchable(),
                                    Ref::new("ColumnReferenceSegment").to_matchable(),
                                    one_of(vec![
                                        Sequence::new(vec![
                                            Ref::keyword("DROP").to_matchable(),
                                            Ref::keyword("DEFAULT").to_matchable(),
                                        ])
                                        .to_matchable(),
                                        Sequence::new(vec![
                                            Ref::keyword("SET").to_matchable(),
                                            Ref::keyword("DEFAULT").to_matchable(),
                                            Ref::new("NakedIdentifierSegment").to_matchable(),
                                            Ref::new("DotSegment").to_matchable(),
                                            Ref::keyword("NEXTVAL").to_matchable(),
                                        ])
                                        .to_matchable(),
                                        Sequence::new(vec![
                                            one_of(vec![
                                                Ref::keyword("SET").to_matchable(),
                                                Ref::keyword("DROP").to_matchable(),
                                            ])
                                            .config(|this| this.optional())
                                            .to_matchable(),
                                            Ref::keyword("NOT").to_matchable(),
                                            Ref::keyword("NULL").to_matchable(),
                                        ])
                                        .to_matchable(),
                                        Sequence::new(vec![
                                            Sequence::new(vec![
                                                Sequence::new(vec![
                                                    Ref::keyword("SET").to_matchable(),
                                                    Ref::keyword("DATA").optional().to_matchable(),
                                                ])
                                                .to_matchable(),
                                                Ref::keyword("TYPE").optional().to_matchable(),
                                            ])
                                            .to_matchable(),
                                            Ref::new("DatatypeSegment").to_matchable(),
                                        ])
                                        .to_matchable(),
                                        Ref::new("CommentClauseSegment").to_matchable(),
                                    ])
                                    .to_matchable(),
                                ])
                                .to_matchable(),
                                Sequence::new(vec![
                                    Ref::keyword("COLUMN").to_matchable(),
                                    Ref::new("ColumnReferenceSegment").to_matchable(),
                                    Ref::keyword("SET").to_matchable(),
                                    Ref::keyword("MASKING").to_matchable(),
                                    Ref::keyword("POLICY").to_matchable(),
                                    Ref::new("FunctionNameSegment").to_matchable(),
                                    Sequence::new(vec![
                                        Ref::keyword("USING").to_matchable(),
                                        Bracketed::new(vec![
                                            Delimited::new(vec![
                                                one_of(vec![
                                                    Ref::new("ColumnReferenceSegment")
                                                        .to_matchable(),
                                                    Ref::new("ExpressionSegment").to_matchable(),
                                                ])
                                                .to_matchable(),
                                            ])
                                            .to_matchable(),
                                        ])
                                        .to_matchable(),
                                    ])
                                    .config(|this| this.optional())
                                    .to_matchable(),
                                ])
                                .to_matchable(),
                                Sequence::new(vec![
                                    Ref::keyword("COLUMN").to_matchable(),
                                    Ref::new("ColumnReferenceSegment").to_matchable(),
                                    Ref::keyword("UNSET").to_matchable(),
                                    Ref::keyword("MASKING").to_matchable(),
                                    Ref::keyword("POLICY").to_matchable(),
                                ])
                                .to_matchable(),
                                Sequence::new(vec![
                                    Ref::keyword("COLUMN").to_matchable(),
                                    Ref::new("ColumnReferenceSegment").to_matchable(),
                                    Ref::keyword("SET").to_matchable(),
                                    Ref::keyword("TAG").to_matchable(),
                                    Ref::new("TagReferenceSegment").to_matchable(),
                                    Ref::new("EqualsSegment").to_matchable(),
                                    Ref::new("QuotedLiteralSegment").to_matchable(),
                                ])
                                .to_matchable(),
                                Sequence::new(vec![
                                    Ref::keyword("COLUMN").to_matchable(),
                                    Ref::new("ColumnReferenceSegment").to_matchable(),
                                    Ref::keyword("UNSET").to_matchable(),
                                    Ref::keyword("TAG").to_matchable(),
                                    Ref::new("TagReferenceSegment").to_matchable(),
                                ])
                                .to_matchable(),
                            ])
                            .to_matchable(),
                        ])
                        .to_matchable(),
                    ])
                    .to_matchable(),
                    // Drop column
                    Sequence::new(vec![
                        Ref::keyword("DROP").to_matchable(),
                        Ref::keyword("COLUMN").optional().to_matchable(),
                        Delimited::new(vec![Ref::new("ColumnReferenceSegment").to_matchable()])
                            .to_matchable(),
                    ])
                    .to_matchable(),
                    // Add or Modify column
                    Sequence::new(vec![
                        one_of(vec![
                            Ref::keyword("ADD").to_matchable(),
                            Ref::keyword("MODIFY").to_matchable(),
                        ])
                        .to_matchable(),
                        Ref::keyword("COLUMN").optional().to_matchable(),
                        Ref::new("ColumnDefinitionSegment").to_matchable(),
                        one_of(vec![
                            Sequence::new(vec![
                                one_of(vec![
                                    Ref::keyword("FIRST").to_matchable(),
                                    Ref::keyword("AFTER").to_matchable(),
                                ])
                                .to_matchable(),
                                Ref::new("ColumnReferenceSegment").to_matchable(),
                            ])
                            .to_matchable(),
                            // Bracketed Version of the same
                            Ref::new("BracketedColumnReferenceListGrammar").to_matchable(),
                        ])
                        .config(|this| this.optional())
                        .to_matchable(),
                    ])
                    .to_matchable(),
                ])
                .to_matchable()
            })
            .to_matchable()
            .into(),
        ),
        (
            "AlterTableClusteringActionSegment".into(),
            NodeMatcher::new(SyntaxKind::AlterTableClusteringAction, |_| {
                one_of(vec![
                    Sequence::new(vec![
                        Ref::keyword("CLUSTER").to_matchable(),
                        Ref::keyword("BY").to_matchable(),
                        one_of(vec![
                            Ref::new("FunctionSegment").to_matchable(),
                            Bracketed::new(vec![
                                Delimited::new(vec![Ref::new("ExpressionSegment").to_matchable()])
                                    .to_matchable(),
                            ])
                            .to_matchable(),
                        ])
                        .to_matchable(),
                    ])
                    .to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("RECLUSTER").to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("MAX_SIZE").to_matchable(),
                            Ref::new("EqualsSegment").to_matchable(),
                            Ref::new("NumericLiteralSegment").to_matchable(),
                        ])
                        .config(|this| this.optional())
                        .to_matchable(),
                        Ref::new("WhereClauseSegment").optional().to_matchable(),
                    ])
                    .to_matchable(),
                    Sequence::new(vec![
                        one_of(vec![
                            Ref::keyword("SUSPEND").to_matchable(),
                            Ref::keyword("RESUME").to_matchable(),
                        ])
                        .to_matchable(),
                        Ref::keyword("RECLUSTER").to_matchable(),
                    ])
                    .to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("DROP").to_matchable(),
                        Ref::keyword("CLUSTERING").to_matchable(),
                        Ref::keyword("KEY").to_matchable(),
                    ])
                    .to_matchable(),
                ])
                .to_matchable()
            })
            .to_matchable()
            .into(),
        ),
        (
            "AlterTableConstraintActionSegment".into(),
            NodeMatcher::new(SyntaxKind::AlterTableConstraintAction, |_| {
                one_of(vec![
                    // Add Column
                    Sequence::new(vec![
                        Ref::keyword("ADD").to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("CONSTRAINT").to_matchable(),
                            one_of(vec![
                                Ref::new("NakedIdentifierSegment").to_matchable(),
                                Ref::new("QuotedIdentifierSegment").to_matchable(),
                            ])
                            .config(|this| this.optional())
                            .to_matchable(),
                        ])
                        .to_matchable(),
                        one_of(vec![
                            Sequence::new(vec![
                                Ref::new("PrimaryKeyGrammar").to_matchable(),
                                Bracketed::new(vec![
                                    Delimited::new(vec![
                                        Ref::new("ColumnReferenceSegment").to_matchable(),
                                    ])
                                    .to_matchable(),
                                ])
                                .to_matchable(),
                            ])
                            .to_matchable(),
                            Sequence::new(vec![
                                Sequence::new(vec![
                                    Ref::new("ForeignKeyGrammar").to_matchable(),
                                    Bracketed::new(vec![
                                        Delimited::new(vec![
                                            Ref::new("ColumnReferenceSegment").to_matchable(),
                                        ])
                                        .to_matchable(),
                                    ])
                                    .to_matchable(),
                                ])
                                .to_matchable(),
                                Ref::keyword("REFERENCES").to_matchable(),
                                Ref::new("TableReferenceSegment").to_matchable(),
                                Bracketed::new(vec![
                                    Delimited::new(vec![
                                        Ref::new("ColumnReferenceSegment").to_matchable(),
                                    ])
                                    .to_matchable(),
                                ])
                                .config(|this| this.optional())
                                .to_matchable(),
                            ])
                            .to_matchable(),
                            Sequence::new(vec![
                                Ref::keyword("UNIQUE").to_matchable(),
                                Bracketed::new(vec![
                                    Ref::new("ColumnReferenceSegment").to_matchable(),
                                ])
                                .config(|this| this.optional())
                                .to_matchable(),
                            ])
                            .to_matchable(),
                        ])
                        .to_matchable(),
                    ])
                    .to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("DROP").to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("CONSTRAINT").to_matchable(),
                            Ref::new("NakedIdentifierSegment").to_matchable(),
                        ])
                        .config(|this| this.optional())
                        .to_matchable(),
                        one_of(vec![
                            Ref::new("PrimaryKeyGrammar").to_matchable(),
                            Ref::new("ForeignKeyGrammar").to_matchable(),
                            Ref::keyword("UNIQUE").to_matchable(),
                        ])
                        .to_matchable(),
                        Delimited::new(vec![Ref::new("ColumnReferenceSegment").to_matchable()])
                            .to_matchable(),
                    ])
                    .to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("RENAME").to_matchable(),
                        Ref::keyword("CONSTRAINT").to_matchable(),
                        Ref::new("NakedIdentifierSegment").to_matchable(),
                        Ref::keyword("TO").to_matchable(),
                        Ref::new("NakedIdentifierSegment").to_matchable(),
                    ])
                    .to_matchable(),
                ])
                .to_matchable()
            })
            .to_matchable()
            .into(),
        ),
        (
            "AlterWarehouseStatementSegment".into(),
            NodeMatcher::new(SyntaxKind::AlterWarehouseStatement, |_| {
                Sequence::new(vec![
                    Ref::keyword("ALTER").to_matchable(),
                    Ref::keyword("WAREHOUSE").to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("IF").to_matchable(),
                        Ref::keyword("EXISTS").to_matchable(),
                    ])
                    .config(|this| this.optional())
                    .to_matchable(),
                    one_of(vec![
                        Sequence::new(vec![
                            Ref::new("ObjectReferenceSegment").optional().to_matchable(),
                            one_of(vec![
                                Ref::keyword("SUSPEND").to_matchable(),
                                Sequence::new(vec![
                                    Ref::keyword("RESUME").to_matchable(),
                                    Sequence::new(vec![
                                        Ref::keyword("IF").to_matchable(),
                                        Ref::keyword("SUSPENDED").to_matchable(),
                                    ])
                                    .config(|this| this.optional())
                                    .to_matchable(),
                                ])
                                .to_matchable(),
                            ])
                            .to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::new("ObjectReferenceSegment").optional().to_matchable(),
                            Sequence::new(vec![
                                Ref::keyword("ABORT").to_matchable(),
                                Ref::keyword("ALL").to_matchable(),
                                Ref::keyword("QUERIES").to_matchable(),
                            ])
                            .to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::new("ObjectReferenceSegment").to_matchable(),
                            Ref::keyword("RENAME").to_matchable(),
                            Ref::keyword("TO").to_matchable(),
                            Ref::new("ObjectReferenceSegment").to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::new("ObjectReferenceSegment").optional().to_matchable(),
                            Ref::keyword("SET").to_matchable(),
                            one_of(vec![
                                AnyNumberOf::new(vec![
                                    Ref::new("CommaSegment").optional().to_matchable(),
                                    Ref::new("WarehouseObjectPropertiesSegment").to_matchable(),
                                    Ref::new("CommentEqualsClauseSegment").to_matchable(),
                                    Ref::new("WarehouseObjectParamsSegment").to_matchable(),
                                ])
                                .to_matchable(),
                                Ref::new("TagEqualsSegment").to_matchable(),
                            ])
                            .to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::new("ObjectReferenceSegment").to_matchable(),
                            Ref::keyword("UNSET").to_matchable(),
                            one_of(vec![
                                Delimited::new(vec![
                                    Ref::new("NakedIdentifierSegment").to_matchable(),
                                ])
                                .to_matchable(),
                                Sequence::new(vec![
                                    Ref::keyword("TAG").to_matchable(),
                                    Delimited::new(vec![
                                        Ref::new("TagReferenceSegment").to_matchable(),
                                    ])
                                    .to_matchable(),
                                ])
                                .to_matchable(),
                            ])
                            .to_matchable(),
                        ])
                        .to_matchable(),
                    ])
                    .to_matchable(),
                ])
                .to_matchable()
            })
            .to_matchable()
            .into(),
        ),
        (
            "AlterShareStatementSegment".into(),
            NodeMatcher::new(SyntaxKind::AlterShareStatement, |_| {
                Sequence::new(vec![
                    Ref::keyword("ALTER").to_matchable(),
                    Ref::keyword("SHARE").to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("IF").to_matchable(),
                        Ref::keyword("EXISTS").to_matchable(),
                    ])
                    .config(|this| this.optional())
                    .to_matchable(),
                    Ref::new("NakedIdentifierSegment").to_matchable(),
                    one_of(vec![
                        Sequence::new(vec![
                            one_of(vec![
                                Ref::keyword("ADD").to_matchable(),
                                Ref::keyword("REMOVE").to_matchable(),
                            ])
                            .to_matchable(),
                            Ref::keyword("ACCOUNTS").to_matchable(),
                            Ref::new("EqualsSegment").to_matchable(),
                            Delimited::new(vec![Ref::new("NakedIdentifierSegment").to_matchable()])
                                .to_matchable(),
                            Sequence::new(vec![
                                Ref::keyword("SHARE_RESTRICTIONS").to_matchable(),
                                Ref::new("EqualsSegment").to_matchable(),
                                Ref::new("BooleanLiteralGrammar").to_matchable(),
                            ])
                            .config(|this| this.optional())
                            .to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("SET").to_matchable(),
                            Ref::keyword("ACCOUNTS").to_matchable(),
                            Ref::new("EqualsSegment").to_matchable(),
                            Delimited::new(vec![Ref::new("NakedIdentifierSegment").to_matchable()])
                                .to_matchable(),
                            Ref::new("CommentEqualsClauseSegment")
                                .optional()
                                .to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("SET").to_matchable(),
                            Ref::new("TagEqualsSegment").to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("UNSET").to_matchable(),
                            Ref::keyword("TAG").to_matchable(),
                            Ref::new("TagReferenceSegment").to_matchable(),
                            AnyNumberOf::new(vec![
                                Ref::new("CommaSegment").to_matchable(),
                                Ref::new("TagReferenceSegment").to_matchable(),
                            ])
                            .config(|this| this.optional())
                            .to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("UNSET").to_matchable(),
                            Ref::keyword("COMMENT").to_matchable(),
                        ])
                        .to_matchable(),
                    ])
                    .to_matchable(),
                ])
                .to_matchable()
            })
            .to_matchable()
            .into(),
        ),
        (
            "AlterStorageIntegrationSegment".into(),
            NodeMatcher::new(SyntaxKind::AlterStorageIntegrationStatement, |_| {
                Sequence::new(vec![
                    Ref::keyword("ALTER").to_matchable(),
                    Ref::keyword("STORAGE").optional().to_matchable(),
                    Ref::keyword("INTEGRATION").to_matchable(),
                    Ref::new("IfExistsGrammar").optional().to_matchable(),
                    Ref::new("ObjectReferenceSegment").to_matchable(),
                    one_of(vec![
                        Sequence::new(vec![
                            Ref::keyword("SET").to_matchable(),
                            one_of(vec![
                                Ref::new("TagEqualsSegment").optional().to_matchable(),
                                any_set_of(vec![
                                    Sequence::new(vec![
                                        Ref::keyword("COMMENT").to_matchable(),
                                        Ref::new("EqualsSegment").to_matchable(),
                                        Ref::new("QuotedLiteralSegment").to_matchable(),
                                    ])
                                    .to_matchable(),
                                    Sequence::new(vec![
                                        Ref::keyword("ENABLED").to_matchable(),
                                        Ref::new("EqualsSegment").to_matchable(),
                                        Ref::new("BooleanLiteralGrammar").to_matchable(),
                                    ])
                                    .to_matchable(),
                                    one_of(vec![
                                        any_set_of(vec![
                                            Sequence::new(vec![
                                                Ref::keyword("STORAGE_AWS_ROLE_ARN").to_matchable(),
                                                Ref::new("EqualsSegment").to_matchable(),
                                                Ref::new("QuotedLiteralSegment").to_matchable(),
                                            ])
                                            .to_matchable(),
                                            Sequence::new(vec![
                                                Ref::keyword("STORAGE_AWS_OBJECT_ACL")
                                                    .to_matchable(),
                                                Ref::new("EqualsSegment").to_matchable(),
                                                Ref::new("QuotedLiteralSegment").to_matchable(),
                                            ])
                                            .to_matchable(),
                                        ])
                                        .to_matchable(),
                                        any_set_of(vec![
                                            Sequence::new(vec![
                                                Ref::keyword("AZURE_TENANT_ID").to_matchable(),
                                                Ref::new("EqualsSegment").to_matchable(),
                                                Ref::new("QuotedLiteralSegment").to_matchable(),
                                            ])
                                            .to_matchable(),
                                        ])
                                        .to_matchable(),
                                    ])
                                    .to_matchable(),
                                    Sequence::new(vec![
                                        Ref::keyword("STORAGE_ALLOWED_LOCATIONS").to_matchable(),
                                        Ref::new("EqualsSegment").to_matchable(),
                                        one_of(vec![
                                            Bracketed::new(vec![
                                                Delimited::new(vec![
                                                    one_of(vec![
                                                        Ref::new("S3Path").to_matchable(),
                                                        Ref::new("GCSPath").to_matchable(),
                                                        Ref::new("AzureBlobStoragePath")
                                                            .to_matchable(),
                                                    ])
                                                    .to_matchable(),
                                                ])
                                                .to_matchable(),
                                            ])
                                            .to_matchable(),
                                            Bracketed::new(vec![
                                                Ref::new("QuotedStarSegment").to_matchable(),
                                            ])
                                            .to_matchable(),
                                        ])
                                        .to_matchable(),
                                    ])
                                    .to_matchable(),
                                    Sequence::new(vec![
                                        Ref::keyword("STORAGE_BLOCKED_LOCATIONS").to_matchable(),
                                        Ref::new("EqualsSegment").to_matchable(),
                                        Bracketed::new(vec![
                                            Delimited::new(vec![
                                                one_of(vec![
                                                    Ref::new("S3Path").to_matchable(),
                                                    Ref::new("GCSPath").to_matchable(),
                                                    Ref::new("AzureBlobStoragePath").to_matchable(),
                                                ])
                                                .to_matchable(),
                                            ])
                                            .to_matchable(),
                                        ])
                                        .to_matchable(),
                                    ])
                                    .to_matchable(),
                                ])
                                .to_matchable(),
                            ])
                            .to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("UNSET").to_matchable(),
                            one_of(vec![
                                Sequence::new(vec![
                                    Ref::keyword("TAG").to_matchable(),
                                    Delimited::new(vec![
                                        Ref::new("TagReferenceSegment").to_matchable(),
                                    ])
                                    .to_matchable(),
                                ])
                                .config(|this| this.optional())
                                .to_matchable(),
                                Ref::keyword("COMMENT").to_matchable(),
                                Ref::keyword("ENABLED").to_matchable(),
                                Ref::keyword("STORAGE_BLOCKED_LOCATIONS").to_matchable(),
                            ])
                            .to_matchable(),
                        ])
                        .to_matchable(),
                    ])
                    .to_matchable(),
                ])
                .to_matchable()
            })
            .to_matchable()
            .into(),
        ),
        (
            "AlterExternalTableStatementSegment".into(),
            NodeMatcher::new(SyntaxKind::AlterExternalTableStatement, |_| {
                Sequence::new(vec![
                    Ref::keyword("ALTER").to_matchable(),
                    Ref::keyword("EXTERNAL").to_matchable(),
                    Ref::keyword("TABLE").to_matchable(),
                    Ref::new("IfExistsGrammar").optional().to_matchable(),
                    Ref::new("TableReferenceSegment").to_matchable(),
                    one_of(vec![
                        Sequence::new(vec![
                            Ref::keyword("REFRESH").to_matchable(),
                            Ref::new("QuotedLiteralSegment").optional().to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            one_of(vec![
                                Ref::keyword("ADD").to_matchable(),
                                Ref::keyword("REMOVE").to_matchable(),
                            ])
                            .to_matchable(),
                            Ref::keyword("FILES").to_matchable(),
                            Bracketed::new(vec![
                                Delimited::new(vec![
                                    Ref::new("QuotedLiteralSegment").to_matchable(),
                                ])
                                .to_matchable(),
                            ])
                            .to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("SET").to_matchable(),
                            Sequence::new(vec![
                                Ref::keyword("AUTO_REFRESH").to_matchable(),
                                Ref::new("EqualsSegment").to_matchable(),
                                Ref::new("BooleanLiteralGrammar").to_matchable(),
                            ])
                            .config(|this| this.optional())
                            .to_matchable(),
                            Ref::new("TagEqualsSegment").optional().to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("UNSET").to_matchable(),
                            Ref::new("TagEqualsSegment").to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("DROP").to_matchable(),
                            Ref::keyword("PARTITION").to_matchable(),
                            Ref::keyword("LOCATION").to_matchable(),
                            Ref::new("QuotedLiteralSegment").to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("ADD").to_matchable(),
                            Ref::keyword("PARTITION").to_matchable(),
                            Bracketed::new(vec![
                                Delimited::new(vec![
                                    Sequence::new(vec![
                                        Ref::new("ColumnReferenceSegment").to_matchable(),
                                        Ref::new("EqualsSegment").to_matchable(),
                                        Ref::new("QuotedLiteralSegment").to_matchable(),
                                    ])
                                    .to_matchable(),
                                ])
                                .to_matchable(),
                            ])
                            .to_matchable(),
                            Ref::keyword("LOCATION").to_matchable(),
                            Ref::new("QuotedLiteralSegment").to_matchable(),
                        ])
                        .to_matchable(),
                    ])
                    .to_matchable(),
                ])
                .to_matchable()
            })
            .to_matchable()
            .into(),
        ),
        (
            "CommentEqualsClauseSegment".into(),
            NodeMatcher::new(SyntaxKind::CommentEqualsClause, |_| {
                Sequence::new(vec![
                    Ref::keyword("COMMENT").to_matchable(),
                    Ref::new("EqualsSegment").to_matchable(),
                    Ref::new("QuotedLiteralSegment").to_matchable(),
                ])
                .to_matchable()
            })
            .to_matchable()
            .into(),
        ),
        (
            "TagBracketedEqualsSegment".into(),
            NodeMatcher::new(SyntaxKind::TagBracketedEquals, |_| {
                Sequence::new(vec![
                    Sequence::new(vec![Ref::keyword("WITH").to_matchable()])
                        .config(|this| this.optional())
                        .to_matchable(),
                    Ref::keyword("TAG").to_matchable(),
                    Bracketed::new(vec![
                        Delimited::new(vec![
                            Sequence::new(vec![
                                Ref::new("TagReferenceSegment").to_matchable(),
                                Ref::new("EqualsSegment").to_matchable(),
                                Ref::new("QuotedLiteralSegment").to_matchable(),
                            ])
                            .to_matchable(),
                        ])
                        .to_matchable(),
                    ])
                    .to_matchable(),
                ])
                .to_matchable()
            })
            .to_matchable()
            .into(),
        ),
        (
            "TagEqualsSegment".into(),
            NodeMatcher::new(SyntaxKind::TagEquals, |_| {
                Sequence::new(vec![
                    Ref::keyword("TAG").to_matchable(),
                    Delimited::new(vec![
                        Sequence::new(vec![
                            Ref::new("TagReferenceSegment").to_matchable(),
                            Ref::new("EqualsSegment").to_matchable(),
                            Ref::new("QuotedLiteralSegment").to_matchable(),
                        ])
                        .to_matchable(),
                    ])
                    .to_matchable(),
                ])
                .to_matchable()
            })
            .to_matchable()
            .into(),
        ),
    ]);

    snowflake_dialect.replace_grammar(
        "UnorderedSelectStatementSegment",
        ansi::get_unordered_select_statement_segment_grammar().copy(
            Some(vec![
                Ref::new("QualifyClauseSegment").optional().to_matchable(),
            ]),
            None,
            Some(Ref::new("OverlapsClauseSegment").optional().to_matchable()),
            None,
            Vec::new(),
            false,
        ),
    );

    snowflake_dialect.add([
        (
            "AccessStatementSegment".into(),
            NodeMatcher::new(SyntaxKind::AccessStatement, |_| {
                let global_permissions = one_of(vec![
                    Sequence::new(vec![
                        Ref::keyword("CREATE").to_matchable(),
                        one_of(vec![
                            Ref::keyword("ACCOUNT").to_matchable(),
                            Ref::keyword("ROLE").to_matchable(),
                            Ref::keyword("USER").to_matchable(),
                            Ref::keyword("WAREHOUSE").to_matchable(),
                            Ref::keyword("DATABASE").to_matchable(),
                            Ref::keyword("INTEGRATION").to_matchable(),
                            Ref::keyword("SHARE").to_matchable(),
                            Sequence::new(vec![
                                Ref::keyword("DATA").to_matchable(),
                                Ref::keyword("EXCHANGE").to_matchable(),
                                Ref::keyword("LISTING").to_matchable(),
                            ])
                            .to_matchable(),
                            Sequence::new(vec![
                                Ref::keyword("NETWORK").to_matchable(),
                                Ref::keyword("POLICY").to_matchable(),
                            ])
                            .to_matchable(),
                        ])
                        .to_matchable(),
                    ])
                    .to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("APPLY").to_matchable(),
                        Ref::keyword("MASKING").to_matchable(),
                        Ref::keyword("POLICY").to_matchable(),
                    ])
                    .to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("APPLY").to_matchable(),
                        Ref::keyword("ROW").to_matchable(),
                        Ref::keyword("ACCESS").to_matchable(),
                        Ref::keyword("POLICY").to_matchable(),
                    ])
                    .to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("APPLY").to_matchable(),
                        Ref::keyword("SESSION").to_matchable(),
                        Ref::keyword("POLICY").to_matchable(),
                    ])
                    .to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("APPLY").to_matchable(),
                        Ref::keyword("TAG").to_matchable(),
                    ])
                    .to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("ATTACH").to_matchable(),
                        Ref::keyword("POLICY").to_matchable(),
                    ])
                    .to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("EXECUTE").to_matchable(),
                        Ref::keyword("TASK").to_matchable(),
                    ])
                    .to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("IMPORT").to_matchable(),
                        Ref::keyword("SHARE").to_matchable(),
                    ])
                    .to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("MANAGE").to_matchable(),
                        one_of(vec![
                            Ref::keyword("GRANTS").to_matchable(),
                            Sequence::new(vec![
                                one_of(vec![
                                    Ref::keyword("ACCOUNT").to_matchable(),
                                    Ref::keyword("ORGANIZATION").to_matchable(),
                                    Ref::keyword("USER").to_matchable(),
                                ])
                                .to_matchable(),
                                Ref::keyword("SUPPORT").to_matchable(),
                                Ref::keyword("CASES").to_matchable(),
                            ])
                            .to_matchable(),
                        ])
                        .to_matchable(),
                    ])
                    .to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("MONITOR").to_matchable(),
                        one_of(vec![
                            Ref::keyword("EXECUTION").to_matchable(),
                            Ref::keyword("USAGE").to_matchable(),
                        ])
                        .to_matchable(),
                    ])
                    .to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("OVERRIDE").to_matchable(),
                        Ref::keyword("SHARE").to_matchable(),
                        Ref::keyword("RESTRICTIONS").to_matchable(),
                    ])
                    .to_matchable(),
                ]);

                let schema_object_names = [
                    "TABLE",
                    "VIEW",
                    "STAGE",
                    "FUNCTION",
                    "PROCEDURE",
                    "ROUTINE",
                    "SEQUENCE",
                    "STREAM",
                    "TASK",
                    "PIPE",
                ];

                let schema_object_names_keywrods: Vec<Matchable> = schema_object_names
                    .iter()
                    .map(|name| Ref::keyword(*name).to_matchable())
                    .collect();

                let mut schema_object_types = schema_object_names_keywrods.clone();
                schema_object_types.append(&mut vec![
                    Sequence::new(vec![
                        Ref::keyword("MATERIALIZED").to_matchable(),
                        Ref::keyword("VIEW").to_matchable(),
                    ])
                    .to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("EXTERNAL").to_matchable(),
                        Ref::keyword("TABLE").to_matchable(),
                    ])
                    .to_matchable(),
                    Sequence::new(vec![
                        one_of(vec![
                            Ref::keyword("TEMP").to_matchable(),
                            Ref::keyword("TEMPORARY").to_matchable(),
                        ])
                        .to_matchable(),
                        Ref::keyword("TABLE").to_matchable(),
                    ])
                    .to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("FILE").to_matchable(),
                        Ref::keyword("FORMAT").to_matchable(),
                    ])
                    .to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("SESSION").to_matchable(),
                        Ref::keyword("POLICY").to_matchable(),
                    ])
                    .to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("MASKING").to_matchable(),
                        Ref::keyword("POLICY").to_matchable(),
                    ])
                    .to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("ROW").to_matchable(),
                        Ref::keyword("ACCESS").to_matchable(),
                        Ref::keyword("POLICY").to_matchable(),
                    ])
                    .to_matchable(),
                ]);

                let schema_object_types = one_of(schema_object_types);

                let schema_object_types_plural = one_of(
                    schema_object_names
                        .iter()
                        .map(|name| Ref::keyword(format!("{name}S")).to_matchable())
                        .collect(),
                );

                let permissions = Sequence::new(vec![
                    one_of(vec![
                        Sequence::new(vec![
                            Ref::keyword("CREATE").to_matchable(),
                            one_of(vec![
                                Ref::keyword("SCHEMA").to_matchable(),
                                schema_object_types.clone().to_matchable(),
                            ])
                            .to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("IMPORTED").to_matchable(),
                            Ref::keyword("PRIVILEGES").to_matchable(),
                        ])
                        .to_matchable(),
                        Ref::keyword("APPLY").to_matchable(),
                        Ref::keyword("CONNECT").to_matchable(),
                        Ref::keyword("CREATE").to_matchable(),
                        Ref::keyword("DELETE").to_matchable(),
                        Ref::keyword("EXECUTE").to_matchable(),
                        Ref::keyword("INSERT").to_matchable(),
                        Ref::keyword("MODIFY").to_matchable(),
                        Ref::keyword("MONITOR").to_matchable(),
                        Ref::keyword("OPERATE").to_matchable(),
                        Ref::keyword("OWNERSHIP").to_matchable(),
                        Ref::keyword("READ").to_matchable(),
                        Ref::keyword("REFERENCE_USAGE").to_matchable(),
                        Ref::keyword("REFERENCES").to_matchable(),
                        Ref::keyword("SELECT").to_matchable(),
                        Ref::keyword("TEMP").to_matchable(),
                        Ref::keyword("TEMPORARY").to_matchable(),
                        Ref::keyword("TRIGGER").to_matchable(),
                        Ref::keyword("TRUNCATE").to_matchable(),
                        Ref::keyword("UPDATE").to_matchable(),
                        Ref::keyword("USAGE").to_matchable(),
                        Ref::keyword("USE_ANY_ROLE").to_matchable(),
                        Ref::keyword("WRITE").to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("ALL").to_matchable(),
                            Ref::keyword("PRIVILEGES").optional().to_matchable(),
                        ])
                        .to_matchable(),
                    ])
                    .to_matchable(),
                    Ref::new("BracketedColumnReferenceListGrammar")
                        .optional()
                        .to_matchable(),
                ]);

                let objects = one_of(vec![
                    Ref::keyword("ACCOUNT").to_matchable(),
                    Sequence::new(vec![
                        one_of(vec![
                            Sequence::new(vec![
                                Ref::keyword("RESOURCE").to_matchable(),
                                Ref::keyword("MONITOR").to_matchable(),
                            ])
                            .to_matchable(),
                            Ref::keyword("WAREHOUSE").to_matchable(),
                            Ref::keyword("DATABASE").to_matchable(),
                            Ref::keyword("DOMAIN").to_matchable(),
                            Ref::keyword("INTEGRATION").to_matchable(),
                            Ref::keyword("SCHEMA").to_matchable(),
                            Ref::keyword("ROLE").to_matchable(),
                            Sequence::new(vec![
                                Ref::keyword("ALL").to_matchable(),
                                Ref::keyword("SCHEMAS").to_matchable(),
                                Ref::keyword("IN").to_matchable(),
                                Ref::keyword("DATABASE").to_matchable(),
                            ])
                            .to_matchable(),
                            Sequence::new(vec![
                                Ref::keyword("FUTURE").to_matchable(),
                                Ref::keyword("SCHEMAS").to_matchable(),
                                Ref::keyword("IN").to_matchable(),
                                Ref::keyword("DATABASE").to_matchable(),
                            ])
                            .to_matchable(),
                            schema_object_types.clone().to_matchable(),
                            Sequence::new(vec![
                                Ref::keyword("ALL").to_matchable(),
                                one_of(vec![
                                    schema_object_types_plural.clone().to_matchable(),
                                    Sequence::new(vec![
                                        Ref::keyword("MATERIALIZED").to_matchable(),
                                        Ref::keyword("VIEWS").to_matchable(),
                                    ])
                                    .to_matchable(),
                                    Sequence::new(vec![
                                        Ref::keyword("EXTERNAL").to_matchable(),
                                        Ref::keyword("TABLES").to_matchable(),
                                    ])
                                    .to_matchable(),
                                    Sequence::new(vec![
                                        Ref::keyword("FILE").to_matchable(),
                                        Ref::keyword("FORMATS").to_matchable(),
                                    ])
                                    .to_matchable(),
                                ])
                                .to_matchable(),
                                Ref::keyword("IN").to_matchable(),
                                one_of(vec![
                                    Ref::keyword("SCHEMA").to_matchable(),
                                    Ref::keyword("DATABASE").to_matchable(),
                                ])
                                .to_matchable(),
                            ])
                            .to_matchable(),
                            Sequence::new(vec![
                                Ref::keyword("FUTURE").to_matchable(),
                                one_of(vec![
                                    schema_object_types_plural.clone().to_matchable(),
                                    Sequence::new(vec![
                                        Ref::keyword("MATERIALIZED").to_matchable(),
                                        Ref::keyword("VIEWS").to_matchable(),
                                    ])
                                    .to_matchable(),
                                    Sequence::new(vec![
                                        Ref::keyword("EXTERNAL").to_matchable(),
                                        Ref::keyword("TABLES").to_matchable(),
                                    ])
                                    .to_matchable(),
                                    Sequence::new(vec![
                                        Ref::keyword("FILE").to_matchable(),
                                        Ref::keyword("FORMATS").to_matchable(),
                                    ])
                                    .to_matchable(),
                                ])
                                .to_matchable(),
                                Ref::keyword("IN").to_matchable(),
                                one_of(vec![
                                    Ref::keyword("DATABASE").to_matchable(),
                                    Ref::keyword("SCHEMA").to_matchable(),
                                ])
                                .to_matchable(),
                            ])
                            .to_matchable(),
                        ])
                        .config(|this| this.optional())
                        .to_matchable(),
                        Delimited::new(vec![
                            Ref::new("ObjectReferenceSegment").to_matchable(),
                            Sequence::new(vec![
                                Ref::new("FunctionNameSegment").to_matchable(),
                                Ref::new("FunctionParameterListGrammar")
                                    .optional()
                                    .to_matchable(),
                            ])
                            .to_matchable(),
                        ])
                        .config(|this| {
                            this.terminators = vec![
                                Ref::keyword("TO").to_matchable(),
                                Ref::keyword("FROM").to_matchable(),
                            ]
                        })
                        .to_matchable(),
                    ])
                    .to_matchable(),
                ]);

                one_of(vec![
                    // Grant statement
                    Sequence::new(vec![
                        Ref::keyword("GRANT").to_matchable(),
                        one_of(vec![
                            Sequence::new(vec![
                                Delimited::new(vec![
                                    one_of(vec![
                                        global_permissions.clone().to_matchable(),
                                        permissions.clone().to_matchable(),
                                    ])
                                    .to_matchable(),
                                ])
                                .config(|this| {
                                    this.terminators = vec![Ref::keyword("ON").to_matchable()]
                                })
                                .to_matchable(),
                                Ref::keyword("ON").to_matchable(),
                                objects.clone().to_matchable(),
                            ])
                            .to_matchable(),
                            Sequence::new(vec![
                                Ref::keyword("ROLE").to_matchable(),
                                Ref::new("ObjectReferenceSegment").to_matchable(),
                            ])
                            .to_matchable(),
                            Sequence::new(vec![
                                Ref::keyword("OWNERSHIP").to_matchable(),
                                Ref::keyword("ON").to_matchable(),
                                Ref::keyword("USER").to_matchable(),
                                Ref::new("ObjectReferenceSegment").to_matchable(),
                            ])
                            .to_matchable(),
                            Sequence::new(vec![
                                Ref::keyword("ADD").to_matchable(),
                                Ref::keyword("SEARCH").to_matchable(),
                                Ref::keyword("OPTIMIZATION").to_matchable(),
                                Ref::keyword("ON").to_matchable(),
                                Ref::keyword("SCHEMA").to_matchable(),
                                Ref::new("SchemaReferenceSegment").to_matchable(),
                            ])
                            .to_matchable(),
                            Ref::new("ObjectReferenceSegment").to_matchable(),
                        ])
                        .to_matchable(),
                        Ref::keyword("TO").to_matchable(),
                        Ref::keyword("USER").optional().to_matchable(),
                        Ref::keyword("ROLE").optional().to_matchable(),
                        Ref::keyword("SHARE").optional().to_matchable(),
                        Delimited::new(vec![
                            one_of(vec![
                                Ref::new("RoleReferenceSegment").to_matchable(),
                                Ref::new("FunctionSegment").to_matchable(),
                                Ref::keyword("PUBLIC").to_matchable(),
                            ])
                            .to_matchable(),
                        ])
                        .to_matchable(),
                        one_of(vec![
                            Sequence::new(vec![
                                Ref::keyword("WITH").to_matchable(),
                                Ref::keyword("GRANT").to_matchable(),
                                Ref::keyword("OPTION").to_matchable(),
                            ])
                            .to_matchable(),
                            Sequence::new(vec![
                                Ref::keyword("WITH").to_matchable(),
                                Ref::keyword("ADMIN").to_matchable(),
                                Ref::keyword("OPTION").to_matchable(),
                            ])
                            .to_matchable(),
                            Sequence::new(vec![
                                one_of(vec![
                                    Ref::keyword("REVOKE").to_matchable(),
                                    Ref::keyword("COPY").to_matchable(),
                                ])
                                .to_matchable(),
                                Ref::keyword("CURRENT").to_matchable(),
                                Ref::keyword("GRANTS").to_matchable(),
                            ])
                            .config(|this| this.optional())
                            .to_matchable(),
                        ])
                        .config(|this| this.optional())
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("GRANTED").to_matchable(),
                            Ref::keyword("BY").to_matchable(),
                            one_of(vec![
                                Ref::keyword("CURRENT_USER").to_matchable(),
                                Ref::keyword("SESSION_USER").to_matchable(),
                                Ref::new("ObjectReferenceSegment").to_matchable(),
                            ])
                            .config(|this| this.optional())
                            .to_matchable(),
                        ])
                        .config(|this| this.optional())
                        .to_matchable(),
                    ])
                    .to_matchable(),
                    // Revoke statement
                    Sequence::new(vec![
                        Ref::keyword("REVOKE").to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("GRANT").to_matchable(),
                            Ref::keyword("OPTION").to_matchable(),
                            Ref::keyword("FOR").to_matchable(),
                        ])
                        .config(|this| this.optional())
                        .to_matchable(),
                        one_of(vec![
                            Sequence::new(vec![
                                Delimited::new(vec![
                                    one_of(vec![
                                        global_permissions.clone().to_matchable(),
                                        permissions.clone().to_matchable(),
                                    ])
                                    .to_matchable(),
                                ])
                                .config(|this| {
                                    this.terminators = vec![Ref::keyword("ON").to_matchable()];
                                })
                                .to_matchable(),
                                Ref::keyword("ON").to_matchable(),
                                objects.clone().to_matchable(),
                            ])
                            .to_matchable(),
                            Sequence::new(vec![
                                Ref::keyword("ROLE").to_matchable(),
                                Ref::new("ObjectReferenceSegment").to_matchable(),
                            ])
                            .to_matchable(),
                            Sequence::new(vec![
                                Ref::keyword("OWNERSHIP").to_matchable(),
                                Ref::keyword("ON").to_matchable(),
                                Ref::keyword("USER").to_matchable(),
                                Ref::new("ObjectReferenceSegment").to_matchable(),
                            ])
                            .to_matchable(),
                            Sequence::new(vec![
                                Ref::keyword("ADD").to_matchable(),
                                Ref::keyword("SEARCH").to_matchable(),
                                Ref::keyword("OPTIMIZATION").to_matchable(),
                                Ref::keyword("ON").to_matchable(),
                                Ref::keyword("SCHEMA").to_matchable(),
                                Ref::new("SchemaReferenceSegment").to_matchable(),
                            ])
                            .to_matchable(),
                        ])
                        .to_matchable(),
                        Ref::keyword("FROM").to_matchable(),
                        Ref::keyword("USER").optional().to_matchable(),
                        Ref::keyword("ROLE").optional().to_matchable(),
                        Ref::keyword("SHARE").optional().to_matchable(),
                        Delimited::new(vec![Ref::new("ObjectReferenceSegment").to_matchable()])
                            .to_matchable(),
                        Ref::new("DropBehaviorGrammar").optional().to_matchable(),
                    ])
                    .to_matchable(),
                ])
                .to_matchable()
            })
            .to_matchable()
            .into(),
        ),
        (
            "CreateCloneStatementSegment".into(),
            NodeMatcher::new(SyntaxKind::CreateCloneStatement, |_| {
                Sequence::new(vec![
                    Ref::keyword("CREATE").to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("OR").to_matchable(),
                        Ref::keyword("REPLACE").to_matchable(),
                    ])
                    .config(|this| this.optional())
                    .to_matchable(),
                    one_of(vec![
                        Ref::keyword("DATABASE").to_matchable(),
                        Ref::keyword("SCHEMA").to_matchable(),
                        Ref::keyword("TABLE").to_matchable(),
                        Ref::keyword("SEQUENCE").to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("FILE").to_matchable(),
                            Ref::keyword("FORMAT").to_matchable(),
                        ])
                        .to_matchable(),
                        Ref::keyword("STAGE").to_matchable(),
                        Ref::keyword("STREAM").to_matchable(),
                        Ref::keyword("TASK").to_matchable(),
                    ])
                    .to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("IF").to_matchable(),
                        Ref::keyword("NOT").to_matchable(),
                        Ref::keyword("EXISTS").to_matchable(),
                    ])
                    .config(|this| this.optional())
                    .to_matchable(),
                    Ref::new("ObjectReferenceSegment").to_matchable(),
                    Ref::keyword("CLONE").to_matchable(),
                    Ref::new("ObjectReferenceSegment").to_matchable(),
                    one_of(vec![
                        Ref::new("FromAtExpressionSegment").to_matchable(),
                        Ref::new("FromBeforeExpressionSegment").to_matchable(),
                    ])
                    .config(|this| this.optional())
                    .to_matchable(),
                ])
                .to_matchable()
            })
            .to_matchable()
            .into(),
        ),
        (
            "CreateDatabaseFromShareStatementSegment".into(),
            NodeMatcher::new(SyntaxKind::CreateDatabaseFromShareStatement, |_| {
                Sequence::new(vec![
                    Ref::keyword("CREATE").to_matchable(),
                    Ref::keyword("DATABASE").to_matchable(),
                    Ref::new("ObjectReferenceSegment").to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("FROM").to_matchable(),
                        Ref::keyword("SHARE").to_matchable(),
                    ])
                    .to_matchable(),
                    Ref::new("ObjectReferenceSegment").to_matchable(),
                ])
                .to_matchable()
            })
            .to_matchable()
            .into(),
        ),
        (
            "CreateProcedureStatementSegment".into(),
            NodeMatcher::new(SyntaxKind::CreateProcedureStatement, |_| {
                Sequence::new(vec![
                    Ref::keyword("CREATE").to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("OR").to_matchable(),
                        Ref::keyword("REPLACE").to_matchable(),
                    ])
                    .config(|this| this.optional())
                    .to_matchable(),
                    Sequence::new(vec![Ref::keyword("SECURE").to_matchable()])
                        .config(|this| this.optional())
                        .to_matchable(),
                    Ref::keyword("PROCEDURE").to_matchable(),
                    Ref::new("FunctionNameSegment").to_matchable(),
                    Ref::new("FunctionParameterListGrammar").to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("COPY").to_matchable(),
                        Ref::keyword("GRANTS").to_matchable(),
                    ])
                    .config(|this| this.optional())
                    .to_matchable(),
                    Ref::keyword("RETURNS").to_matchable(),
                    one_of(vec![
                        Ref::new("DatatypeSegment").to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("TABLE").to_matchable(),
                            Bracketed::new(vec![
                                Delimited::new(vec![
                                    Ref::new("ColumnDefinitionSegment").to_matchable(),
                                ])
                                .config(|this| this.optional())
                                .to_matchable(),
                            ])
                            .to_matchable(),
                        ])
                        .to_matchable(),
                    ])
                    .to_matchable(),
                    any_set_of(vec![
                        Sequence::new(vec![
                            Ref::keyword("NOT").to_matchable(),
                            Ref::keyword("NULL").to_matchable(),
                        ])
                        .config(|this| this.optional())
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("LANGUAGE").to_matchable(),
                            one_of(vec![
                                Ref::keyword("JAVA").to_matchable(),
                                Ref::keyword("JAVASCRIPT").to_matchable(),
                                Ref::keyword("PYTHON").to_matchable(),
                                Ref::keyword("SCALA").to_matchable(),
                                Ref::keyword("SQL").to_matchable(),
                            ])
                            .config(|this| this.optional())
                            .to_matchable(),
                        ])
                        .to_matchable(),
                        one_of(vec![
                            Sequence::new(vec![
                                Ref::keyword("CALLED").to_matchable(),
                                Ref::keyword("ON").to_matchable(),
                                Ref::keyword("NULL").to_matchable(),
                                Ref::keyword("INPUT").to_matchable(),
                            ])
                            .to_matchable(),
                            Sequence::new(vec![
                                Ref::keyword("RETURNS").to_matchable(),
                                Ref::keyword("NULL").to_matchable(),
                                Ref::keyword("ON").to_matchable(),
                                Ref::keyword("NULL").to_matchable(),
                                Ref::keyword("INPUT").to_matchable(),
                            ])
                            .to_matchable(),
                            Ref::keyword("STRICT").to_matchable(),
                        ])
                        .config(|this| this.optional())
                        .to_matchable(),
                        one_of(vec![
                            Ref::keyword("VOLATILE").to_matchable(),
                            Ref::keyword("IMMUTABLE").to_matchable(),
                        ])
                        .config(|this| this.optional())
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("RUNTIME_VERSION").to_matchable(),
                            Ref::new("EqualsSegment").to_matchable(),
                            Ref::new("QuotedLiteralSegment").to_matchable(),
                        ])
                        .config(|this| this.optional())
                        .to_matchable(),
                        Ref::new("CommentEqualsClauseSegment")
                            .optional()
                            .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("IMPORTS").to_matchable(),
                            Ref::new("EqualsSegment").to_matchable(),
                            Bracketed::new(vec![
                                Delimited::new(vec![
                                    Ref::new("QuotedLiteralSegment").to_matchable(),
                                ])
                                .to_matchable(),
                            ])
                            .to_matchable(),
                        ])
                        .config(|this| this.optional())
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("PACKAGES").to_matchable(),
                            Ref::new("EqualsSegment").to_matchable(),
                            Bracketed::new(vec![
                                Delimited::new(vec![
                                    Ref::new("QuotedLiteralSegment").to_matchable(),
                                ])
                                .to_matchable(),
                            ])
                            .to_matchable(),
                        ])
                        .config(|this| this.optional())
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("HANDLER").to_matchable(),
                            Ref::new("EqualsSegment").to_matchable(),
                            Ref::new("QuotedLiteralSegment").to_matchable(),
                        ])
                        .config(|this| this.optional())
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("TARGET_PATH").to_matchable(),
                            Ref::new("EqualsSegment").to_matchable(),
                            Ref::new("QuotedLiteralSegment").to_matchable(),
                        ])
                        .config(|this| this.optional())
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("EXECUTE").to_matchable(),
                            Ref::keyword("AS").to_matchable(),
                            one_of(vec![
                                Ref::keyword("CALLER").to_matchable(),
                                Ref::keyword("OWNER").to_matchable(),
                            ])
                            .to_matchable(),
                        ])
                        .config(|this| this.optional())
                        .to_matchable(),
                    ])
                    .config(|this| this.optional())
                    .to_matchable(),
                    Ref::keyword("AS").to_matchable(),
                    one_of(vec![
                        Ref::new("DoubleQuotedUDFBody").to_matchable(),
                        Ref::new("SingleQuotedUDFBody").to_matchable(),
                        Ref::new("DollarQuotedUDFBody").to_matchable(),
                        Ref::new("ScriptingBlockStatementSegment").to_matchable(),
                    ])
                    .to_matchable(),
                ])
                .to_matchable()
            })
            .to_matchable()
            .into(),
        ),
        (
            "AlterProcedureStatementSegment".into(),
            NodeMatcher::new(SyntaxKind::AlterProcedureStatement, |_| {
                Sequence::new(vec![
                    Ref::keyword("ALTER").to_matchable(),
                    Ref::keyword("PROCEDURE").to_matchable(),
                    Ref::new("IfExistsGrammar").optional().to_matchable(),
                    Ref::new("FunctionNameSegment").to_matchable(),
                    Ref::new("FunctionParameterListGrammar").to_matchable(),
                    one_of(vec![
                        Sequence::new(vec![
                            Ref::keyword("RENAME").to_matchable(),
                            Ref::keyword("TO").to_matchable(),
                            Ref::new("FunctionNameSegment").to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("EXECUTE").to_matchable(),
                            Ref::keyword("AS").to_matchable(),
                            one_of(vec![
                                Ref::keyword("CALLER").to_matchable(),
                                Ref::keyword("OWNER").to_matchable(),
                            ])
                            .to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("SET").to_matchable(),
                            one_of(vec![
                                Ref::new("TagEqualsSegment").to_matchable(),
                                Ref::new("CommentEqualsClauseSegment").to_matchable(),
                            ])
                            .to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("UNSET").to_matchable(),
                            one_of(vec![
                                Sequence::new(vec![
                                    Ref::keyword("TAG").to_matchable(),
                                    Delimited::new(vec![
                                        Ref::new("TagReferenceSegment").to_matchable(),
                                    ])
                                    .to_matchable(),
                                ])
                                .to_matchable(),
                                Ref::keyword("COMMENT").to_matchable(),
                            ])
                            .to_matchable(),
                        ])
                        .to_matchable(),
                    ])
                    .to_matchable(),
                ])
                .to_matchable()
            })
            .to_matchable()
            .into(),
        ),
        (
            "ReturnStatementSegment".into(),
            NodeMatcher::new(SyntaxKind::ReturnStatement, |_| {
                Sequence::new(vec![
                    Ref::keyword("RETURN").to_matchable(),
                    Ref::new("ExpressionSegment").to_matchable(),
                ])
                .to_matchable()
            })
            .to_matchable()
            .into(),
        ),
        (
            "ScriptingBlockStatementSegment".into(),
            NodeMatcher::new(SyntaxKind::ScriptingBlockStatement, |_| {
                one_of(vec![
                    Sequence::new(vec![
                        Ref::keyword("BEGIN").to_matchable(),
                        Delimited::new(vec![Ref::new("StatementSegment").to_matchable()])
                            .to_matchable(),
                    ])
                    .to_matchable(),
                    Sequence::new(vec![Ref::keyword("END").to_matchable()]).to_matchable(),
                ])
                .to_matchable()
            })
            .to_matchable()
            .into(),
        ),
        (
            "ScriptingLetStatementSegment".into(),
            NodeMatcher::new(SyntaxKind::ScriptingLetStatement, |_| {
                one_of(vec![
                    // Initial declaration and assignment
                    Sequence::new(vec![
                        Ref::keyword("LET").to_matchable(),
                        Ref::new("LocalVariableNameSegment").to_matchable(),
                        one_of(vec![
                            // Variable assignment
                            one_of(vec![
                                Sequence::new(vec![
                                    Ref::new("DatatypeSegment").to_matchable(),
                                    one_of(vec![
                                        Ref::keyword("DEFAULT").to_matchable(),
                                        Ref::new("WalrusOperatorSegment").to_matchable(),
                                    ])
                                    .to_matchable(),
                                    Ref::new("ExpressionSegment").to_matchable(),
                                ])
                                .to_matchable(),
                                Sequence::new(vec![
                                    one_of(vec![
                                        Ref::keyword("DEFAULT").to_matchable(),
                                        Ref::new("WalrusOperatorSegment").to_matchable(),
                                    ])
                                    .to_matchable(),
                                    Ref::new("ExpressionSegment").to_matchable(),
                                ])
                                .to_matchable(),
                            ])
                            .to_matchable(),
                            // Cursor assignment
                            Sequence::new(vec![
                                Ref::keyword("CURSOR").to_matchable(),
                                Ref::keyword("FOR").to_matchable(),
                                one_of(vec![
                                    Ref::new("LocalVariableNameSegment").to_matchable(),
                                    Ref::new("SelectableGrammar").to_matchable(),
                                ])
                                .to_matchable(),
                            ])
                            .to_matchable(),
                            // Resultset assignment
                            Sequence::new(vec![
                                Ref::keyword("RESULTSET").to_matchable(),
                                Ref::new("WalrusOperatorSegment").to_matchable(),
                                Bracketed::new(vec![Ref::new("SelectableGrammar").to_matchable()])
                                    .to_matchable(),
                            ])
                            .to_matchable(),
                        ])
                        .to_matchable(),
                    ])
                    .to_matchable(),
                    // Subsequent assignment
                    Sequence::new(vec![
                        Ref::new("LocalVariableNameSegment").to_matchable(),
                        Ref::new("WalrusOperatorSegment").to_matchable(),
                        one_of(vec![
                            // Variable reassignment
                            Ref::new("ExpressionSegment").to_matchable(),
                            // Resultset reassignment
                            Bracketed::new(vec![Ref::new("SelectableGrammar").to_matchable()])
                                .to_matchable(),
                        ])
                        .to_matchable(),
                    ])
                    .to_matchable(),
                ])
                .to_matchable()
            })
            .to_matchable()
            .into(),
        ),
        (
            "CreateFunctionStatementSegment".into(),
            NodeMatcher::new(SyntaxKind::CreateFunctionStatement, |_| {
                Sequence::new(vec![
                    Ref::keyword("CREATE").to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("OR").to_matchable(),
                        Ref::keyword("REPLACE").to_matchable(),
                    ])
                    .config(|this| this.optional())
                    .to_matchable(),
                    Sequence::new(vec![Ref::keyword("SECURE").to_matchable()])
                        .config(|this| this.optional())
                        .to_matchable(),
                    Ref::keyword("FUNCTION").to_matchable(),
                    Ref::new("IfNotExistsGrammar").optional().to_matchable(),
                    Ref::new("FunctionNameSegment").to_matchable(),
                    Ref::new("FunctionParameterListGrammar").to_matchable(),
                    Ref::keyword("RETURNS").to_matchable(),
                    one_of(vec![
                        Ref::new("DatatypeSegment").to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("TABLE").to_matchable(),
                            Bracketed::new(vec![
                                Delimited::new(vec![
                                    Ref::new("ColumnDefinitionSegment").to_matchable(),
                                ])
                                .to_matchable(),
                            ])
                            .to_matchable(),
                        ])
                        .to_matchable(),
                    ])
                    .to_matchable(),
                    any_set_of(vec![
                        Sequence::new(vec![
                            Ref::keyword("NOT").to_matchable(),
                            Ref::keyword("NULL").to_matchable(),
                        ])
                        .config(|this| this.optional())
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("LANGUAGE").to_matchable(),
                            one_of(vec![
                                Ref::keyword("JAVASCRIPT").to_matchable(),
                                Ref::keyword("SQL").to_matchable(),
                                Ref::keyword("PYTHON").to_matchable(),
                                Ref::keyword("JAVA").to_matchable(),
                                Ref::keyword("SCALA").to_matchable(),
                            ])
                            .config(|this| this.optional())
                            .to_matchable(),
                        ])
                        .to_matchable(),
                        one_of(vec![
                            Sequence::new(vec![
                                Ref::keyword("CALLED").to_matchable(),
                                Ref::keyword("ON").to_matchable(),
                                Ref::keyword("NULL").to_matchable(),
                                Ref::keyword("INPUT").to_matchable(),
                            ])
                            .to_matchable(),
                            Sequence::new(vec![
                                Ref::keyword("RETURNS").to_matchable(),
                                Ref::keyword("NULL").to_matchable(),
                                Ref::keyword("ON").to_matchable(),
                                Ref::keyword("NULL").to_matchable(),
                                Ref::keyword("INPUT").to_matchable(),
                            ])
                            .to_matchable(),
                            Ref::keyword("STRICT").to_matchable(),
                        ])
                        .config(|this| this.optional())
                        .to_matchable(),
                        one_of(vec![
                            Ref::keyword("VOLATILE").to_matchable(),
                            Ref::keyword("IMMUTABLE").to_matchable(),
                        ])
                        .config(|this| this.optional())
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("RUNTIME_VERSION").to_matchable(),
                            Ref::new("EqualsSegment").to_matchable(),
                            Ref::new("QuotedLiteralSegment").to_matchable(),
                        ])
                        .config(|this| this.optional())
                        .to_matchable(),
                        Ref::new("CommentEqualsClauseSegment")
                            .optional()
                            .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("IMPORTS").to_matchable(),
                            Ref::new("EqualsSegment").to_matchable(),
                            Bracketed::new(vec![
                                Delimited::new(vec![
                                    Ref::new("QuotedLiteralSegment").to_matchable(),
                                ])
                                .to_matchable(),
                            ])
                            .to_matchable(),
                        ])
                        .config(|this| this.optional())
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("PACKAGES").to_matchable(),
                            Ref::new("EqualsSegment").to_matchable(),
                            Bracketed::new(vec![
                                Delimited::new(vec![
                                    Ref::new("QuotedLiteralSegment").to_matchable(),
                                ])
                                .to_matchable(),
                            ])
                            .to_matchable(),
                        ])
                        .config(|this| this.optional())
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("HANDLER").to_matchable(),
                            Ref::new("EqualsSegment").to_matchable(),
                            Ref::new("QuotedLiteralSegment").to_matchable(),
                        ])
                        .config(|this| this.optional())
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("TARGET_PATH").to_matchable(),
                            Ref::new("EqualsSegment").to_matchable(),
                            Ref::new("QuotedLiteralSegment").to_matchable(),
                        ])
                        .config(|this| this.optional())
                        .to_matchable(),
                    ])
                    .config(|this| this.optional())
                    .to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("AS").to_matchable(),
                        one_of(vec![
                            // Either a foreign programming language UDF...
                            Ref::new("DoubleQuotedUDFBody").to_matchable(),
                            Ref::new("SingleQuotedUDFBody").to_matchable(),
                            Ref::new("DollarQuotedUDFBody").to_matchable(),
                            // ...or a SQL UDF
                            Ref::new("ScriptingBlockStatementSegment").to_matchable(),
                        ])
                        .to_matchable(),
                    ])
                    .config(|this| this.optional())
                    .to_matchable(),
                ])
                .to_matchable()
            })
            .to_matchable()
            .into(),
        ),
        (
            "AlterFunctionStatementSegment".into(),
            NodeMatcher::new(SyntaxKind::AlterFunctionStatement, |_| {
                Sequence::new(vec![
                    Ref::keyword("ALTER").to_matchable(),
                    Ref::keyword("FUNCTION").to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("IF").to_matchable(),
                        Ref::keyword("EXISTS").to_matchable(),
                    ])
                    .config(|this| this.optional())
                    .to_matchable(),
                    Ref::new("FunctionNameSegment").to_matchable(),
                    Ref::new("FunctionParameterListGrammar").to_matchable(),
                    one_of(vec![
                        Sequence::new(vec![
                            Ref::keyword("RENAME").to_matchable(),
                            Ref::keyword("TO").to_matchable(),
                            Ref::new("FunctionNameSegment").to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("SET").to_matchable(),
                            one_of(vec![
                                Ref::new("CommentEqualsClauseSegment").to_matchable(),
                                Sequence::new(vec![
                                    Ref::keyword("API_INTEGRATION").to_matchable(),
                                    Ref::new("EqualsSegment").to_matchable(),
                                    Ref::new("SingleIdentifierGrammar").to_matchable(),
                                ])
                                .to_matchable(),
                                Sequence::new(vec![
                                    Ref::keyword("HEADERS").to_matchable(),
                                    Ref::new("EqualsSegment").to_matchable(),
                                    Bracketed::new(vec![
                                        Delimited::new(vec![
                                            Sequence::new(vec![
                                                Ref::new("SingleQuotedIdentifierSegment")
                                                    .to_matchable(),
                                                Ref::new("EqualsSegment").to_matchable(),
                                                Ref::new("SingleQuotedIdentifierSegment")
                                                    .to_matchable(),
                                            ])
                                            .to_matchable(),
                                        ])
                                        .to_matchable(),
                                    ])
                                    .to_matchable(),
                                ])
                                .to_matchable(),
                                Sequence::new(vec![
                                    Ref::keyword("CONTEXT_HEADERS").to_matchable(),
                                    Ref::new("EqualsSegment").to_matchable(),
                                    Bracketed::new(vec![
                                        Delimited::new(vec![
                                            Ref::new("ContextHeadersGrammar").to_matchable(),
                                        ])
                                        .to_matchable(),
                                    ])
                                    .to_matchable(),
                                ])
                                .to_matchable(),
                                Sequence::new(vec![
                                    Ref::keyword("MAX_BATCH_ROWS").to_matchable(),
                                    Ref::new("EqualsSegment").to_matchable(),
                                    Ref::new("NumericLiteralSegment").to_matchable(),
                                ])
                                .to_matchable(),
                                Sequence::new(vec![
                                    Ref::keyword("COMPRESSION").to_matchable(),
                                    Ref::new("EqualsSegment").to_matchable(),
                                    Ref::new("CompressionType").to_matchable(),
                                ])
                                .to_matchable(),
                                Ref::keyword("SECURE").to_matchable(),
                                Sequence::new(vec![
                                    one_of(vec![
                                        Ref::keyword("REQUEST_TRANSLATOR").to_matchable(),
                                        Ref::keyword("RESPONSE_TRANSLATOR").to_matchable(),
                                    ])
                                    .to_matchable(),
                                    Ref::new("EqualsSegment").to_matchable(),
                                    Ref::new("FunctionNameSegment").to_matchable(),
                                ])
                                .to_matchable(),
                            ])
                            .to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("UNSET").to_matchable(),
                            one_of(vec![
                                Ref::keyword("COMMENT").to_matchable(),
                                Ref::keyword("HEADERS").to_matchable(),
                                Ref::keyword("CONTEXT_HEADERS").to_matchable(),
                                Ref::keyword("MAX_BATCH_ROWS").to_matchable(),
                                Ref::keyword("COMPRESSION").to_matchable(),
                                Ref::keyword("SECURE").to_matchable(),
                                Ref::keyword("REQUEST_TRANSLATOR").to_matchable(),
                                Ref::keyword("RESPONSE_TRANSLATOR").to_matchable(),
                            ])
                            .to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("RENAME").to_matchable(),
                            Ref::keyword("TO").to_matchable(),
                            Ref::new("SingleIdentifierGrammar").to_matchable(),
                        ])
                        .to_matchable(),
                    ])
                    .to_matchable(),
                ])
                .to_matchable()
            })
            .to_matchable()
            .into(),
        ),
        (
            "CreateExternalFunctionStatementSegment".into(),
            NodeMatcher::new(SyntaxKind::CreateExternalFunctionStatement, |_| {
                Sequence::new(vec![
                    Ref::keyword("CREATE").to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("OR").to_matchable(),
                        Ref::keyword("REPLACE").to_matchable(),
                    ])
                    .config(|this| this.optional())
                    .to_matchable(),
                    Sequence::new(vec![Ref::keyword("SECURE").to_matchable()])
                        .config(|this| this.optional())
                        .to_matchable(),
                    Ref::keyword("EXTERNAL").to_matchable(),
                    Ref::keyword("FUNCTION").to_matchable(),
                    Ref::new("FunctionNameSegment").to_matchable(),
                    Ref::new("FunctionParameterListGrammar").to_matchable(),
                    Ref::keyword("RETURNS").to_matchable(),
                    Ref::new("DatatypeSegment").to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("NOT").optional().to_matchable(),
                        Ref::keyword("NULL").to_matchable(),
                    ])
                    .config(|this| this.optional())
                    .to_matchable(),
                    one_of(vec![
                        Sequence::new(vec![
                            Ref::keyword("CALLED").to_matchable(),
                            Ref::keyword("ON").to_matchable(),
                            Ref::keyword("NULL").to_matchable(),
                            Ref::keyword("INPUT").to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("RETURNS").to_matchable(),
                            Ref::keyword("NULL").to_matchable(),
                            Ref::keyword("ON").to_matchable(),
                            Ref::keyword("NULL").to_matchable(),
                            Ref::keyword("INPUT").to_matchable(),
                        ])
                        .to_matchable(),
                        Ref::keyword("STRICT").to_matchable(),
                    ])
                    .config(|this| this.optional())
                    .to_matchable(),
                    one_of(vec![
                        Ref::keyword("VOLATILE").to_matchable(),
                        Ref::keyword("IMMUTABLE").to_matchable(),
                    ])
                    .config(|this| this.optional())
                    .to_matchable(),
                    Ref::new("CommentEqualsClauseSegment")
                        .optional()
                        .to_matchable(),
                    Ref::keyword("API_INTEGRATION").to_matchable(),
                    Ref::new("EqualsSegment").to_matchable(),
                    Ref::new("SingleIdentifierGrammar").to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("HEADERS").to_matchable(),
                        Ref::new("EqualsSegment").to_matchable(),
                        Bracketed::new(vec![
                            Delimited::new(vec![
                                Sequence::new(vec![
                                    Ref::new("SingleQuotedIdentifierSegment").to_matchable(),
                                    Ref::new("EqualsSegment").to_matchable(),
                                    Ref::new("SingleQuotedIdentifierSegment").to_matchable(),
                                ])
                                .to_matchable(),
                            ])
                            .to_matchable(),
                        ])
                        .to_matchable(),
                    ])
                    .config(|this| this.optional())
                    .to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("CONTEXT_HEADERS").to_matchable(),
                        Ref::new("EqualsSegment").to_matchable(),
                        Bracketed::new(vec![
                            Delimited::new(vec![Ref::new("ContextHeadersGrammar").to_matchable()])
                                .to_matchable(),
                        ])
                        .to_matchable(),
                    ])
                    .config(|this| this.optional())
                    .to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("MAX_BATCH_ROWS").to_matchable(),
                        Ref::new("EqualsSegment").to_matchable(),
                        Ref::new("NumericLiteralSegment").to_matchable(),
                    ])
                    .config(|this| this.optional())
                    .to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("COMPRESSION").to_matchable(),
                        Ref::new("EqualsSegment").to_matchable(),
                        Ref::new("CompressionType").to_matchable(),
                    ])
                    .config(|this| this.optional())
                    .to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("REQUEST_TRANSLATOR").to_matchable(),
                        Ref::new("EqualsSegment").to_matchable(),
                        Ref::new("FunctionNameSegment").to_matchable(),
                    ])
                    .config(|this| this.optional())
                    .to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("RESPONSE_TRANSLATOR").to_matchable(),
                        Ref::new("EqualsSegment").to_matchable(),
                        Ref::new("FunctionNameSegment").to_matchable(),
                    ])
                    .config(|this| this.optional())
                    .to_matchable(),
                    Ref::keyword("AS").to_matchable(),
                    Ref::new("SingleQuotedIdentifierSegment").to_matchable(),
                ])
                .to_matchable()
            })
            .to_matchable()
            .into(),
        ),
        (
            "WarehouseObjectPropertiesSegment".into(),
            NodeMatcher::new(SyntaxKind::WarehouseObjectProperties, |_| {
                any_set_of(vec![
                    Sequence::new(vec![
                        Ref::keyword("WAREHOUSE_TYPE").to_matchable(),
                        Ref::new("EqualsSegment").to_matchable(),
                        Ref::new("WarehouseType").to_matchable(),
                    ])
                    .to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("WAREHOUSE_SIZE").to_matchable(),
                        Ref::new("EqualsSegment").to_matchable(),
                        Ref::new("WarehouseSize").to_matchable(),
                    ])
                    .to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("WAIT_FOR_COMPLETION").to_matchable(),
                        Ref::new("EqualsSegment").to_matchable(),
                        Ref::new("BooleanLiteralGrammar").to_matchable(),
                    ])
                    .to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("MAX_CLUSTER_COUNT").to_matchable(),
                        Ref::new("EqualsSegment").to_matchable(),
                        Ref::new("NumericLiteralSegment").to_matchable(),
                    ])
                    .to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("MIN_CLUSTER_COUNT").to_matchable(),
                        Ref::new("EqualsSegment").to_matchable(),
                        Ref::new("NumericLiteralSegment").to_matchable(),
                    ])
                    .to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("SCALING_POLICY").to_matchable(),
                        Ref::new("EqualsSegment").to_matchable(),
                        Ref::new("ScalingPolicy").to_matchable(),
                    ])
                    .to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("AUTO_SUSPEND").to_matchable(),
                        Ref::new("EqualsSegment").to_matchable(),
                        one_of(vec![
                            Ref::new("NumericLiteralSegment").to_matchable(),
                            Ref::keyword("NULL").to_matchable(),
                        ])
                        .to_matchable(),
                    ])
                    .to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("AUTO_RESUME").to_matchable(),
                        Ref::new("EqualsSegment").to_matchable(),
                        Ref::new("BooleanLiteralGrammar").to_matchable(),
                    ])
                    .to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("INITIALLY_SUSPENDED").to_matchable(),
                        Ref::new("EqualsSegment").to_matchable(),
                        Ref::new("BooleanLiteralGrammar").to_matchable(),
                    ])
                    .to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("RESOURCE_MONITOR").to_matchable(),
                        Ref::new("EqualsSegment").to_matchable(),
                        Ref::new("NakedIdentifierSegment").to_matchable(),
                    ])
                    .to_matchable(),
                ])
                .to_matchable()
            })
            .to_matchable()
            .into(),
        ),
        (
            "WarehouseObjectParamsSegment".into(),
            NodeMatcher::new(SyntaxKind::WarehouseObjectProperties, |_| {
                any_set_of(vec![
                    Sequence::new(vec![
                        Ref::keyword("MAX_CONCURRENCY_LEVEL").to_matchable(),
                        Ref::new("EqualsSegment").to_matchable(),
                        Ref::new("NumericLiteralSegment").to_matchable(),
                    ])
                    .to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("STATEMENT_QUEUED_TIMEOUT_IN_SECONDS").to_matchable(),
                        Ref::new("EqualsSegment").to_matchable(),
                        Ref::new("NumericLiteralSegment").to_matchable(),
                    ])
                    .to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("STATEMENT_TIMEOUT_IN_SECONDS").to_matchable(),
                        Ref::new("EqualsSegment").to_matchable(),
                        Ref::new("NumericLiteralSegment").to_matchable(),
                    ])
                    .to_matchable(),
                ])
                .to_matchable()
            })
            .to_matchable()
            .into(),
        ),
        (
            "ConstraintPropertiesSegment".into(),
            NodeMatcher::new(SyntaxKind::ConstraintPropertiesSegment, |_| {
                Sequence::new(vec![
                    Sequence::new(vec![
                        Ref::keyword("CONSTRAINT").to_matchable(),
                        Ref::new("QuotedLiteralSegment").to_matchable(),
                    ])
                    .config(|this| this.optional())
                    .to_matchable(),
                    one_of(vec![
                        Sequence::new(vec![
                            Ref::keyword("UNIQUE").to_matchable(),
                            Bracketed::new(vec![Ref::new("ColumnReferenceSegment").to_matchable()])
                                .config(|this| this.optional())
                                .to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::new("PrimaryKeyGrammar").to_matchable(),
                            Bracketed::new(vec![Ref::new("ColumnReferenceSegment").to_matchable()])
                                .config(|this| this.optional())
                                .to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Sequence::new(vec![
                                Ref::new("ForeignKeyGrammar").to_matchable(),
                                Bracketed::new(vec![
                                    Ref::new("ColumnReferenceSegment").to_matchable(),
                                ])
                                .config(|this| this.optional())
                                .to_matchable(),
                            ])
                            .to_matchable(),
                            Ref::keyword("REFERENCES").to_matchable(),
                            Ref::new("TableReferenceSegment").to_matchable(),
                            Bracketed::new(vec![Ref::new("ColumnReferenceSegment").to_matchable()])
                                .to_matchable(),
                        ])
                        .to_matchable(),
                    ])
                    .to_matchable(),
                    any_set_of(vec![
                        one_of(vec![
                            Sequence::new(vec![
                                Ref::keyword("NOT").optional().to_matchable(),
                                Ref::keyword("ENFORCED").to_matchable(),
                            ])
                            .to_matchable(),
                            Sequence::new(vec![
                                Ref::keyword("NOT").optional().to_matchable(),
                                Ref::keyword("DEFERRABLE").to_matchable(),
                            ])
                            .to_matchable(),
                            Sequence::new(vec![
                                Ref::keyword("INITIALLY").to_matchable(),
                                one_of(vec![
                                    Ref::keyword("DEFERRED").to_matchable(),
                                    Ref::keyword("IMMEDIATE").to_matchable(),
                                ])
                                .to_matchable(),
                            ])
                            .to_matchable(),
                        ])
                        .to_matchable(),
                    ])
                    .to_matchable(),
                ])
                .to_matchable()
            })
            .to_matchable()
            .into(),
        ),
    ]);

    snowflake_dialect.replace_grammar(
        "ColumnConstraintSegment",
        any_set_of(vec![
            Sequence::new(vec![
                Ref::keyword("COLLATE").to_matchable(),
                Ref::new("CollationReferenceSegment").to_matchable(),
            ])
            .to_matchable(),
            Sequence::new(vec![
                Ref::keyword("DEFAULT").to_matchable(),
                Ref::new("ExpressionSegment").to_matchable(),
            ])
            .to_matchable(),
            Sequence::new(vec![
                one_of(vec![
                    Ref::keyword("AUTOINCREMENT").to_matchable(),
                    Ref::keyword("IDENTITY").to_matchable(),
                ])
                .to_matchable(),
                one_of(vec![
                    Bracketed::new(vec![
                        Delimited::new(vec![Ref::new("NumericLiteralSegment").to_matchable()])
                            .to_matchable(),
                    ])
                    .to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("START").to_matchable(),
                        Ref::new("NumericLiteralSegment").to_matchable(),
                        Ref::keyword("INCREMENT").to_matchable(),
                        Ref::new("NumericLiteralSegment").to_matchable(),
                    ])
                    .to_matchable(),
                ])
                .config(|this| this.optional())
                .to_matchable(),
            ])
            .to_matchable(),
            Sequence::new(vec![
                Ref::keyword("NOT").optional().to_matchable(),
                Ref::keyword("NULL").to_matchable(),
            ])
            .to_matchable(),
            Sequence::new(vec![
                Ref::keyword("WITH").optional().to_matchable(),
                Ref::keyword("MASKING").to_matchable(),
                Ref::keyword("POLICY").to_matchable(),
                Ref::new("FunctionNameSegment").to_matchable(),
                Sequence::new(vec![
                    Ref::keyword("USING").to_matchable(),
                    Bracketed::new(vec![
                        Delimited::new(vec![
                            one_of(vec![
                                Ref::new("ColumnReferenceSegment").to_matchable(),
                                Ref::new("ExpressionSegment").to_matchable(),
                            ])
                            .to_matchable(),
                        ])
                        .to_matchable(),
                    ])
                    .to_matchable(),
                ])
                .config(|this| this.optional())
                .to_matchable(),
            ])
            .to_matchable(),
            Ref::new("TagBracketedEqualsSegment")
                .optional()
                .to_matchable(),
            Ref::new("ConstraintPropertiesSegment").to_matchable(),
            Sequence::new(vec![
                Ref::keyword("CHECK").to_matchable(),
                Bracketed::new(vec![Ref::new("ExpressionSegment").to_matchable()]).to_matchable(),
            ])
            .to_matchable(),
            Sequence::new(vec![
                Ref::keyword("REFERENCES").to_matchable(),
                Ref::new("ColumnReferenceSegment").to_matchable(),
                Ref::new("BracketedColumnReferenceListGrammar")
                    .optional()
                    .to_matchable(),
            ])
            .to_matchable(),
        ])
        .to_matchable(),
    );

    snowflake_dialect.add([(
        "CopyOptionsSegment".into(),
        NodeMatcher::new(SyntaxKind::CopyOptions, |_| {
            one_of(vec![
                any_set_of(vec![
                    Sequence::new(vec![
                        Ref::keyword("ON_ERROR").to_matchable(),
                        Ref::new("EqualsSegment").to_matchable(),
                        Ref::new("CopyOptionOnErrorSegment").to_matchable(),
                    ])
                    .to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("SIZE_LIMIT").to_matchable(),
                        Ref::new("EqualsSegment").to_matchable(),
                        Ref::new("NumericLiteralSegment").to_matchable(),
                    ])
                    .to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("PURGE").to_matchable(),
                        Ref::new("EqualsSegment").to_matchable(),
                        Ref::new("BooleanLiteralGrammar").to_matchable(),
                    ])
                    .to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("RETURN_FAILED_ONLY").to_matchable(),
                        Ref::new("EqualsSegment").to_matchable(),
                        Ref::new("BooleanLiteralGrammar").to_matchable(),
                    ])
                    .to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("MATCH_BY_COLUMN_NAME").to_matchable(),
                        Ref::new("EqualsSegment").to_matchable(),
                        one_of(vec![
                            Ref::keyword("CASE_SENSITIVE").to_matchable(),
                            Ref::keyword("CASE_INSENSITIVE").to_matchable(),
                            Ref::keyword("NONE").to_matchable(),
                        ])
                        .to_matchable(),
                    ])
                    .to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("ENFORCE_LENGTH").to_matchable(),
                        Ref::new("EqualsSegment").to_matchable(),
                        Ref::new("BooleanLiteralGrammar").to_matchable(),
                    ])
                    .to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("TRUNCATECOLUMNS").to_matchable(),
                        Ref::new("EqualsSegment").to_matchable(),
                        Ref::new("BooleanLiteralGrammar").to_matchable(),
                    ])
                    .to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("FORCE").to_matchable(),
                        Ref::new("EqualsSegment").to_matchable(),
                        Ref::new("BooleanLiteralGrammar").to_matchable(),
                    ])
                    .to_matchable(),
                ])
                .to_matchable(),
                any_set_of(vec![
                    Sequence::new(vec![
                        Ref::keyword("OVERWRITE").to_matchable(),
                        Ref::new("EqualsSegment").to_matchable(),
                        Ref::new("BooleanLiteralGrammar").to_matchable(),
                    ])
                    .to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("SINGLE").to_matchable(),
                        Ref::new("EqualsSegment").to_matchable(),
                        Ref::new("BooleanLiteralGrammar").to_matchable(),
                    ])
                    .to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("MAX_FILE_SIZE").to_matchable(),
                        Ref::new("EqualsSegment").to_matchable(),
                        Ref::new("NumericLiteralSegment").to_matchable(),
                    ])
                    .to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("INCLUDE_QUERY_ID").to_matchable(),
                        Ref::new("EqualsSegment").to_matchable(),
                        Ref::new("BooleanLiteralGrammar").to_matchable(),
                    ])
                    .to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("DETAILED_OUTPUT").to_matchable(),
                        Ref::new("EqualsSegment").to_matchable(),
                        Ref::new("BooleanLiteralGrammar").to_matchable(),
                    ])
                    .to_matchable(),
                ])
                .to_matchable(),
            ])
            .to_matchable()
        })
        .to_matchable()
        .into(),
    )]);

    snowflake_dialect.replace_grammar(
        "CreateSchemaStatementSegment",
        Sequence::new(vec![
            Ref::keyword("CREATE").to_matchable(),
            Ref::new("OrReplaceGrammar").optional().to_matchable(),
            Ref::new("TemporaryTransientGrammar")
                .optional()
                .to_matchable(),
            Ref::keyword("SCHEMA").to_matchable(),
            Ref::new("IfNotExistsGrammar").optional().to_matchable(),
            Ref::new("SchemaReferenceSegment").to_matchable(),
            Sequence::new(vec![
                Ref::keyword("WITH").to_matchable(),
                Ref::keyword("MANAGED").to_matchable(),
                Ref::keyword("ACCESS").to_matchable(),
            ])
            .config(|this| this.optional())
            .to_matchable(),
            Ref::new("SchemaObjectParamsSegment")
                .optional()
                .to_matchable(),
            Ref::new("TagBracketedEqualsSegment")
                .optional()
                .to_matchable(),
        ])
        .to_matchable(),
    );

    snowflake_dialect.add([
        (
            "AlterRoleStatementSegment".into(),
            NodeMatcher::new(SyntaxKind::AlterRoleStatement, |_| {
                Sequence::new(vec![
                    Ref::keyword("ALTER").to_matchable(),
                    Ref::keyword("ROLE").to_matchable(),
                    Ref::new("IfExistsGrammar").optional().to_matchable(),
                    Ref::new("RoleReferenceSegment").to_matchable(),
                    one_of(vec![
                        Sequence::new(vec![
                            Ref::keyword("SET").to_matchable(),
                            one_of(vec![
                                Ref::new("RoleReferenceSegment").to_matchable(),
                                Ref::new("TagEqualsSegment").to_matchable(),
                                Sequence::new(vec![
                                    Ref::keyword("COMMENT").to_matchable(),
                                    Ref::new("EqualsSegment").to_matchable(),
                                    Ref::new("QuotedLiteralSegment").to_matchable(),
                                ])
                                .to_matchable(),
                            ])
                            .to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("UNSET").to_matchable(),
                            one_of(vec![
                                Ref::new("RoleReferenceSegment").to_matchable(),
                                Sequence::new(vec![
                                    Ref::keyword("TAG").to_matchable(),
                                    Delimited::new(vec![
                                        Ref::new("TagReferenceSegment").to_matchable(),
                                    ])
                                    .to_matchable(),
                                ])
                                .to_matchable(),
                                Sequence::new(vec![Ref::keyword("COMMENT").to_matchable()])
                                    .to_matchable(),
                            ])
                            .to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("RENAME").to_matchable(),
                            Ref::keyword("TO").to_matchable(),
                            one_of(vec![Ref::new("RoleReferenceSegment").to_matchable()])
                                .to_matchable(),
                        ])
                        .to_matchable(),
                    ])
                    .to_matchable(),
                ])
                .to_matchable()
            })
            .to_matchable()
            .into(),
        ),
        (
            "AlterSchemaStatementSegment".into(),
            NodeMatcher::new(SyntaxKind::AlterSchemaStatement, |_| {
                Sequence::new(vec![
                    Ref::keyword("ALTER").to_matchable(),
                    Ref::keyword("SCHEMA").to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("IF").to_matchable(),
                        Ref::keyword("EXISTS").to_matchable(),
                    ])
                    .config(|this| this.optional())
                    .to_matchable(),
                    Ref::new("SchemaReferenceSegment").to_matchable(),
                    one_of(vec![
                        Sequence::new(vec![
                            Ref::keyword("RENAME").to_matchable(),
                            Ref::keyword("TO").to_matchable(),
                            Ref::new("SchemaReferenceSegment").to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("SWAP").to_matchable(),
                            Ref::keyword("WITH").to_matchable(),
                            Ref::new("SchemaReferenceSegment").to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("SET").to_matchable(),
                            one_of(vec![
                                Ref::new("SchemaObjectParamsSegment").to_matchable(),
                                Ref::new("TagEqualsSegment").to_matchable(),
                            ])
                            .to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("UNSET").to_matchable(),
                            one_of(vec![
                                Delimited::new(vec![
                                    Ref::keyword("DATA_RETENTION_TIME_IN_DAYS").to_matchable(),
                                    Ref::keyword("MAX_DATA_EXTENSION_TIME_IN_DAYS").to_matchable(),
                                    Ref::keyword("DEFAULT_DDL_COLLATION").to_matchable(),
                                    Ref::keyword("COMMENT").to_matchable(),
                                ])
                                .to_matchable(),
                                Sequence::new(vec![
                                    Ref::keyword("TAG").to_matchable(),
                                    Delimited::new(vec![
                                        Ref::new("TagReferenceSegment").to_matchable(),
                                    ])
                                    .to_matchable(),
                                ])
                                .to_matchable(),
                            ])
                            .to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            one_of(vec![
                                Ref::keyword("ENABLE").to_matchable(),
                                Ref::keyword("DISABLE").to_matchable(),
                            ])
                            .to_matchable(),
                            Sequence::new(vec![
                                Ref::keyword("MANAGED").to_matchable(),
                                Ref::keyword("ACCESS").to_matchable(),
                            ])
                            .to_matchable(),
                        ])
                        .to_matchable(),
                    ])
                    .to_matchable(),
                ])
                .to_matchable()
            })
            .to_matchable()
            .into(),
        ),
        (
            "SchemaObjectParamsSegment".into(),
            NodeMatcher::new(SyntaxKind::SchemaObjectProperties, |_| {
                any_set_of(vec![
                    Sequence::new(vec![
                        Ref::keyword("DATA_RETENTION_TIME_IN_DAYS").to_matchable(),
                        Ref::new("EqualsSegment").to_matchable(),
                        Ref::new("NumericLiteralSegment").to_matchable(),
                    ])
                    .to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("MAX_DATA_EXTENSION_TIME_IN_DAYS").to_matchable(),
                        Ref::new("EqualsSegment").to_matchable(),
                        Ref::new("NumericLiteralSegment").to_matchable(),
                    ])
                    .to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("DEFAULT_DDL_COLLATION").to_matchable(),
                        Ref::new("EqualsSegment").to_matchable(),
                        Ref::new("QuotedLiteralSegment").to_matchable(),
                    ])
                    .to_matchable(),
                    Ref::new("CommentEqualsClauseSegment").to_matchable(),
                ])
                .to_matchable()
            })
            .to_matchable()
            .into(),
        ),
    ]);

    snowflake_dialect.replace_grammar(
        "CreateTableStatementSegment",
        Sequence::new(vec![
            Ref::keyword("CREATE").to_matchable(),
            Ref::new("OrReplaceGrammar").optional().to_matchable(),
            Ref::new("TemporaryTransientGrammar")
                .optional()
                .to_matchable(),
            Ref::keyword("TABLE").to_matchable(),
            Ref::new("IfNotExistsGrammar").optional().to_matchable(),
            Ref::new("TableReferenceSegment").to_matchable(),
            any_set_of(vec![
                Sequence::new(vec![
                    Bracketed::new(vec![
                        Delimited::new(vec![
                            Sequence::new(vec![
                                one_of(vec![
                                    Ref::new("TableConstraintSegment").to_matchable(),
                                    Ref::new("ColumnDefinitionSegment").to_matchable(),
                                    Ref::new("SingleIdentifierGrammar").to_matchable(),
                                ])
                                .to_matchable(),
                                Ref::new("CommentClauseSegment").optional().to_matchable(),
                            ])
                            .to_matchable(),
                        ])
                        .to_matchable(),
                    ])
                    .to_matchable(),
                ])
                .config(|this| this.optional())
                .to_matchable(),
                Sequence::new(vec![
                    Ref::keyword("CLUSTER").to_matchable(),
                    Ref::keyword("BY").to_matchable(),
                    one_of(vec![
                        Ref::new("FunctionSegment").to_matchable(),
                        Bracketed::new(vec![
                            Delimited::new(vec![Ref::new("ExpressionSegment").to_matchable()])
                                .to_matchable(),
                        ])
                        .to_matchable(),
                    ])
                    .to_matchable(),
                ])
                .config(|this| this.optional())
                .to_matchable(),
                Sequence::new(vec![
                    Ref::keyword("STAGE_FILE_FORMAT").to_matchable(),
                    Ref::new("EqualsSegment").to_matchable(),
                    Ref::new("FileFormatSegment").to_matchable(),
                ])
                .config(|this| this.optional())
                .to_matchable(),
                Sequence::new(vec![
                    Ref::keyword("STAGE_COPY_OPTIONS").to_matchable(),
                    Ref::new("EqualsSegment").to_matchable(),
                    Bracketed::new(vec![Ref::new("CopyOptionsSegment").to_matchable()])
                        .to_matchable(),
                ])
                .config(|this| this.optional())
                .to_matchable(),
                Sequence::new(vec![
                    Ref::keyword("DATA_RETENTION_TIME_IN_DAYS").to_matchable(),
                    Ref::new("EqualsSegment").to_matchable(),
                    Ref::new("NumericLiteralSegment").to_matchable(),
                ])
                .config(|this| this.optional())
                .to_matchable(),
                Sequence::new(vec![
                    Ref::keyword("MAX_DATA_EXTENSION_TIME_IN_DAYS").to_matchable(),
                    Ref::new("EqualsSegment").to_matchable(),
                    Ref::new("NumericLiteralSegment").to_matchable(),
                ])
                .config(|this| this.optional())
                .to_matchable(),
                Sequence::new(vec![
                    Ref::keyword("CHANGE_TRACKING").to_matchable(),
                    Ref::new("EqualsSegment").to_matchable(),
                    Ref::new("BooleanLiteralGrammar").to_matchable(),
                ])
                .config(|this| this.optional())
                .to_matchable(),
                Sequence::new(vec![
                    Ref::keyword("DEFAULT_DDL_COLLATION").to_matchable(),
                    Ref::new("EqualsSegment").to_matchable(),
                    Ref::new("QuotedLiteralGrammar").to_matchable(),
                ])
                .config(|this| this.optional())
                .to_matchable(),
                Sequence::new(vec![
                    Ref::keyword("COPY").to_matchable(),
                    Ref::keyword("GRANTS").to_matchable(),
                ])
                .config(|this| this.optional())
                .to_matchable(),
                Sequence::new(vec![
                    Ref::keyword("WITH").optional().to_matchable(),
                    Ref::keyword("ROW").to_matchable(),
                    Ref::keyword("ACCESS").to_matchable(),
                    Ref::keyword("POLICY").to_matchable(),
                    Ref::new("NakedIdentifierSegment").to_matchable(),
                    Ref::keyword("ON").to_matchable(),
                    Bracketed::new(vec![
                        Delimited::new(vec![Ref::new("ColumnReferenceSegment").to_matchable()])
                            .to_matchable(),
                    ])
                    .to_matchable(),
                ])
                .config(|this| this.optional())
                .to_matchable(),
                Ref::new("TagBracketedEqualsSegment")
                    .optional()
                    .to_matchable(),
                Ref::new("CommentEqualsClauseSegment")
                    .optional()
                    .to_matchable(),
                one_of(vec![
                    Sequence::new(vec![
                        Ref::keyword("AS").to_matchable(),
                        optionally_bracketed(vec![Ref::new("SelectableGrammar").to_matchable()])
                            .to_matchable(),
                    ])
                    .to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("LIKE").to_matchable(),
                        Ref::new("TableReferenceSegment").to_matchable(),
                    ])
                    .to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("CLONE").to_matchable(),
                        Ref::new("TableReferenceSegment").to_matchable(),
                    ])
                    .to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("USING").to_matchable(),
                        Ref::keyword("TEMPLATE").to_matchable(),
                        Ref::new("SelectableGrammar").to_matchable(),
                    ])
                    .to_matchable(),
                ])
                .config(|this| this.optional())
                .to_matchable(),
            ])
            .to_matchable(),
        ])
        .to_matchable(),
    );

    snowflake_dialect.add([
        (
            "CreateTaskSegment".into(),
            NodeMatcher::new(SyntaxKind::CreateTaskStatement, |_| {
                Sequence::new(vec![
                    Ref::keyword("CREATE").to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("OR").to_matchable(),
                        Ref::keyword("REPLACE").to_matchable(),
                    ])
                    .config(|this| this.optional())
                    .to_matchable(),
                    Ref::keyword("TASK").to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("IF").to_matchable(),
                        Ref::keyword("NOT").to_matchable(),
                        Ref::keyword("EXISTS").to_matchable(),
                    ])
                    .config(|this| this.optional())
                    .to_matchable(),
                    Ref::new("ObjectReferenceSegment").to_matchable(),
                    MetaSegment::indent().to_matchable(),
                    AnyNumberOf::new(vec![
                        one_of(vec![
                            Sequence::new(vec![
                                Ref::keyword("WAREHOUSE").to_matchable(),
                                Ref::new("EqualsSegment").to_matchable(),
                                Ref::new("ObjectReferenceSegment").to_matchable(),
                            ])
                            .to_matchable(),
                            Sequence::new(vec![
                                Ref::keyword("USER_TASK_MANAGED_INITIAL_WAREHOUSE_SIZE")
                                    .to_matchable(),
                                Ref::new("EqualsSegment").to_matchable(),
                                Ref::new("WarehouseSize").to_matchable(),
                            ])
                            .to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("SCHEDULE").to_matchable(),
                            Ref::new("EqualsSegment").to_matchable(),
                            Ref::new("QuotedLiteralSegment").to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("ALLOW_OVERLAPPING_EXECUTION").to_matchable(),
                            Ref::new("EqualsSegment").to_matchable(),
                            Ref::new("BooleanLiteralGrammar").to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("USER_TASK_TIMEOUT_MS").to_matchable(),
                            Ref::new("EqualsSegment").to_matchable(),
                            Ref::new("NumericLiteralSegment").to_matchable(),
                        ])
                        .to_matchable(),
                        Delimited::new(vec![
                            Sequence::new(vec![
                                Ref::new("ParameterNameSegment").to_matchable(),
                                Ref::new("EqualsSegment").to_matchable(),
                                one_of(vec![
                                    Ref::new("BooleanLiteralGrammar").to_matchable(),
                                    Ref::new("QuotedLiteralSegment").to_matchable(),
                                    Ref::new("NumericLiteralSegment").to_matchable(),
                                ])
                                .to_matchable(),
                            ])
                            .to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("COPY").to_matchable(),
                            Ref::keyword("GRANTS").to_matchable(),
                        ])
                        .to_matchable(),
                        Ref::new("CommentEqualsClauseSegment").to_matchable(),
                    ])
                    .to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("AFTER").to_matchable(),
                        Ref::new("ObjectReferenceSegment").to_matchable(),
                    ])
                    .config(|this| this.optional())
                    .to_matchable(),
                    MetaSegment::dedent().to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("WHEN").to_matchable(),
                        MetaSegment::indent().to_matchable(),
                        Ref::new("TaskExpressionSegment").to_matchable(),
                        MetaSegment::dedent().to_matchable(),
                    ])
                    .config(|this| this.optional())
                    .to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("AS").to_matchable(),
                        MetaSegment::indent().to_matchable(),
                        Ref::new("StatementSegment").to_matchable(),
                        MetaSegment::dedent().to_matchable(),
                    ])
                    .to_matchable(),
                ])
                .to_matchable()
            })
            .to_matchable()
            .into(),
        ),
        (
            "TaskExpressionSegment".into(),
            NodeMatcher::new(SyntaxKind::SnowflakeTaskExpressionSegment, |_| {
                Sequence::new(vec![
                    Delimited::new(vec![
                        one_of(vec![
                            Ref::new("ExpressionSegment").to_matchable(),
                            Sequence::new(vec![
                                Ref::new("SystemFunctionName").to_matchable(),
                                Bracketed::new(vec![
                                    Ref::new("QuotedLiteralSegment").to_matchable(),
                                ])
                                .to_matchable(),
                            ])
                            .to_matchable(),
                        ])
                        .to_matchable(),
                    ])
                    .config(|this| {
                        this.delimiter(one_of(vec![
                            Ref::new("BooleanBinaryOperatorGrammar").to_matchable(),
                        ]))
                    })
                    .to_matchable(),
                ])
                .to_matchable()
            })
            .to_matchable()
            .into(),
        ),
        (
            "CreateStatementSegment".into(),
            NodeMatcher::new(SyntaxKind::CreateStatement, |_| {
                Sequence::new(vec![
                    Ref::keyword("CREATE").to_matchable(),
                    Ref::new("OrReplaceGrammar").optional().to_matchable(),
                    one_of(vec![
                        Sequence::new(vec![
                            Ref::keyword("NETWORK").to_matchable(),
                            Ref::keyword("POLICY").to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("RESOURCE").to_matchable(),
                            Ref::keyword("MONITOR").to_matchable(),
                        ])
                        .to_matchable(),
                        Ref::keyword("SHARE").to_matchable(),
                        Ref::keyword("ROLE").to_matchable(),
                        Ref::keyword("USER").to_matchable(),
                        Ref::keyword("TAG").to_matchable(),
                        Ref::keyword("WAREHOUSE").to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("NOTIFICATION").to_matchable(),
                            Ref::keyword("INTEGRATION").to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("SECURITY").to_matchable(),
                            Ref::keyword("INTEGRATION").to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("STORAGE").to_matchable(),
                            Ref::keyword("INTEGRATION").to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("MATERIALIZED").to_matchable(),
                            Ref::keyword("VIEW").to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("MASKING").to_matchable(),
                            Ref::keyword("POLICY").to_matchable(),
                        ])
                        .to_matchable(),
                        Ref::keyword("PIPE").to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("EXTERNAL").to_matchable(),
                            Ref::keyword("FUNCTION").to_matchable(),
                        ])
                        .to_matchable(),
                        Ref::keyword("DATABASE").to_matchable(),
                        Ref::keyword("SEQUENCE").to_matchable(),
                    ])
                    .to_matchable(),
                    Ref::new("IfNotExistsGrammar").optional().to_matchable(),
                    Ref::new("ObjectReferenceSegment").to_matchable(),
                    any_set_of(vec![
                        Sequence::new(vec![
                            Ref::keyword("TYPE").to_matchable(),
                            Ref::new("EqualsSegment").to_matchable(),
                            Ref::keyword("QUEUE").to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("ENABLED").to_matchable(),
                            Ref::new("EqualsSegment").to_matchable(),
                            Ref::new("BooleanLiteralGrammar").to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("NOTIFICATION_PROVIDER").to_matchable(),
                            Ref::new("EqualsSegment").to_matchable(),
                            one_of(vec![
                                Ref::keyword("AWS_SNS").to_matchable(),
                                Ref::keyword("AZURE_EVENT_GRID").to_matchable(),
                                Ref::keyword("GCP_PUBSUB").to_matchable(),
                                Ref::keyword("AZURE_STORAGE_QUEUE").to_matchable(),
                                Ref::new("QuotedLiteralSegment").to_matchable(),
                            ])
                            .to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("AWS_SNS_TOPIC_ARN").to_matchable(),
                            Ref::new("EqualsSegment").to_matchable(),
                            Ref::new("QuotedLiteralSegment").to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("AWS_SNS_ROLE_ARN").to_matchable(),
                            Ref::new("EqualsSegment").to_matchable(),
                            Ref::new("QuotedLiteralSegment").to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("AZURE_TENANT_ID").to_matchable(),
                            Ref::new("EqualsSegment").to_matchable(),
                            Ref::new("QuotedLiteralSegment").to_matchable(),
                        ])
                        .to_matchable(),
                        one_of(vec![
                            Sequence::new(vec![
                                Ref::keyword("AZURE_STORAGE_QUEUE_PRIMARY_URI").to_matchable(),
                                Ref::new("EqualsSegment").to_matchable(),
                                Ref::new("QuotedLiteralSegment").to_matchable(),
                            ])
                            .to_matchable(),
                            Sequence::new(vec![
                                Ref::keyword("AZURE_EVENT_GRID_TOPIC_ENDPOINT").to_matchable(),
                                Ref::new("EqualsSegment").to_matchable(),
                                Ref::new("QuotedLiteralSegment").to_matchable(),
                            ])
                            .to_matchable(),
                        ])
                        .to_matchable(),
                        one_of(vec![
                            Sequence::new(vec![
                                Ref::keyword("GCP_PUBSUB_SUBSCRIPTION_NAME").to_matchable(),
                                Ref::new("EqualsSegment").to_matchable(),
                                Ref::new("QuotedLiteralSegment").to_matchable(),
                            ])
                            .to_matchable(),
                            Sequence::new(vec![
                                Ref::keyword("GCP_PUBSUB_TOPIC_NAME").to_matchable(),
                                Ref::new("EqualsSegment").to_matchable(),
                                Ref::new("QuotedLiteralSegment").to_matchable(),
                            ])
                            .to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("DIRECTION").to_matchable(),
                            Ref::new("EqualsSegment").to_matchable(),
                            Ref::keyword("OUTBOUND").to_matchable(),
                        ])
                        .config(|this| this.optional())
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("COMMENT").to_matchable(),
                            Ref::new("EqualsSegment").to_matchable(),
                            Ref::new("QuotedLiteralSegment").to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("ALLOWED_VALUES").to_matchable(),
                            Delimited::new(vec![Ref::new("QuotedLiteralSegment").to_matchable()])
                                .to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("ALLOWED_IP_LIST").to_matchable(),
                            Ref::new("EqualsSegment").to_matchable(),
                            Bracketed::new(vec![
                                Delimited::new(vec![
                                    Ref::new("QuotedLiteralSegment").to_matchable(),
                                ])
                                .to_matchable(),
                            ])
                            .to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("BLOCKED_IP_LIST").to_matchable(),
                            Ref::new("EqualsSegment").to_matchable(),
                            Bracketed::new(vec![
                                Delimited::new(vec![
                                    Ref::new("QuotedLiteralSegment").to_matchable(),
                                ])
                                .to_matchable(),
                            ])
                            .to_matchable(),
                        ])
                        .to_matchable(),
                    ])
                    .to_matchable(),
                    any_set_of(vec![
                        Sequence::new(vec![
                            Ref::keyword("TYPE").to_matchable(),
                            Ref::new("EqualsSegment").to_matchable(),
                            Ref::keyword("EXTERNAL_STAGE").to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("ENABLED").to_matchable(),
                            Ref::new("EqualsSegment").to_matchable(),
                            Ref::new("BooleanLiteralGrammar").to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("STORAGE_PROVIDER").to_matchable(),
                            Ref::new("EqualsSegment").to_matchable(),
                            one_of(vec![
                                Ref::keyword("S3").to_matchable(),
                                Ref::keyword("AZURE").to_matchable(),
                                Ref::keyword("GCS").to_matchable(),
                                Ref::new("QuotedLiteralSegment").to_matchable(),
                            ])
                            .to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("AZURE_TENANT_ID").to_matchable(),
                            Ref::new("EqualsSegment").to_matchable(),
                            Ref::new("QuotedLiteralSegment").to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("STORAGE_AWS_ROLE_ARN").to_matchable(),
                            Ref::new("EqualsSegment").to_matchable(),
                            Ref::new("QuotedLiteralSegment").to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("STORAGE_AWS_OBJECT_ACL").to_matchable(),
                            Ref::new("EqualsSegment").to_matchable(),
                            StringParser::new("'bucket-owner-full-control'", SyntaxKind::Literal)
                                .to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("STORAGE_ALLOWED_LOCATIONS").to_matchable(),
                            Ref::new("EqualsSegment").to_matchable(),
                            one_of(vec![
                                Bracketed::new(vec![
                                    Delimited::new(vec![
                                        one_of(vec![
                                            Ref::new("S3Path").to_matchable(),
                                            Ref::new("GCSPath").to_matchable(),
                                            Ref::new("AzureBlobStoragePath").to_matchable(),
                                        ])
                                        .to_matchable(),
                                    ])
                                    .to_matchable(),
                                ])
                                .to_matchable(),
                                Bracketed::new(vec![Ref::new("QuotedStarSegment").to_matchable()])
                                    .to_matchable(),
                            ])
                            .to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("STORAGE_BLOCKED_LOCATIONS").to_matchable(),
                            Ref::new("EqualsSegment").to_matchable(),
                            Bracketed::new(vec![
                                Delimited::new(vec![
                                    one_of(vec![
                                        Ref::new("S3Path").to_matchable(),
                                        Ref::new("GCSPath").to_matchable(),
                                        Ref::new("AzureBlobStoragePath").to_matchable(),
                                    ])
                                    .to_matchable(),
                                ])
                                .to_matchable(),
                            ])
                            .to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("COMMENT").to_matchable(),
                            Ref::new("EqualsSegment").to_matchable(),
                            Ref::new("QuotedLiteralSegment").to_matchable(),
                        ])
                        .to_matchable(),
                    ])
                    .to_matchable(),
                    Sequence::new(vec![
                        Sequence::new(vec![
                            Ref::keyword("AUTO_INGEST").to_matchable(),
                            Ref::new("EqualsSegment").to_matchable(),
                            Ref::new("BooleanLiteralGrammar").to_matchable(),
                        ])
                        .config(|this| this.optional())
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("ERROR_INTEGRATION").to_matchable(),
                            Ref::new("EqualsSegment").to_matchable(),
                            Ref::new("ObjectReferenceSegment").to_matchable(),
                        ])
                        .config(|this| this.optional())
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("AWS_SNS_TOPIC").to_matchable(),
                            Ref::new("EqualsSegment").to_matchable(),
                            Ref::new("QuotedLiteralSegment").to_matchable(),
                        ])
                        .config(|this| this.optional())
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("INTEGRATION").to_matchable(),
                            Ref::new("EqualsSegment").to_matchable(),
                            one_of(vec![
                                Ref::new("QuotedLiteralSegment").to_matchable(),
                                Ref::new("ObjectReferenceSegment").to_matchable(),
                            ])
                            .to_matchable(),
                        ])
                        .config(|this| this.optional())
                        .to_matchable(),
                    ])
                    .config(|this| this.optional())
                    .to_matchable(),
                    Sequence::new(vec![
                        Sequence::new(vec![Ref::keyword("WITH").to_matchable()])
                            .config(|this| this.optional())
                            .to_matchable(),
                        AnyNumberOf::new(vec![
                            Ref::new("WarehouseObjectPropertiesSegment").to_matchable(),
                            Ref::new("CommentEqualsClauseSegment").to_matchable(),
                            Ref::new("WarehouseObjectParamsSegment").to_matchable(),
                        ])
                        .to_matchable(),
                        Ref::new("TagBracketedEqualsSegment")
                            .optional()
                            .to_matchable(),
                    ])
                    .config(|this| this.optional())
                    .to_matchable(),
                    Ref::new("CommentEqualsClauseSegment")
                        .optional()
                        .to_matchable(),
                    Ref::keyword("AS").optional().to_matchable(),
                    one_of(vec![
                        Ref::new("SelectStatementSegment").to_matchable(),
                        Sequence::new(vec![
                            Bracketed::new(vec![
                                Ref::new("FunctionContentsGrammar").to_matchable(),
                            ])
                            .config(|this| this.optional())
                            .to_matchable(),
                            Ref::keyword("RETURNS").to_matchable(),
                            Ref::new("DatatypeSegment").to_matchable(),
                            Ref::new("FunctionAssignerSegment").to_matchable(),
                            Ref::new("ExpressionSegment").to_matchable(),
                            Sequence::new(vec![
                                Ref::keyword("COMMENT").to_matchable(),
                                Ref::new("EqualsSegment").to_matchable(),
                                Ref::new("QuotedLiteralSegment").to_matchable(),
                            ])
                            .config(|this| this.optional())
                            .to_matchable(),
                        ])
                        .config(|this| this.optional())
                        .to_matchable(),
                        Ref::new("CopyIntoTableStatementSegment").to_matchable(),
                    ])
                    .config(|this| this.optional())
                    .to_matchable(),
                ])
                .to_matchable()
            })
            .to_matchable()
            .into(),
        ),
        (
            "CreateUserSegment".into(),
            NodeMatcher::new(SyntaxKind::CreateUserStatement, |_| {
                Sequence::new(vec![
                    Ref::keyword("CREATE").to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("OR").to_matchable(),
                        Ref::keyword("REPLACE").to_matchable(),
                    ])
                    .config(|this| this.optional())
                    .to_matchable(),
                    Ref::keyword("USER").to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("IF").to_matchable(),
                        Ref::keyword("NOT").to_matchable(),
                        Ref::keyword("EXISTS").to_matchable(),
                    ])
                    .config(|this| this.optional())
                    .to_matchable(),
                    Ref::new("ObjectReferenceSegment").to_matchable(),
                    MetaSegment::indent().to_matchable(),
                    AnyNumberOf::new(vec![
                        Sequence::new(vec![
                            Ref::keyword("PASSWORD").to_matchable(),
                            Ref::new("EqualsSegment").to_matchable(),
                            Ref::new("QuotedLiteralSegment").to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("LOGIN_NAME").to_matchable(),
                            Ref::new("EqualsSegment").to_matchable(),
                            one_of(vec![
                                Ref::new("ObjectReferenceSegment").to_matchable(),
                                Ref::new("QuotedLiteralSegment").to_matchable(),
                            ])
                            .to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("DISPLAY_NAME").to_matchable(),
                            Ref::new("EqualsSegment").to_matchable(),
                            one_of(vec![
                                Ref::new("ObjectReferenceSegment").to_matchable(),
                                Ref::new("QuotedLiteralSegment").to_matchable(),
                            ])
                            .to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("FIRST_NAME").to_matchable(),
                            Ref::new("EqualsSegment").to_matchable(),
                            one_of(vec![
                                Ref::new("ObjectReferenceSegment").to_matchable(),
                                Ref::new("QuotedLiteralSegment").to_matchable(),
                            ])
                            .to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("MIDDLE_NAME").to_matchable(),
                            Ref::new("EqualsSegment").to_matchable(),
                            one_of(vec![
                                Ref::new("ObjectReferenceSegment").to_matchable(),
                                Ref::new("QuotedLiteralSegment").to_matchable(),
                            ])
                            .to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("LAST_NAME").to_matchable(),
                            Ref::new("EqualsSegment").to_matchable(),
                            one_of(vec![
                                Ref::new("ObjectReferenceSegment").to_matchable(),
                                Ref::new("QuotedLiteralSegment").to_matchable(),
                            ])
                            .to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("EMAIL").to_matchable(),
                            Ref::new("EqualsSegment").to_matchable(),
                            Ref::new("QuotedLiteralSegment").to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("MUST_CHANGE_PASSWORD").to_matchable(),
                            Ref::new("EqualsSegment").to_matchable(),
                            Ref::new("BooleanLiteralGrammar").to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("DISABLED").to_matchable(),
                            Ref::new("EqualsSegment").to_matchable(),
                            Ref::new("BooleanLiteralGrammar").to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("DAYS_TO_EXPIRY").to_matchable(),
                            Ref::new("EqualsSegment").to_matchable(),
                            Ref::new("NumericLiteralSegment").to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("MINS_TO_UNLOCK").to_matchable(),
                            Ref::new("EqualsSegment").to_matchable(),
                            Ref::new("NumericLiteralSegment").to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("DEFAULT_WAREHOUSE").to_matchable(),
                            Ref::new("EqualsSegment").to_matchable(),
                            one_of(vec![
                                Ref::new("ObjectReferenceSegment").to_matchable(),
                                Ref::new("QuotedLiteralSegment").to_matchable(),
                            ])
                            .to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("DEFAULT_NAMESPACE").to_matchable(),
                            Ref::new("EqualsSegment").to_matchable(),
                            one_of(vec![
                                Ref::new("ObjectReferenceSegment").to_matchable(),
                                Ref::new("QuotedLiteralSegment").to_matchable(),
                            ])
                            .to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("DEFAULT_ROLE").to_matchable(),
                            Ref::new("EqualsSegment").to_matchable(),
                            one_of(vec![
                                Ref::new("ObjectReferenceSegment").to_matchable(),
                                Ref::new("QuotedLiteralSegment").to_matchable(),
                            ])
                            .to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("DEFAULT_SECONDARY_ROLES").to_matchable(),
                            Ref::new("EqualsSegment").to_matchable(),
                            Bracketed::new(vec![Ref::new("QuotedLiteralSegment").to_matchable()])
                                .to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("MINS_TO_BYPASS_MFA").to_matchable(),
                            Ref::new("EqualsSegment").to_matchable(),
                            Ref::new("NumericLiteralSegment").to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("RSA_PUBLIC_KEY").to_matchable(),
                            Ref::new("EqualsSegment").to_matchable(),
                            Ref::new("ObjectReferenceSegment").to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("RSA_PUBLIC_KEY_2").to_matchable(),
                            Ref::new("EqualsSegment").to_matchable(),
                            Ref::new("ObjectReferenceSegment").to_matchable(),
                        ])
                        .to_matchable(),
                        Ref::new("CommentEqualsClauseSegment").to_matchable(),
                    ])
                    .to_matchable(),
                    MetaSegment::dedent().to_matchable(),
                ])
                .to_matchable()
            })
            .to_matchable()
            .into(),
        ),
    ]);

    snowflake_dialect.replace_grammar(
        "CreateViewStatementSegment",
        Sequence::new(vec![
            Ref::keyword("CREATE").to_matchable(),
            Ref::new("OrReplaceGrammar").optional().to_matchable(),
            any_set_of(vec![
                Ref::keyword("SECURE").to_matchable(),
                Ref::keyword("RECURSIVE").to_matchable(),
            ])
            .to_matchable(),
            Ref::new("TemporaryGrammar").optional().to_matchable(),
            Ref::keyword("VIEW").to_matchable(),
            Ref::new("IfNotExistsGrammar").optional().to_matchable(),
            Ref::new("TableReferenceSegment").to_matchable(),
            any_set_of(vec![
                Bracketed::new(vec![
                    Delimited::new(vec![
                        Sequence::new(vec![
                            Ref::new("ColumnReferenceSegment").to_matchable(),
                            Ref::new("CommentClauseSegment").optional().to_matchable(),
                        ])
                        .to_matchable(),
                    ])
                    .to_matchable(),
                ])
                .to_matchable(),
                Sequence::new(vec![
                    Ref::keyword("WITH").optional().to_matchable(),
                    Ref::keyword("ROW").to_matchable(),
                    Ref::keyword("ACCESS").to_matchable(),
                    Ref::keyword("POLICY").to_matchable(),
                    Ref::new("NakedIdentifierSegment").to_matchable(),
                    Ref::keyword("ON").to_matchable(),
                    Bracketed::new(vec![
                        Delimited::new(vec![Ref::new("ColumnReferenceSegment").to_matchable()])
                            .to_matchable(),
                    ])
                    .to_matchable(),
                ])
                .to_matchable(),
                Ref::new("TagBracketedEqualsSegment").to_matchable(),
                Sequence::new(vec![
                    Ref::keyword("COPY").to_matchable(),
                    Ref::keyword("GRANTS").to_matchable(),
                ])
                .to_matchable(),
                Ref::new("CommentEqualsClauseSegment").to_matchable(),
            ])
            .to_matchable(),
            Ref::keyword("AS").to_matchable(),
            optionally_bracketed(vec![Ref::new("SelectableGrammar").to_matchable()]).to_matchable(),
        ])
        .to_matchable(),
    );

    snowflake_dialect.add([
        (
            "AlterViewStatementSegment".into(),
            NodeMatcher::new(SyntaxKind::AlterViewStatement, |_| {
                Sequence::new(vec![
                    Ref::keyword("ALTER").to_matchable(),
                    Ref::keyword("VIEW").to_matchable(),
                    Ref::new("IfExistsGrammar").optional().to_matchable(),
                    Ref::new("TableReferenceSegment").to_matchable(),
                    one_of(vec![
                        Sequence::new(vec![
                            Ref::keyword("RENAME").to_matchable(),
                            Ref::keyword("TO").to_matchable(),
                            Ref::new("TableReferenceSegment").to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("COMMENT").to_matchable(),
                            Ref::new("EqualsSegment").to_matchable(),
                            Ref::new("QuotedLiteralSegment").to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("UNSET").to_matchable(),
                            Ref::keyword("COMMENT").to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            one_of(vec![
                                Ref::keyword("SET").to_matchable(),
                                Ref::keyword("UNSET").to_matchable(),
                            ])
                            .to_matchable(),
                            Ref::keyword("SECURE").to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("SET").to_matchable(),
                            Ref::new("TagEqualsSegment").to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("UNSET").to_matchable(),
                            Ref::keyword("TAG").to_matchable(),
                            Delimited::new(vec![Ref::new("TagReferenceSegment").to_matchable()])
                                .to_matchable(),
                        ])
                        .to_matchable(),
                        Delimited::new(vec![
                            Sequence::new(vec![
                                Ref::keyword("ADD").to_matchable(),
                                Ref::keyword("ROW").to_matchable(),
                                Ref::keyword("ACCESS").to_matchable(),
                                Ref::keyword("POLICY").to_matchable(),
                                Ref::new("FunctionNameSegment").to_matchable(),
                                Ref::keyword("ON").to_matchable(),
                                Bracketed::new(vec![
                                    Delimited::new(vec![
                                        Ref::new("ColumnReferenceSegment").to_matchable(),
                                    ])
                                    .to_matchable(),
                                ])
                                .to_matchable(),
                            ])
                            .to_matchable(),
                            Sequence::new(vec![
                                Ref::keyword("DROP").to_matchable(),
                                Ref::keyword("ROW").to_matchable(),
                                Ref::keyword("ACCESS").to_matchable(),
                                Ref::keyword("POLICY").to_matchable(),
                                Ref::new("FunctionNameSegment").to_matchable(),
                            ])
                            .to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            one_of(vec![
                                Ref::keyword("ALTER").to_matchable(),
                                Ref::keyword("MODIFY").to_matchable(),
                            ])
                            .to_matchable(),
                            one_of(vec![
                                Delimited::new(vec![
                                    Sequence::new(vec![
                                        Ref::keyword("COLUMN").optional().to_matchable(),
                                        Ref::new("ColumnReferenceSegment").to_matchable(),
                                        one_of(vec![
                                            Sequence::new(vec![
                                                Ref::keyword("SET").to_matchable(),
                                                Ref::keyword("MASKING").to_matchable(),
                                                Ref::keyword("POLICY").to_matchable(),
                                                Ref::new("FunctionNameSegment").to_matchable(),
                                                Sequence::new(vec![
                                                    Ref::keyword("USING").to_matchable(),
                                                    Bracketed::new(vec![
                                                        Delimited::new(vec![
                                                            Ref::new("ColumnReferenceSegment")
                                                                .to_matchable(),
                                                        ])
                                                        .to_matchable(),
                                                    ])
                                                    .config(|this| this.optional())
                                                    .to_matchable(),
                                                ])
                                                .config(|this| this.optional())
                                                .to_matchable(),
                                            ])
                                            .to_matchable(),
                                            Sequence::new(vec![
                                                Ref::keyword("UNSET").to_matchable(),
                                                Ref::keyword("MASKING").to_matchable(),
                                                Ref::keyword("POLICY").to_matchable(),
                                            ])
                                            .to_matchable(),
                                            Sequence::new(vec![
                                                Ref::keyword("SET").to_matchable(),
                                                Ref::new("TagEqualsSegment").to_matchable(),
                                            ])
                                            .to_matchable(),
                                        ])
                                        .to_matchable(),
                                    ])
                                    .to_matchable(),
                                    Sequence::new(vec![
                                        Ref::keyword("COLUMN").to_matchable(),
                                        Ref::new("ColumnReferenceSegment").to_matchable(),
                                        Ref::keyword("UNSET").to_matchable(),
                                        Ref::keyword("TAG").to_matchable(),
                                        Delimited::new(vec![
                                            Ref::new("TagReferenceSegment").to_matchable(),
                                        ])
                                        .to_matchable(),
                                    ])
                                    .to_matchable(),
                                ])
                                .to_matchable(),
                            ])
                            .to_matchable(),
                        ])
                        .to_matchable(),
                    ])
                    .to_matchable(),
                ])
                .to_matchable()
            })
            .to_matchable()
            .into(),
        ),
        (
            "AlterMaterializedViewStatementSegment".into(),
            NodeMatcher::new(SyntaxKind::AlterMaterializedViewStatement, |_| {
                Sequence::new(vec![
                    Ref::keyword("ALTER").to_matchable(),
                    Ref::keyword("MATERIALIZED").to_matchable(),
                    Ref::keyword("VIEW").to_matchable(),
                    Ref::new("TableReferenceSegment").to_matchable(),
                    one_of(vec![
                        Sequence::new(vec![
                            Ref::keyword("RENAME").to_matchable(),
                            Ref::keyword("TO").to_matchable(),
                            Ref::new("TableReferenceSegment").to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("CLUSTER").to_matchable(),
                            Ref::keyword("BY").to_matchable(),
                            Delimited::new(vec![Ref::new("ExpressionSegment").to_matchable()])
                                .to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("DROP").to_matchable(),
                            Ref::keyword("CLUSTERING").to_matchable(),
                            Ref::keyword("KEY").to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("SUSPEND").to_matchable(),
                            Ref::keyword("RECLUSTER").to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("RESUME").to_matchable(),
                            Ref::keyword("RECLUSTER").to_matchable(),
                        ])
                        .to_matchable(),
                        Ref::keyword("SUSPEND").to_matchable(),
                        Ref::keyword("RESUME").to_matchable(),
                        Sequence::new(vec![
                            one_of(vec![
                                Ref::keyword("SET").to_matchable(),
                                Ref::keyword("UNSET").to_matchable(),
                            ])
                            .to_matchable(),
                            one_of(vec![
                                Ref::keyword("SECURE").to_matchable(),
                                Ref::new("CommentEqualsClauseSegment").to_matchable(),
                                Ref::new("TagEqualsSegment").to_matchable(),
                            ])
                            .to_matchable(),
                        ])
                        .to_matchable(),
                    ])
                    .to_matchable(),
                ])
                .to_matchable()
            })
            .to_matchable()
            .into(),
        ),
        (
            "CreateFileFormatSegment".into(),
            NodeMatcher::new(SyntaxKind::CreateFileFormatSegment, |_| {
                Sequence::new(vec![
                    Ref::keyword("CREATE").to_matchable(),
                    Ref::new("OrReplaceGrammar").optional().to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("FILE").to_matchable(),
                        Ref::keyword("FORMAT").to_matchable(),
                    ])
                    .to_matchable(),
                    Ref::new("IfNotExistsGrammar").optional().to_matchable(),
                    Ref::new("ObjectReferenceSegment").to_matchable(),
                    one_of(vec![
                        Ref::new("CsvFileFormatTypeParameters").to_matchable(),
                        Ref::new("JsonFileFormatTypeParameters").to_matchable(),
                        Ref::new("AvroFileFormatTypeParameters").to_matchable(),
                        Ref::new("OrcFileFormatTypeParameters").to_matchable(),
                        Ref::new("ParquetFileFormatTypeParameters").to_matchable(),
                        Ref::new("XmlFileFormatTypeParameters").to_matchable(),
                    ])
                    .to_matchable(),
                    Sequence::new(vec![
                        Ref::new("CommaSegment").optional().to_matchable(),
                        Ref::new("CommentEqualsClauseSegment").to_matchable(),
                    ])
                    .config(|this| this.optional())
                    .to_matchable(),
                ])
                .to_matchable()
            })
            .to_matchable()
            .into(),
        ),
        (
            "AlterFileFormatSegment".into(),
            NodeMatcher::new(SyntaxKind::AlterFileFormatSegment, |_| {
                Sequence::new(vec![
                    Ref::keyword("ALTER").to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("FILE").to_matchable(),
                        Ref::keyword("FORMAT").to_matchable(),
                    ])
                    .to_matchable(),
                    Ref::new("IfExistsGrammar").optional().to_matchable(),
                    Ref::new("ObjectReferenceSegment").to_matchable(),
                    one_of(vec![
                        Sequence::new(vec![
                            Ref::keyword("RENAME").to_matchable(),
                            Ref::keyword("TO").to_matchable(),
                            Ref::new("ObjectReferenceSegment").to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("SET").to_matchable(),
                            one_of(vec![
                                Ref::new("CsvFileFormatTypeParameters").to_matchable(),
                                Ref::new("JsonFileFormatTypeParameters").to_matchable(),
                                Ref::new("AvroFileFormatTypeParameters").to_matchable(),
                                Ref::new("OrcFileFormatTypeParameters").to_matchable(),
                                Ref::new("ParquetFileFormatTypeParameters").to_matchable(),
                                Ref::new("XmlFileFormatTypeParameters").to_matchable(),
                            ])
                            .to_matchable(),
                        ])
                        .to_matchable(),
                    ])
                    .to_matchable(),
                    Sequence::new(vec![
                        Ref::new("CommaSegment").optional().to_matchable(),
                        Ref::new("CommentEqualsClauseSegment").to_matchable(),
                    ])
                    .config(|this| this.optional())
                    .to_matchable(),
                ])
                .to_matchable()
            })
            .to_matchable()
            .into(),
        ),
        (
            "CsvFileFormatTypeParameters".into(),
            NodeMatcher::new(SyntaxKind::CsvFileFormatTypeParameters, |_| {
                let file_format_type_parameter = one_of(vec![
                    Sequence::new(vec![
                        Ref::keyword("TYPE").to_matchable(),
                        Ref::new("EqualsSegment").to_matchable(),
                        one_of(vec![
                            StringParser::new("'CSV'", SyntaxKind::FileType).to_matchable(),
                            StringParser::new("CSV", SyntaxKind::FileType).to_matchable(),
                        ])
                        .to_matchable(),
                    ])
                    .to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("COMPRESSION").to_matchable(),
                        Ref::new("EqualsSegment").to_matchable(),
                        Ref::new("CompressionType").to_matchable(),
                    ])
                    .to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("FILE_EXTENSION").to_matchable(),
                        Ref::new("EqualsSegment").to_matchable(),
                        Ref::new("QuotedLiteralSegment").to_matchable(),
                    ])
                    .to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("SKIP_HEADER").to_matchable(),
                        Ref::new("EqualsSegment").to_matchable(),
                        Ref::new("IntegerSegment").to_matchable(),
                    ])
                    .to_matchable(),
                    Sequence::new(vec![
                        one_of(vec![
                            Ref::keyword("DATE_FORMAT").to_matchable(),
                            Ref::keyword("TIME_FORMAT").to_matchable(),
                            Ref::keyword("TIMESTAMP_FORMAT").to_matchable(),
                        ])
                        .to_matchable(),
                        Ref::new("EqualsSegment").to_matchable(),
                        one_of(vec![
                            Ref::keyword("AUTO").to_matchable(),
                            Ref::new("QuotedLiteralSegment").to_matchable(),
                        ])
                        .to_matchable(),
                    ])
                    .to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("BINARY_FORMAT").to_matchable(),
                        Ref::new("EqualsSegment").to_matchable(),
                        one_of(vec![
                            Ref::keyword("HEX").to_matchable(),
                            Ref::keyword("BASE64").to_matchable(),
                            Ref::keyword("UTF8").to_matchable(),
                        ])
                        .to_matchable(),
                    ])
                    .to_matchable(),
                    Sequence::new(vec![
                        one_of(vec![
                            Ref::keyword("RECORD_DELIMITER").to_matchable(),
                            Ref::keyword("FIELD_DELIMITER").to_matchable(),
                            Ref::keyword("ESCAPE").to_matchable(),
                            Ref::keyword("ESCAPE_UNENCLOSED_FIELD").to_matchable(),
                            Ref::keyword("FIELD_OPTIONALLY_ENCLOSED_BY").to_matchable(),
                        ])
                        .to_matchable(),
                        Ref::new("EqualsSegment").to_matchable(),
                        one_of(vec![
                            Ref::keyword("NONE").to_matchable(),
                            Ref::new("QuotedLiteralSegment").to_matchable(),
                        ])
                        .to_matchable(),
                    ])
                    .to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("NULL_IF").to_matchable(),
                        Ref::new("EqualsSegment").to_matchable(),
                        Bracketed::new(vec![
                            Delimited::new(vec![Ref::new("QuotedLiteralSegment").to_matchable()])
                                .config(|this| this.optional())
                                .to_matchable(),
                        ])
                        .to_matchable(),
                    ])
                    .to_matchable(),
                    Sequence::new(vec![
                        one_of(vec![
                            Ref::keyword("SKIP_BLANK_LINES").to_matchable(),
                            Ref::keyword("ERROR_ON_COLUMN_COUNT_MISMATCH").to_matchable(),
                            Ref::keyword("REPLACE_INVALID_CHARACTERS").to_matchable(),
                            Ref::keyword("VALIDATE_UTF8").to_matchable(),
                            Ref::keyword("EMPTY_FIELD_AS_NULL").to_matchable(),
                            Ref::keyword("SKIP_BYTE_ORDER_MARK").to_matchable(),
                            Ref::keyword("TRIM_SPACE").to_matchable(),
                        ])
                        .to_matchable(),
                        Ref::new("EqualsSegment").to_matchable(),
                        Ref::new("BooleanLiteralGrammar").to_matchable(),
                    ])
                    .to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("ENCODING").to_matchable(),
                        Ref::new("EqualsSegment").to_matchable(),
                        one_of(vec![
                            Ref::keyword("UTF8").to_matchable(),
                            Ref::new("QuotedLiteralSegment").to_matchable(),
                        ])
                        .to_matchable(),
                    ])
                    .to_matchable(),
                ]);

                one_of(vec![
                    Delimited::new(vec![file_format_type_parameter.clone().to_matchable()])
                        .to_matchable(),
                    AnyNumberOf::new(vec![file_format_type_parameter.to_matchable()])
                        .to_matchable(),
                ])
                .to_matchable()
            })
            .to_matchable()
            .into(),
        ),
        (
            "JsonFileFormatTypeParameters".into(),
            NodeMatcher::new(SyntaxKind::JsonFileFormatTypeParameters, |_| {
                let file_format_type_parameter = one_of(vec![
                    Sequence::new(vec![
                        Ref::keyword("TYPE").to_matchable(),
                        Ref::new("EqualsSegment").to_matchable(),
                        one_of(vec![
                            StringParser::new("'JSON'", SyntaxKind::FileType).to_matchable(),
                            StringParser::new("JSON", SyntaxKind::FileType).to_matchable(),
                        ])
                        .to_matchable(),
                    ])
                    .to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("COMPRESSION").to_matchable(),
                        Ref::new("EqualsSegment").to_matchable(),
                        Ref::new("CompressionType").to_matchable(),
                    ])
                    .to_matchable(),
                    Sequence::new(vec![
                        one_of(vec![
                            Ref::keyword("DATE_FORMAT").to_matchable(),
                            Ref::keyword("TIME_FORMAT").to_matchable(),
                            Ref::keyword("TIMESTAMP_FORMAT").to_matchable(),
                        ])
                        .to_matchable(),
                        Ref::new("EqualsSegment").to_matchable(),
                        one_of(vec![
                            Ref::new("QuotedLiteralSegment").to_matchable(),
                            Ref::keyword("AUTO").to_matchable(),
                        ])
                        .to_matchable(),
                    ])
                    .to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("BINARY_FORMAT").to_matchable(),
                        Ref::new("EqualsSegment").to_matchable(),
                        one_of(vec![
                            Ref::keyword("HEX").to_matchable(),
                            Ref::keyword("BASE64").to_matchable(),
                            Ref::keyword("UTF8").to_matchable(),
                        ])
                        .to_matchable(),
                    ])
                    .to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("NULL_IF").to_matchable(),
                        Ref::new("EqualsSegment").to_matchable(),
                        Bracketed::new(vec![
                            Delimited::new(vec![Ref::new("QuotedLiteralSegment").to_matchable()])
                                .config(|this| this.optional())
                                .to_matchable(),
                        ])
                        .to_matchable(),
                    ])
                    .to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("FILE_EXTENSION").to_matchable(),
                        Ref::new("EqualsSegment").to_matchable(),
                        Ref::new("QuotedLiteralSegment").to_matchable(),
                    ])
                    .to_matchable(),
                    Sequence::new(vec![
                        one_of(vec![
                            Ref::keyword("TRIM_SPACE").to_matchable(),
                            Ref::keyword("ENABLE_OCTAL").to_matchable(),
                            Ref::keyword("ALLOW_DUPLICATE").to_matchable(),
                            Ref::keyword("STRIP_OUTER_ARRAY").to_matchable(),
                            Ref::keyword("STRIP_NULL_VALUES").to_matchable(),
                            Ref::keyword("REPLACE_INVALID_CHARACTERS").to_matchable(),
                            Ref::keyword("IGNORE_UTF8_ERRORS").to_matchable(),
                            Ref::keyword("SKIP_BYTE_ORDER_MARK").to_matchable(),
                        ])
                        .to_matchable(),
                        Ref::new("EqualsSegment").to_matchable(),
                        Ref::new("BooleanLiteralGrammar").to_matchable(),
                    ])
                    .to_matchable(),
                ]);

                one_of(vec![
                    Delimited::new(vec![file_format_type_parameter.clone().to_matchable()])
                        .to_matchable(),
                    AnyNumberOf::new(vec![file_format_type_parameter.to_matchable()])
                        .to_matchable(),
                ])
                .to_matchable()
            })
            .to_matchable()
            .into(),
        ),
        (
            "AvroFileFormatTypeParameters".into(),
            NodeMatcher::new(SyntaxKind::AvroFileFormatTypeParameters, |_| {
                let file_format_type_parameter = one_of(vec![
                    Sequence::new(vec![
                        Ref::keyword("TYPE").to_matchable(),
                        Ref::new("EqualsSegment").to_matchable(),
                        one_of(vec![
                            StringParser::new("'AVRO'", SyntaxKind::FileType).to_matchable(),
                            StringParser::new("AVRO", SyntaxKind::FileType).to_matchable(),
                        ])
                        .to_matchable(),
                    ])
                    .to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("COMPRESSION").to_matchable(),
                        Ref::new("EqualsSegment").to_matchable(),
                        Ref::new("CompressionType").to_matchable(),
                    ])
                    .to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("TRIM_SPACE").to_matchable(),
                        Ref::new("EqualsSegment").to_matchable(),
                        Ref::new("BooleanLiteralGrammar").to_matchable(),
                    ])
                    .to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("NULL_IF").to_matchable(),
                        Ref::new("EqualsSegment").to_matchable(),
                        Bracketed::new(vec![
                            Delimited::new(vec![Ref::new("QuotedLiteralSegment").to_matchable()])
                                .config(|this| this.optional())
                                .to_matchable(),
                        ])
                        .to_matchable(),
                    ])
                    .to_matchable(),
                ]);

                one_of(vec![
                    Delimited::new(vec![file_format_type_parameter.clone().to_matchable()])
                        .to_matchable(),
                    AnyNumberOf::new(vec![file_format_type_parameter.to_matchable()])
                        .to_matchable(),
                ])
                .to_matchable()
            })
            .to_matchable()
            .into(),
        ),
        (
            "OrcFileFormatTypeParameters".into(),
            NodeMatcher::new(SyntaxKind::OrcFileFormatTypeParameters, |_| {
                let file_format_type_parameter = one_of(vec![
                    Sequence::new(vec![
                        Ref::keyword("TYPE").to_matchable(),
                        Ref::new("EqualsSegment").to_matchable(),
                        one_of(vec![
                            StringParser::new("'ORC'", SyntaxKind::FileType).to_matchable(),
                            StringParser::new("ORC", SyntaxKind::FileType).to_matchable(),
                        ])
                        .to_matchable(),
                    ])
                    .to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("TRIM_SPACE").to_matchable(),
                        Ref::new("EqualsSegment").to_matchable(),
                        Ref::new("BooleanLiteralGrammar").to_matchable(),
                    ])
                    .to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("NULL_IF").to_matchable(),
                        Ref::new("EqualsSegment").to_matchable(),
                        Bracketed::new(vec![
                            Delimited::new(vec![Ref::new("QuotedLiteralSegment").to_matchable()])
                                .config(|this| this.optional())
                                .to_matchable(),
                        ])
                        .to_matchable(),
                    ])
                    .to_matchable(),
                ]);

                one_of(vec![
                    Delimited::new(vec![file_format_type_parameter.clone().to_matchable()])
                        .to_matchable(),
                    AnyNumberOf::new(vec![file_format_type_parameter.to_matchable()])
                        .to_matchable(),
                ])
                .to_matchable()
            })
            .to_matchable()
            .into(),
        ),
        (
            "ParquetFileFormatTypeParameters".into(),
            NodeMatcher::new(SyntaxKind::ParquetFileFormatTypeParameters, |_| {
                let file_format_type_parameter = one_of(vec![
                    Sequence::new(vec![
                        Ref::keyword("TYPE").to_matchable(),
                        Ref::new("EqualsSegment").to_matchable(),
                        one_of(vec![
                            StringParser::new("'PARQUET'", SyntaxKind::FileType).to_matchable(),
                            StringParser::new("PARQUET", SyntaxKind::FileType).to_matchable(),
                        ])
                        .to_matchable(),
                    ])
                    .to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("COMPRESSION").to_matchable(),
                        Ref::new("EqualsSegment").to_matchable(),
                        Ref::new("CompressionType").to_matchable(),
                    ])
                    .to_matchable(),
                    Sequence::new(vec![
                        one_of(vec![
                            Ref::keyword("SNAPPY_COMPRESSION").to_matchable(),
                            Ref::keyword("BINARY_AS_TEXT").to_matchable(),
                            Ref::keyword("TRIM_SPACE").to_matchable(),
                        ])
                        .to_matchable(),
                        Ref::new("EqualsSegment").to_matchable(),
                        Ref::new("BooleanLiteralGrammar").to_matchable(),
                    ])
                    .to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("NULL_IF").to_matchable(),
                        Ref::new("EqualsSegment").to_matchable(),
                        Bracketed::new(vec![
                            Delimited::new(vec![Ref::new("QuotedLiteralSegment").to_matchable()])
                                .config(|this| this.optional())
                                .to_matchable(),
                        ])
                        .to_matchable(),
                    ])
                    .to_matchable(),
                ]);

                one_of(vec![
                    Delimited::new(vec![file_format_type_parameter.clone().to_matchable()])
                        .to_matchable(),
                    AnyNumberOf::new(vec![file_format_type_parameter.to_matchable()])
                        .to_matchable(),
                ])
                .to_matchable()
            })
            .to_matchable()
            .into(),
        ),
        (
            "XmlFileFormatTypeParameters".into(),
            NodeMatcher::new(SyntaxKind::XmlFileFormatTypeParameters, |_| {
                let file_format_type_parameter = one_of(vec![
                    Sequence::new(vec![
                        Ref::keyword("TYPE").to_matchable(),
                        Ref::new("EqualsSegment").to_matchable(),
                        one_of(vec![
                            StringParser::new("'XML'", SyntaxKind::FileType).to_matchable(),
                            StringParser::new("XML", SyntaxKind::FileType).to_matchable(),
                        ])
                        .to_matchable(),
                    ])
                    .to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("COMPRESSION").to_matchable(),
                        Ref::new("EqualsSegment").to_matchable(),
                        Ref::new("CompressionType").to_matchable(),
                    ])
                    .to_matchable(),
                    Sequence::new(vec![
                        one_of(vec![
                            Ref::keyword("IGNORE_UTF8_ERRORS").to_matchable(),
                            Ref::keyword("PRESERVE_SPACE").to_matchable(),
                            Ref::keyword("STRIP_OUTER_ELEMENT").to_matchable(),
                            Ref::keyword("DISABLE_SNOWFLAKE_DATA").to_matchable(),
                            Ref::keyword("DISABLE_AUTO_CONVERT").to_matchable(),
                            Ref::keyword("SKIP_BYTE_ORDER_MARK").to_matchable(),
                        ])
                        .to_matchable(),
                        Ref::new("EqualsSegment").to_matchable(),
                        Ref::new("BooleanLiteralGrammar").to_matchable(),
                    ])
                    .to_matchable(),
                ]);

                one_of(vec![
                    Delimited::new(vec![file_format_type_parameter.clone().to_matchable()])
                        .to_matchable(),
                    AnyNumberOf::new(vec![file_format_type_parameter.to_matchable()])
                        .to_matchable(),
                ])
                .to_matchable()
            })
            .to_matchable()
            .into(),
        ),
        (
            "AlterPipeSegment".into(),
            NodeMatcher::new(SyntaxKind::AlterPipeSegment, |_| {
                Sequence::new(vec![
                    Ref::keyword("ALTER").to_matchable(),
                    Ref::keyword("PIPE").to_matchable(),
                    Ref::new("IfExistsGrammar").optional().to_matchable(),
                    Ref::new("ObjectReferenceSegment").to_matchable(),
                    one_of(vec![
                        Sequence::new(vec![
                            Ref::keyword("SET").to_matchable(),
                            AnyNumberOf::new(vec![
                                Sequence::new(vec![
                                    Ref::keyword("PIPE_EXECUTION_PAUSED").to_matchable(),
                                    Ref::new("EqualsSegment").to_matchable(),
                                    Ref::new("BooleanLiteralGrammar").to_matchable(),
                                ])
                                .to_matchable(),
                                Ref::new("CommentEqualsClauseSegment").to_matchable(),
                            ])
                            .to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("UNSET").to_matchable(),
                            one_of(vec![
                                Ref::keyword("PIPE_EXECUTION_PAUSED").to_matchable(),
                                Ref::keyword("COMMENT").to_matchable(),
                            ])
                            .to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("SET").to_matchable(),
                            Ref::new("TagEqualsSegment").to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("UNSET").to_matchable(),
                            Sequence::new(vec![
                                Ref::keyword("TAG").to_matchable(),
                                Delimited::new(vec![
                                    Ref::new("TagReferenceSegment").to_matchable(),
                                ])
                                .to_matchable(),
                            ])
                            .to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("REFRESH").to_matchable(),
                            Sequence::new(vec![
                                Ref::keyword("PREFIX").to_matchable(),
                                Ref::new("EqualsSegment").to_matchable(),
                                Ref::new("QuotedLiteralSegment").to_matchable(),
                            ])
                            .config(|this| this.optional())
                            .to_matchable(),
                            Sequence::new(vec![
                                Ref::keyword("MODIFIED_AFTER").to_matchable(),
                                Ref::new("EqualsSegment").to_matchable(),
                                Ref::new("QuotedLiteralSegment").to_matchable(),
                            ])
                            .config(|this| this.optional())
                            .to_matchable(),
                        ])
                        .to_matchable(),
                    ])
                    .to_matchable(),
                    Ref::new("CommaSegment").optional().to_matchable(),
                ])
                .to_matchable()
            })
            .to_matchable()
            .into(),
        ),
        (
            "FileFormatSegment".into(),
            NodeMatcher::new(SyntaxKind::FileFormatSegment, |_| {
                one_of(vec![
                    one_of(vec![
                        Ref::new("QuotedLiteralSegment").to_matchable(),
                        Ref::new("ObjectReferenceSegment").to_matchable(),
                    ])
                    .to_matchable(),
                    Bracketed::new(vec![
                        Sequence::new(vec![
                            one_of(vec![
                                Sequence::new(vec![
                                    Ref::keyword("FORMAT_NAME").to_matchable(),
                                    Ref::new("EqualsSegment").to_matchable(),
                                    one_of(vec![
                                        Ref::new("QuotedLiteralSegment").to_matchable(),
                                        Ref::new("ObjectReferenceSegment").to_matchable(),
                                    ])
                                    .to_matchable(),
                                ])
                                .to_matchable(),
                                one_of(vec![
                                    Ref::new("CsvFileFormatTypeParameters").to_matchable(),
                                    Ref::new("JsonFileFormatTypeParameters").to_matchable(),
                                    Ref::new("AvroFileFormatTypeParameters").to_matchable(),
                                    Ref::new("OrcFileFormatTypeParameters").to_matchable(),
                                    Ref::new("ParquetFileFormatTypeParameters").to_matchable(),
                                    Ref::new("XmlFileFormatTypeParameters").to_matchable(),
                                ])
                                .to_matchable(),
                            ])
                            .to_matchable(),
                            Ref::new("FormatTypeOptions").optional().to_matchable(),
                        ])
                        .to_matchable(),
                    ])
                    .to_matchable(),
                ])
                .to_matchable()
            })
            .to_matchable()
            .into(),
        ),
        (
            "FormatTypeOptions".into(),
            NodeMatcher::new(SyntaxKind::FormatTypeOptions, |_| {
                one_of(vec![
                    // COPY INTO <location>, open for extension
                    any_set_of(vec![
                        Sequence::new(vec![
                            Ref::keyword("COMPRESSION").to_matchable(),
                            Ref::new("EqualsSegment").to_matchable(),
                            Ref::new("CompressionType").to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("RECORD_DELIMITER").to_matchable(),
                            Ref::new("EqualsSegment").to_matchable(),
                            one_of(vec![
                                Ref::keyword("NONE").to_matchable(),
                                Ref::new("QuotedLiteralSegment").to_matchable(),
                            ])
                            .to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("FIELD_DELIMITER").to_matchable(),
                            Ref::new("EqualsSegment").to_matchable(),
                            one_of(vec![
                                Ref::keyword("NONE").to_matchable(),
                                Ref::new("QuotedLiteralSegment").to_matchable(),
                            ])
                            .to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("ESCAPE").to_matchable(),
                            Ref::new("EqualsSegment").to_matchable(),
                            one_of(vec![
                                Ref::keyword("NONE").to_matchable(),
                                Ref::new("QuotedLiteralSegment").to_matchable(),
                            ])
                            .to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("ESCAPE_UNENCLOSED_FIELD").to_matchable(),
                            Ref::new("EqualsSegment").to_matchable(),
                            one_of(vec![
                                Ref::keyword("NONE").to_matchable(),
                                Ref::new("QuotedLiteralSegment").to_matchable(),
                            ])
                            .to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("DATA_FORMAT").to_matchable(),
                            Ref::new("EqualsSegment").to_matchable(),
                            one_of(vec![
                                Ref::keyword("AUTO").to_matchable(),
                                Ref::new("QuotedLiteralSegment").to_matchable(),
                            ])
                            .to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("TIME_FORMAT").to_matchable(),
                            Ref::new("EqualsSegment").to_matchable(),
                            one_of(vec![
                                Ref::keyword("NONE").to_matchable(),
                                Ref::new("QuotedLiteralSegment").to_matchable(),
                            ])
                            .to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("TIMESTAMP_FORMAT").to_matchable(),
                            Ref::new("EqualsSegment").to_matchable(),
                            one_of(vec![
                                Ref::keyword("NONE").to_matchable(),
                                Ref::new("QuotedLiteralSegment").to_matchable(),
                            ])
                            .to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("BINARY_FORMAT").to_matchable(),
                            Ref::new("EqualsSegment").to_matchable(),
                            one_of(vec![
                                Ref::keyword("HEX").to_matchable(),
                                Ref::keyword("BASE64").to_matchable(),
                                Ref::keyword("UTF8").to_matchable(),
                            ])
                            .to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("FIELD_OPTIONALITY_ENCLOSED_BY").to_matchable(),
                            Ref::new("EqualsSegment").to_matchable(),
                            one_of(vec![
                                Ref::keyword("NONE").to_matchable(),
                                Ref::new("QuotedLiteralSegment").to_matchable(),
                            ])
                            .to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("NULL_IF").to_matchable(),
                            Ref::new("EqualsSegment").to_matchable(),
                            Bracketed::new(vec![
                                Delimited::new(vec![
                                    Ref::new("QuotedLiteralSegment").to_matchable(),
                                ])
                                .config(|this| this.optional())
                                .to_matchable(),
                            ])
                            .to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("EMPTY_FIELD_AS_NULL").to_matchable(),
                            Ref::new("EqualsSegment").to_matchable(),
                            Ref::new("BooleanLiteralGrammar").to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("SNAPPY_COMPRESSION").to_matchable(),
                            Ref::new("EqualsSegment").to_matchable(),
                            Ref::new("BooleanLiteralGrammar").to_matchable(),
                        ])
                        .to_matchable(),
                    ])
                    .to_matchable(),
                    // COPY INTO <table>, open for extension
                    any_set_of(vec![]).to_matchable(),
                ])
                .to_matchable()
            })
            .to_matchable()
            .into(),
        ),
        (
            "CreateExternalTableSegment".into(),
            NodeMatcher::new(SyntaxKind::CreateExternalTableStatement, |_| {
                Sequence::new(vec![
                    Ref::keyword("CREATE").to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("OR").to_matchable(),
                        Ref::keyword("REPLACE").to_matchable(),
                    ])
                    .config(|this| this.optional())
                    .to_matchable(),
                    Ref::keyword("EXTERNAL").to_matchable(),
                    Ref::keyword("TABLE").to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("IF").to_matchable(),
                        Ref::keyword("NOT").to_matchable(),
                        Ref::keyword("EXISTS").to_matchable(),
                    ])
                    .config(|this| this.optional())
                    .to_matchable(),
                    Ref::new("TableReferenceSegment").to_matchable(),
                    Bracketed::new(vec![
                        Delimited::new(vec![
                            Sequence::new(vec![
                                Ref::new("SingleIdentifierGrammar").to_matchable(),
                                Ref::new("DatatypeSegment").to_matchable(),
                                Ref::keyword("AS").to_matchable(),
                                optionally_bracketed(vec![
                                    Sequence::new(vec![
                                        Ref::new("ExpressionSegment").to_matchable(),
                                        Ref::new("TableConstraintSegment")
                                            .optional()
                                            .to_matchable(),
                                        Sequence::new(vec![
                                            Ref::keyword("NOT").optional().to_matchable(),
                                            Ref::keyword("NULL").optional().to_matchable(),
                                        ])
                                        .config(|this| this.optional())
                                        .to_matchable(),
                                    ])
                                    .to_matchable(),
                                ])
                                .to_matchable(),
                            ])
                            .to_matchable(),
                        ])
                        .to_matchable(),
                    ])
                    .config(|this| this.optional())
                    .to_matchable(),
                    any_set_of(vec![
                        Sequence::new(vec![
                            Ref::keyword("INTEGRATION").to_matchable(),
                            Ref::new("EqualsSegment").to_matchable(),
                            Ref::new("QuotedLiteralSegment").to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("PARTITION").to_matchable(),
                            Ref::keyword("BY").to_matchable(),
                            Bracketed::new(vec![
                                Delimited::new(vec![
                                    Ref::new("SingleIdentifierGrammar").to_matchable(),
                                ])
                                .to_matchable(),
                            ])
                            .to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Sequence::new(vec![Ref::keyword("WITH").to_matchable()])
                                .config(|this| this.optional())
                                .to_matchable(),
                            Ref::keyword("LOCATION").to_matchable(),
                            Ref::new("EqualsSegment").to_matchable(),
                            Ref::new("StagePath").to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("REFRESH_ON_CREATE").to_matchable(),
                            Ref::new("EqualsSegment").to_matchable(),
                            Ref::new("BooleanLiteralGrammar").to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("AUTO_REFRESH").to_matchable(),
                            Ref::new("EqualsSegment").to_matchable(),
                            Ref::new("BooleanLiteralGrammar").to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("PATTERN").to_matchable(),
                            Ref::new("EqualsSegment").to_matchable(),
                            Ref::new("QuotedLiteralSegment").to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("FILE_FORMAT").to_matchable(),
                            Ref::new("EqualsSegment").to_matchable(),
                            Ref::new("FileFormatSegment").to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("AWS_SNS_TOPIC").to_matchable(),
                            Ref::new("EqualsSegment").to_matchable(),
                            Ref::new("QuotedLiteralSegment").to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("COPY").to_matchable(),
                            Ref::keyword("GRANTS").to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Sequence::new(vec![Ref::keyword("WITH").to_matchable()])
                                .config(|this| this.optional())
                                .to_matchable(),
                            Ref::keyword("ROW").to_matchable(),
                            Ref::keyword("ACCESS").to_matchable(),
                            Ref::keyword("POLICY").to_matchable(),
                            Ref::new("NakedIdentifierSegment").to_matchable(),
                        ])
                        .to_matchable(),
                        Ref::new("TagBracketedEqualsSegment").to_matchable(),
                        Ref::new("CommentEqualsClauseSegment").to_matchable(),
                    ])
                    .to_matchable(),
                ])
                .to_matchable()
            })
            .to_matchable()
            .into(),
        ),
    ]);

    snowflake_dialect.replace_grammar(
        "TableExpressionSegment",
        one_of(vec![
            Ref::new("BareFunctionSegment").to_matchable(),
            Ref::new("FunctionSegment").to_matchable(),
            Ref::new("TableReferenceSegment").to_matchable(),
            Bracketed::new(vec![Ref::new("SelectableGrammar").to_matchable()]).to_matchable(),
            Ref::new("ValuesClauseSegment").to_matchable(),
            Sequence::new(vec![
                Ref::new("StagePath").to_matchable(),
                Bracketed::new(vec![
                    Delimited::new(vec![
                        Sequence::new(vec![
                            Ref::keyword("FILE_FORMAT").to_matchable(),
                            Ref::new("ParameterAssignerSegment").to_matchable(),
                            Ref::new("FileFormatSegment").to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("PATTERN").to_matchable(),
                            Ref::new("ParameterAssignerSegment").to_matchable(),
                            Ref::new("QuotedLiteralSegment").to_matchable(),
                        ])
                        .to_matchable(),
                    ])
                    .to_matchable(),
                ])
                .config(|this| this.optional())
                .to_matchable(),
            ])
            .to_matchable(),
        ])
        .to_matchable(),
    );

    snowflake_dialect.add([
        (
            "PartitionBySegment".into(),
            NodeMatcher::new(SyntaxKind::PartitionBySegment, |_| {
                Sequence::new(vec![
                    Ref::keyword("PARTITION").to_matchable(),
                    Ref::keyword("BY").to_matchable(),
                    MetaSegment::indent().to_matchable(),
                    optionally_bracketed(vec![
                        Delimited::new(vec![Ref::new("ExpressionSegment").to_matchable()])
                            .to_matchable(),
                    ])
                    .to_matchable(),
                    MetaSegment::dedent().to_matchable(),
                ])
                .to_matchable()
            })
            .to_matchable()
            .into(),
        ),
        (
            "CopyIntoLocationStatementSegment".into(),
            NodeMatcher::new(SyntaxKind::CopyIntoLocationStatement, |_| {
                Sequence::new(vec![
                    Ref::keyword("COPY").to_matchable(),
                    Ref::keyword("INTO").to_matchable(),
                    Ref::new("StorageLocation").to_matchable(),
                    Bracketed::new(vec![
                        Delimited::new(vec![Ref::new("ColumnReferenceSegment").to_matchable()])
                            .to_matchable(),
                    ])
                    .config(|this| this.optional())
                    .to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("FROM").to_matchable(),
                        one_of(vec![
                            Ref::new("TableReferenceSegment").to_matchable(),
                            Bracketed::new(vec![Ref::new("SelectStatementSegment").to_matchable()])
                                .to_matchable(),
                        ])
                        .to_matchable(),
                    ])
                    .config(|this| this.optional())
                    .to_matchable(),
                    one_of(vec![
                        Ref::new("S3ExternalStageParameters").to_matchable(),
                        Ref::new("AzureBlobStorageExternalStageParameters").to_matchable(),
                    ])
                    .config(|this| this.optional())
                    .to_matchable(),
                    Ref::new("InternalStageParameters")
                        .optional()
                        .to_matchable(),
                    any_set_of(vec![
                        Ref::new("PartitionBySegment").to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("FILE_FORMAT").to_matchable(),
                            Ref::new("EqualsSegment").to_matchable(),
                            Ref::new("FileFormatSegment").to_matchable(),
                        ])
                        .to_matchable(),
                        Ref::new("CopyOptionsSegment").to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("VALIDATION_MODE").to_matchable(),
                            Ref::new("EqualsSegment").to_matchable(),
                            Ref::new("ValidationModeOptionSegment").to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("HEADER").to_matchable(),
                            Ref::new("EqualsSegment").to_matchable(),
                            Ref::new("BooleanLiteralGrammar").to_matchable(),
                        ])
                        .to_matchable(),
                    ])
                    .to_matchable(),
                ])
                .to_matchable()
            })
            .to_matchable()
            .into(),
        ),
        (
            "CopyIntoTableStatementSegment".into(),
            NodeMatcher::new(SyntaxKind::CopyIntoTableStatement, |_| {
                Sequence::new(vec![
                    Ref::keyword("COPY").to_matchable(),
                    Ref::keyword("INTO").to_matchable(),
                    Ref::new("TableReferenceSegment").to_matchable(),
                    Bracketed::new(vec![
                        Delimited::new(vec![Ref::new("ColumnReferenceSegment").to_matchable()])
                            .to_matchable(),
                    ])
                    .config(|this| this.optional())
                    .to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("FROM").to_matchable(),
                        one_of(vec![
                            Ref::new("StorageLocation").to_matchable(),
                            Bracketed::new(vec![Ref::new("SelectStatementSegment").to_matchable()])
                                .to_matchable(),
                        ])
                        .to_matchable(),
                    ])
                    .config(|this| this.optional())
                    .to_matchable(),
                    one_of(vec![
                        Ref::new("S3ExternalStageParameters").to_matchable(),
                        Ref::new("AzureBlobStorageExternalStageParameters").to_matchable(),
                    ])
                    .config(|this| this.optional())
                    .to_matchable(),
                    Ref::new("InternalStageParameters")
                        .optional()
                        .to_matchable(),
                    any_set_of(vec![
                        Sequence::new(vec![
                            Ref::keyword("FILES").to_matchable(),
                            Ref::new("EqualsSegment").to_matchable(),
                            Bracketed::new(vec![
                                Delimited::new(vec![
                                    Ref::new("QuotedLiteralSegment").to_matchable(),
                                ])
                                .to_matchable(),
                            ])
                            .to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("PATTERN").to_matchable(),
                            Ref::new("EqualsSegment").to_matchable(),
                            one_of(vec![
                                Ref::new("QuotedLiteralSegment").to_matchable(),
                                Ref::new("ReferencedVariableNameSegment").to_matchable(),
                            ])
                            .to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("FILE_FORMAT").to_matchable(),
                            Ref::new("EqualsSegment").to_matchable(),
                            Ref::new("FileFormatSegment").to_matchable(),
                        ])
                        .to_matchable(),
                        Ref::new("CopyOptionsSegment").to_matchable(),
                    ])
                    .to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("VALIDATION_MODE").to_matchable(),
                        Ref::new("EqualsSegment").to_matchable(),
                        Ref::new("ValidationModeOptionSegment").to_matchable(),
                    ])
                    .config(|this| this.optional())
                    .to_matchable(),
                ])
                .to_matchable()
            })
            .to_matchable()
            .into(),
        ),
        (
            "StorageLocation".into(),
            NodeMatcher::new(SyntaxKind::StorageLocation, |_| {
                one_of(vec![
                    Ref::new("StagePath").to_matchable(),
                    Ref::new("S3Path").to_matchable(),
                    Ref::new("GCSPath").to_matchable(),
                    Ref::new("AzureBlobStoragePath").to_matchable(),
                ])
                .to_matchable()
            })
            .to_matchable()
            .into(),
        ),
        (
            "InternalStageParameters".into(),
            NodeMatcher::new(SyntaxKind::StageParameters, |_| {
                Sequence::new(vec![
                    Sequence::new(vec![
                        Ref::keyword("ENCRYPTION").to_matchable(),
                        Ref::new("EqualsSegment").to_matchable(),
                        Bracketed::new(vec![
                            Ref::keyword("TYPE").to_matchable(),
                            Ref::new("EqualsSegment").to_matchable(),
                            Ref::new("SnowflakeEncryptionOption").to_matchable(),
                        ])
                        .to_matchable(),
                    ])
                    .config(|this| this.optional())
                    .to_matchable(),
                ])
                .to_matchable()
            })
            .to_matchable()
            .into(),
        ),
        (
            "S3ExternalStageParameters".into(),
            NodeMatcher::new(SyntaxKind::S3ExternalStageParameters, |_| {
                Sequence::new(vec![
                    one_of(vec![
                        Sequence::new(vec![
                            Ref::keyword("STORAGE_INTEGRATION").to_matchable(),
                            Ref::new("EqualsSegment").to_matchable(),
                            Ref::new("ObjectReferenceSegment").to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("CREDENTIALS").to_matchable(),
                            Ref::new("EqualsSegment").to_matchable(),
                            Bracketed::new(vec![
                                one_of(vec![
                                    Sequence::new(vec![
                                        Ref::keyword("AWS_KEY_ID").to_matchable(),
                                        Ref::new("EqualsSegment").to_matchable(),
                                        Ref::new("QuotedLiteralSegment").to_matchable(),
                                        Ref::keyword("AWS_SECRET_KEY").to_matchable(),
                                        Ref::new("EqualsSegment").to_matchable(),
                                        Ref::new("QuotedLiteralSegment").to_matchable(),
                                        Sequence::new(vec![
                                            Ref::keyword("AWS_TOKEN").to_matchable(),
                                            Ref::new("EqualsSegment").to_matchable(),
                                            Ref::new("QuotedLiteralSegment").to_matchable(),
                                        ])
                                        .config(|this| this.optional())
                                        .to_matchable(),
                                    ])
                                    .to_matchable(),
                                    Sequence::new(vec![
                                        Ref::keyword("AWS_ROLE").to_matchable(),
                                        Ref::new("EqualsSegment").to_matchable(),
                                        Ref::new("QuotedLiteralSegment").to_matchable(),
                                    ])
                                    .to_matchable(),
                                ])
                                .to_matchable(),
                            ])
                            .to_matchable(),
                        ])
                        .to_matchable(),
                    ])
                    .config(|this| this.optional())
                    .to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("ENCRYPTION").to_matchable(),
                        Ref::new("EqualsSegment").to_matchable(),
                        Bracketed::new(vec![
                            one_of(vec![
                                Sequence::new(vec![
                                    Sequence::new(vec![
                                        Ref::keyword("TYPE").to_matchable(),
                                        Ref::new("EqualsSegment").to_matchable(),
                                        Ref::new("S3EncryptionOption").to_matchable(),
                                    ])
                                    .config(|this| this.optional())
                                    .to_matchable(),
                                    Ref::keyword("MASTER_KEY").to_matchable(),
                                    Ref::new("EqualsSegment").to_matchable(),
                                    Ref::new("QuotedLiteralSegment").to_matchable(),
                                ])
                                .to_matchable(),
                                Sequence::new(vec![
                                    Ref::keyword("TYPE").to_matchable(),
                                    Ref::new("EqualsSegment").to_matchable(),
                                    Ref::new("S3EncryptionOption").to_matchable(),
                                ])
                                .to_matchable(),
                                Sequence::new(vec![
                                    Ref::keyword("TYPE").to_matchable(),
                                    Ref::new("EqualsSegment").to_matchable(),
                                    Ref::new("S3EncryptionOption").to_matchable(),
                                    Sequence::new(vec![
                                        Ref::keyword("KMS_KEY_ID").to_matchable(),
                                        Ref::new("EqualsSegment").to_matchable(),
                                        Ref::new("QuotedLiteralSegment").to_matchable(),
                                    ])
                                    .config(|this| this.optional())
                                    .to_matchable(),
                                ])
                                .to_matchable(),
                                Sequence::new(vec![
                                    Ref::keyword("TYPE").to_matchable(),
                                    Ref::new("EqualsSegment").to_matchable(),
                                    Ref::keyword("NONE").to_matchable(),
                                ])
                                .to_matchable(),
                            ])
                            .to_matchable(),
                        ])
                        .to_matchable(),
                    ])
                    .config(|this| this.optional())
                    .to_matchable(),
                ])
                .to_matchable()
            })
            .to_matchable()
            .into(),
        ),
        (
            "GCSExternalStageParameters".into(),
            NodeMatcher::new(SyntaxKind::GcsExternalStageParameters, |_| {
                Sequence::new(vec![
                    Sequence::new(vec![
                        Ref::keyword("STORAGE_INTEGRATION").to_matchable(),
                        Ref::new("EqualsSegment").to_matchable(),
                        Ref::new("ObjectReferenceSegment").to_matchable(),
                    ])
                    .config(|this| this.optional())
                    .to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("ENCRYPTION").to_matchable(),
                        Ref::new("EqualsSegment").to_matchable(),
                        Bracketed::new(vec![
                            Sequence::new(vec![
                                Ref::keyword("TYPE").to_matchable(),
                                Ref::new("EqualsSegment").to_matchable(),
                                one_of(vec![
                                    Sequence::new(vec![
                                        Ref::new("GCSEncryptionOption").to_matchable(),
                                        Sequence::new(vec![
                                            Ref::keyword("KMS_KEY_ID").to_matchable(),
                                            Ref::new("EqualsSegment").to_matchable(),
                                            Ref::new("QuotedLiteralSegment").to_matchable(),
                                        ])
                                        .config(|this| this.optional())
                                        .to_matchable(),
                                    ])
                                    .to_matchable(),
                                    Ref::keyword("NONE").to_matchable(),
                                ])
                                .to_matchable(),
                            ])
                            .to_matchable(),
                        ])
                        .to_matchable(),
                    ])
                    .config(|this| this.optional())
                    .to_matchable(),
                ])
                .to_matchable()
            })
            .to_matchable()
            .into(),
        ),
        (
            "AzureBlobStorageExternalStageParameters".into(),
            NodeMatcher::new(SyntaxKind::AzureBlobStorageExternalStageParameters, |_| {
                Sequence::new(vec![
                    one_of(vec![
                        Sequence::new(vec![
                            Ref::keyword("STORAGE_INTEGRATION").to_matchable(),
                            Ref::new("EqualsSegment").to_matchable(),
                            Ref::new("ObjectReferenceSegment").to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("CREDENTIALS").to_matchable(),
                            Ref::new("EqualsSegment").to_matchable(),
                            Bracketed::new(vec![
                                Sequence::new(vec![
                                    Ref::keyword("AZURE_SAS_TOKEN").to_matchable(),
                                    Ref::new("EqualsSegment").to_matchable(),
                                    Ref::new("QuotedLiteralSegment").to_matchable(),
                                ])
                                .to_matchable(),
                            ])
                            .to_matchable(),
                        ])
                        .to_matchable(),
                    ])
                    .config(|this| this.optional())
                    .to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("ENCRYPTION").to_matchable(),
                        Ref::new("EqualsSegment").to_matchable(),
                        Bracketed::new(vec![
                            Sequence::new(vec![
                                Ref::keyword("TYPE").to_matchable(),
                                Ref::new("EqualsSegment").to_matchable(),
                                one_of(vec![
                                    Sequence::new(vec![
                                        Ref::new("AzureBlobStorageEncryptionOption").to_matchable(),
                                        Sequence::new(vec![
                                            Ref::keyword("MASTER_KEY").to_matchable(),
                                            Ref::new("EqualsSegment").to_matchable(),
                                            Ref::new("QuotedLiteralSegment").to_matchable(),
                                        ])
                                        .config(|this| this.optional())
                                        .to_matchable(),
                                    ])
                                    .to_matchable(),
                                    Ref::keyword("NONE").to_matchable(),
                                ])
                                .to_matchable(),
                            ])
                            .to_matchable(),
                        ])
                        .to_matchable(),
                    ])
                    .config(|this| this.optional())
                    .to_matchable(),
                ])
                .to_matchable()
            })
            .to_matchable()
            .into(),
        ),
        (
            "CreateStageSegment".into(),
            NodeMatcher::new(SyntaxKind::CreateStageStatement, |_| {
                Sequence::new(vec![
                    Ref::keyword("CREATE").to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("OR").to_matchable(),
                        Ref::keyword("REPLACE").to_matchable(),
                    ])
                    .config(|this| this.optional())
                    .to_matchable(),
                    Ref::keyword("TEMPORARY").optional().to_matchable(),
                    Ref::keyword("STAGE").to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("IF").to_matchable(),
                        Ref::keyword("NOT").to_matchable(),
                        Ref::keyword("EXISTS").to_matchable(),
                    ])
                    .config(|this| this.optional())
                    .to_matchable(),
                    Ref::new("ObjectReferenceSegment").to_matchable(),
                    MetaSegment::indent().to_matchable(),
                    one_of(vec![
                        // Internal stages
                        Sequence::new(vec![
                            Ref::new("InternalStageParameters")
                                .optional()
                                .to_matchable(),
                            Sequence::new(vec![
                                Ref::keyword("DIRECTORY").to_matchable(),
                                Ref::new("EqualsSegment").to_matchable(),
                                Bracketed::new(vec![
                                    Sequence::new(vec![
                                        Ref::keyword("ENABLE").to_matchable(),
                                        Ref::new("EqualsSegment").to_matchable(),
                                        Ref::new("BooleanLiteralGrammar").to_matchable(),
                                    ])
                                    .to_matchable(),
                                ])
                                .to_matchable(),
                            ])
                            .config(|this| this.optional())
                            .to_matchable(),
                        ])
                        .to_matchable(),
                        // External S3 stage
                        Sequence::new(vec![
                            Ref::keyword("URL").to_matchable(),
                            Ref::new("EqualsSegment").to_matchable(),
                            Ref::new("S3Path").to_matchable(),
                            Ref::new("S3ExternalStageParameters")
                                .optional()
                                .to_matchable(),
                            Sequence::new(vec![
                                Ref::keyword("DIRECTORY").to_matchable(),
                                Ref::new("EqualsSegment").to_matchable(),
                                Bracketed::new(vec![
                                    Sequence::new(vec![
                                        Ref::keyword("ENABLE").to_matchable(),
                                        Ref::new("EqualsSegment").to_matchable(),
                                        Ref::new("BooleanLiteralGrammar").to_matchable(),
                                    ])
                                    .to_matchable(),
                                    Sequence::new(vec![
                                        Ref::keyword("AUTO_REFRESH").to_matchable(),
                                        Ref::new("EqualsSegment").to_matchable(),
                                        Ref::new("BooleanLiteralGrammar").to_matchable(),
                                    ])
                                    .config(|this| this.optional())
                                    .to_matchable(),
                                ])
                                .to_matchable(),
                            ])
                            .config(|this| this.optional())
                            .to_matchable(),
                        ])
                        .to_matchable(),
                        // External GCS stage
                        Sequence::new(vec![
                            Ref::keyword("URL").to_matchable(),
                            Ref::new("EqualsSegment").to_matchable(),
                            Ref::new("GCSPath").to_matchable(),
                            Ref::new("GCSExternalStageParameters")
                                .optional()
                                .to_matchable(),
                            Sequence::new(vec![
                                Ref::keyword("DIRECTORY").to_matchable(),
                                Ref::new("EqualsSegment").to_matchable(),
                                Bracketed::new(vec![
                                    Sequence::new(vec![
                                        Ref::keyword("ENABLE").to_matchable(),
                                        Ref::new("EqualsSegment").to_matchable(),
                                        Ref::new("BooleanLiteralGrammar").to_matchable(),
                                    ])
                                    .to_matchable(),
                                    Sequence::new(vec![
                                        Ref::keyword("AUTO_REFRESH").to_matchable(),
                                        Ref::new("EqualsSegment").to_matchable(),
                                        Ref::new("BooleanLiteralGrammar").to_matchable(),
                                    ])
                                    .config(|this| this.optional())
                                    .to_matchable(),
                                    Sequence::new(vec![
                                        Ref::keyword("NOTIFICATION_INTEGRATION").to_matchable(),
                                        Ref::new("EqualsSegment").to_matchable(),
                                        one_of(vec![
                                            Ref::new("NakedIdentifierSegment").to_matchable(),
                                            Ref::new("QuotedLiteralSegment").to_matchable(),
                                        ])
                                        .to_matchable(),
                                    ])
                                    .config(|this| this.optional())
                                    .to_matchable(),
                                ])
                                .to_matchable(),
                            ])
                            .config(|this| this.optional())
                            .to_matchable(),
                        ])
                        .to_matchable(),
                        // External Azure Blob Storage stage
                        Sequence::new(vec![
                            Ref::keyword("URL").to_matchable(),
                            Ref::new("EqualsSegment").to_matchable(),
                            Ref::new("AzureBlobStoragePath").to_matchable(),
                            Ref::new("AzureBlobStorageExternalStageParameters")
                                .optional()
                                .to_matchable(),
                            Sequence::new(vec![
                                Ref::keyword("DIRECTORY").to_matchable(),
                                Ref::new("EqualsSegment").to_matchable(),
                                Bracketed::new(vec![
                                    Sequence::new(vec![
                                        Ref::keyword("ENABLE").to_matchable(),
                                        Ref::new("EqualsSegment").to_matchable(),
                                        Ref::new("BooleanLiteralGrammar").to_matchable(),
                                    ])
                                    .to_matchable(),
                                    Sequence::new(vec![
                                        Ref::keyword("AUTO_REFRESH").to_matchable(),
                                        Ref::new("EqualsSegment").to_matchable(),
                                        Ref::new("BooleanLiteralGrammar").to_matchable(),
                                    ])
                                    .config(|this| this.optional())
                                    .to_matchable(),
                                    Sequence::new(vec![
                                        Ref::keyword("NOTIFICATION_INTEGRATION").to_matchable(),
                                        Ref::new("EqualsSegment").to_matchable(),
                                        one_of(vec![
                                            Ref::new("NakedIdentifierSegment").to_matchable(),
                                            Ref::new("QuotedLiteralSegment").to_matchable(),
                                        ])
                                        .to_matchable(),
                                    ])
                                    .config(|this| this.optional())
                                    .to_matchable(),
                                ])
                                .to_matchable(),
                            ])
                            .config(|this| this.optional())
                            .to_matchable(),
                        ])
                        .to_matchable(),
                    ])
                    .config(|this| this.optional())
                    .to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("FILE_FORMAT").to_matchable(),
                        Ref::new("EqualsSegment").to_matchable(),
                        Ref::new("FileFormatSegment").to_matchable(),
                    ])
                    .config(|this| this.optional())
                    .to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("COPY_OPTIONS").to_matchable(),
                        Ref::new("EqualsSegment").to_matchable(),
                        Bracketed::new(vec![Ref::new("CopyOptionsSegment").to_matchable()])
                            .to_matchable(),
                    ])
                    .config(|this| this.optional())
                    .to_matchable(),
                    Ref::new("TagBracketedEqualsSegment")
                        .optional()
                        .to_matchable(),
                    Ref::new("CommentEqualsClauseSegment")
                        .optional()
                        .to_matchable(),
                    MetaSegment::dedent().to_matchable(),
                ])
                .to_matchable()
            })
            .to_matchable()
            .into(),
        ),
        (
            "AlterStageSegment".into(),
            NodeMatcher::new(SyntaxKind::AlterStageStatement, |_| {
                Sequence::new(vec![
                    Ref::keyword("ALTER").to_matchable(),
                    Ref::keyword("STAGE").to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("IF").to_matchable(),
                        Ref::keyword("EXISTS").to_matchable(),
                    ])
                    .config(|this| this.optional())
                    .to_matchable(),
                    Ref::new("ObjectReferenceSegment").to_matchable(),
                    one_of(vec![
                        Sequence::new(vec![
                            Ref::keyword("RENAME").to_matchable(),
                            Ref::keyword("TO").to_matchable(),
                            Ref::new("ObjectReferenceSegment").to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("SET").to_matchable(),
                            MetaSegment::indent().to_matchable(),
                            one_of(vec![
                                Sequence::new(vec![
                                    one_of(vec![
                                        Ref::new("InternalStageParameters").to_matchable(),
                                        Sequence::new(vec![
                                            Sequence::new(vec![
                                                Ref::keyword("URL").to_matchable(),
                                                Ref::new("EqualsSegment").to_matchable(),
                                                Ref::new("S3Path").to_matchable(),
                                            ])
                                            .config(|this| this.optional())
                                            .to_matchable(),
                                            Ref::new("S3ExternalStageParameters")
                                                .optional()
                                                .to_matchable(),
                                        ])
                                        .to_matchable(),
                                        Sequence::new(vec![
                                            Sequence::new(vec![
                                                Ref::keyword("URL").to_matchable(),
                                                Ref::new("EqualsSegment").to_matchable(),
                                                Ref::new("GCSPath").to_matchable(),
                                            ])
                                            .config(|this| this.optional())
                                            .to_matchable(),
                                            Ref::new("GCSExternalStageParameters")
                                                .optional()
                                                .to_matchable(),
                                        ])
                                        .to_matchable(),
                                        Sequence::new(vec![
                                            Sequence::new(vec![
                                                Ref::keyword("URL").to_matchable(),
                                                Ref::new("EqualsSegment").to_matchable(),
                                                Ref::new("AzureBlobStoragePath").to_matchable(),
                                            ])
                                            .config(|this| this.optional())
                                            .to_matchable(),
                                            Ref::new("AzureBlobStorageExternalStageParameters")
                                                .optional()
                                                .to_matchable(),
                                        ])
                                        .to_matchable(),
                                    ])
                                    .config(|this| this.optional())
                                    .to_matchable(),
                                    Sequence::new(vec![
                                        Ref::keyword("FILE_FORMAT").to_matchable(),
                                        Ref::new("EqualsSegment").to_matchable(),
                                        Ref::new("FileFormatSegment").to_matchable(),
                                    ])
                                    .config(|this| this.optional())
                                    .to_matchable(),
                                    Sequence::new(vec![
                                        Ref::keyword("COPY_OPTIONS").to_matchable(),
                                        Ref::new("EqualsSegment").to_matchable(),
                                        Bracketed::new(vec![
                                            Ref::new("CopyOptionsSegment").to_matchable(),
                                        ])
                                        .to_matchable(),
                                    ])
                                    .config(|this| this.optional())
                                    .to_matchable(),
                                    Ref::new("CommentEqualsClauseSegment")
                                        .optional()
                                        .to_matchable(),
                                ])
                                .to_matchable(),
                                Ref::new("TagEqualsSegment").to_matchable(),
                            ])
                            .to_matchable(),
                            MetaSegment::dedent().to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("REFRESH").to_matchable(),
                            Sequence::new(vec![
                                Ref::keyword("SUBPATH").to_matchable(),
                                Ref::new("EqualsSegment").to_matchable(),
                                Ref::new("QuotedLiteralSegment").to_matchable(),
                            ])
                            .config(|this| this.optional())
                            .to_matchable(),
                        ])
                        .to_matchable(),
                    ])
                    .to_matchable(),
                ])
                .to_matchable()
            })
            .to_matchable()
            .into(),
        ),
        (
            "CreateStreamStatementSegment".into(),
            NodeMatcher::new(SyntaxKind::CreateStreamStatement, |_| {
                Sequence::new(vec![
                    Ref::keyword("CREATE").to_matchable(),
                    Ref::new("OrReplaceGrammar").optional().to_matchable(),
                    Ref::keyword("STREAM").to_matchable(),
                    Ref::new("IfNotExistsGrammar").optional().to_matchable(),
                    Ref::new("ObjectReferenceSegment").to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("COPY").to_matchable(),
                        Ref::keyword("GRANTS").to_matchable(),
                    ])
                    .config(|this| this.optional())
                    .to_matchable(),
                    Ref::keyword("ON").to_matchable(),
                    one_of(vec![
                        Sequence::new(vec![
                            one_of(vec![
                                Ref::keyword("TABLE").to_matchable(),
                                Ref::keyword("VIEW").to_matchable(),
                            ])
                            .to_matchable(),
                            Ref::new("ObjectReferenceSegment").to_matchable(),
                            one_of(vec![
                                Ref::new("FromAtExpressionSegment").to_matchable(),
                                Ref::new("FromBeforeExpressionSegment").to_matchable(),
                            ])
                            .config(|this| this.optional())
                            .to_matchable(),
                            Sequence::new(vec![
                                Ref::keyword("APPEND_ONLY").to_matchable(),
                                Ref::new("EqualsSegment").to_matchable(),
                                Ref::new("BooleanLiteralGrammar").to_matchable(),
                            ])
                            .config(|this| this.optional())
                            .to_matchable(),
                            Sequence::new(vec![
                                Ref::keyword("SHOW_INITIAL_ROWS").to_matchable(),
                                Ref::new("EqualsSegment").to_matchable(),
                                Ref::new("BooleanLiteralGrammar").to_matchable(),
                            ])
                            .config(|this| this.optional())
                            .to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("EXTERNAL").to_matchable(),
                            Ref::keyword("TABLE").to_matchable(),
                            Ref::new("ObjectReferenceSegment").to_matchable(),
                            one_of(vec![
                                Ref::new("FromAtExpressionSegment").to_matchable(),
                                Ref::new("FromBeforeExpressionSegment").to_matchable(),
                            ])
                            .config(|this| this.optional())
                            .to_matchable(),
                            Sequence::new(vec![
                                Ref::keyword("INSERT_ONLY").to_matchable(),
                                Ref::new("EqualsSegment").to_matchable(),
                                Ref::new("TrueSegment").to_matchable(),
                            ])
                            .config(|this| this.optional())
                            .to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("STAGE").to_matchable(),
                            Ref::new("ObjectReferenceSegment").to_matchable(),
                        ])
                        .to_matchable(),
                    ])
                    .to_matchable(),
                    Ref::new("CommentEqualsClauseSegment")
                        .optional()
                        .to_matchable(),
                ])
                .to_matchable()
            })
            .to_matchable()
            .into(),
        ),
        (
            "AlterStreamStatementSegment".into(),
            NodeMatcher::new(SyntaxKind::AlterStreamStatement, |_| {
                Sequence::new(vec![
                    Ref::keyword("ALTER").to_matchable(),
                    Ref::keyword("STREAM").to_matchable(),
                    Ref::new("IfExistsGrammar").optional().to_matchable(),
                    Ref::new("ObjectReferenceSegment").to_matchable(),
                    one_of(vec![
                        Sequence::new(vec![
                            Ref::keyword("SET").to_matchable(),
                            Sequence::new(vec![
                                Ref::keyword("APPEND_ONLY").to_matchable(),
                                Ref::new("EqualsSegment").to_matchable(),
                                Ref::new("BooleanLiteralGrammar").to_matchable(),
                            ])
                            .config(|this| this.optional())
                            .to_matchable(),
                            Sequence::new(vec![
                                Ref::keyword("INSERT_ONLY").to_matchable(),
                                Ref::new("EqualsSegment").to_matchable(),
                                Ref::new("TrueSegment").to_matchable(),
                            ])
                            .config(|this| this.optional())
                            .to_matchable(),
                            Ref::new("TagEqualsSegment").optional().to_matchable(),
                            Ref::new("CommentEqualsClauseSegment")
                                .optional()
                                .to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("UNSET").to_matchable(),
                            one_of(vec![
                                Sequence::new(vec![
                                    Ref::keyword("TAG").to_matchable(),
                                    Delimited::new(vec![
                                        Ref::new("TagReferenceSegment").to_matchable(),
                                    ])
                                    .to_matchable(),
                                ])
                                .to_matchable(),
                                Ref::keyword("COMMENT").to_matchable(),
                            ])
                            .to_matchable(),
                        ])
                        .to_matchable(),
                    ])
                    .to_matchable(),
                ])
                .to_matchable()
            })
            .to_matchable()
            .into(),
        ),
        (
            // `ALTER ACCOUNT` statement.
            // https://docs.snowflake.com/en/sql-reference/sql/alter-account
            "AlterAccountStatementSegment".into(),
            Sequence::new(vec![
                Ref::keyword("ALTER").to_matchable(),
                Ref::keyword("ACCOUNT").to_matchable(),
                one_of(vec![
                    Sequence::new(vec![
                        Ref::keyword("SET").to_matchable(),
                        Ref::keyword("RESOURCE_MONITOR").to_matchable(),
                        Ref::new("EqualsSegment").to_matchable(),
                        Ref::new("NakedIdentifierSegment").to_matchable(),
                    ])
                    .to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("SET").to_matchable(),
                        one_of(vec![
                            Ref::keyword("PASSWORD").to_matchable(),
                            Ref::keyword("SESSION").to_matchable(),
                        ])
                        .to_matchable(),
                        Ref::keyword("POLICY").to_matchable(),
                        Ref::new("TableReferenceSegment").to_matchable(),
                    ])
                    .to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("SET").to_matchable(),
                        Ref::new("TagEqualsSegment").to_matchable(),
                    ])
                    .to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("SET").to_matchable(),
                        Delimited::new(vec![
                            Sequence::new(vec![
                                Ref::new("ParameterNameSegment").to_matchable(),
                                Ref::new("EqualsSegment").to_matchable(),
                                one_of(vec![
                                    Ref::new("BooleanLiteralGrammar").to_matchable(),
                                    Ref::new("QuotedLiteralSegment").to_matchable(),
                                    Ref::new("NumericLiteralSegment").to_matchable(),
                                    Ref::new("NakedIdentifierSegment").to_matchable(),
                                ])
                                .to_matchable(),
                            ])
                            .to_matchable(),
                        ])
                        .to_matchable(),
                    ])
                    .to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("UNSET").to_matchable(),
                        one_of(vec![
                            Ref::keyword("PASSWORD").to_matchable(),
                            Ref::keyword("SESSION").to_matchable(),
                        ])
                        .to_matchable(),
                        Ref::keyword("POLICY").to_matchable(),
                    ])
                    .to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("UNSET").to_matchable(),
                        one_of(vec![
                            Sequence::new(vec![
                                Ref::keyword("TAG").to_matchable(),
                                Delimited::new(vec![
                                    Ref::new("TagReferenceSegment").to_matchable(),
                                ])
                                .to_matchable(),
                            ])
                            .to_matchable(),
                            Delimited::new(vec![Ref::new("NakedIdentifierSegment").to_matchable()])
                                .to_matchable(),
                        ])
                        .to_matchable(),
                    ])
                    .to_matchable(),
                ])
                .to_matchable(),
            ])
            .to_matchable()
            .into(),
        ),
        (
            "ShowStatementSegment".into(),
            NodeMatcher::new(SyntaxKind::ShowStatement, |_| {
                let object_types_plural = one_of(vec![
                    Ref::keyword("PARAMETERS").to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("GLOBAL").to_matchable(),
                        Ref::keyword("ACCOUNTS").to_matchable(),
                    ])
                    .to_matchable(),
                    Ref::keyword("REGIONS").to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("REPLICATION").to_matchable(),
                        Ref::keyword("ACCOUNTS").to_matchable(),
                    ])
                    .to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("REPLICATION").to_matchable(),
                        Ref::keyword("DATABASES").to_matchable(),
                    ])
                    .to_matchable(),
                    Ref::keyword("PARAMETERS").to_matchable(),
                    Ref::keyword("VARIABLES").to_matchable(),
                    Ref::keyword("TRANSACTIONS").to_matchable(),
                    Ref::keyword("LOCKS").to_matchable(),
                    Ref::keyword("PARAMETERS").to_matchable(),
                    Ref::keyword("FUNCTIONS").to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("NETWORK").to_matchable(),
                        Ref::keyword("POLICIES").to_matchable(),
                    ])
                    .to_matchable(),
                    Ref::keyword("SHARES").to_matchable(),
                    Ref::keyword("ROLES").to_matchable(),
                    Ref::keyword("GRANTS").to_matchable(),
                    Ref::keyword("USERS").to_matchable(),
                    Ref::keyword("WAREHOUSES").to_matchable(),
                    Ref::keyword("DATABASES").to_matchable(),
                    Sequence::new(vec![
                        one_of(vec![
                            Ref::keyword("API").to_matchable(),
                            Ref::keyword("NOTIFICATION").to_matchable(),
                            Ref::keyword("SECURITY").to_matchable(),
                            Ref::keyword("STORAGE").to_matchable(),
                        ])
                        .config(|this| this.optional())
                        .to_matchable(),
                        Ref::keyword("INTEGRATIONS").to_matchable(),
                    ])
                    .to_matchable(),
                    Ref::keyword("SCHEMAS").to_matchable(),
                    Ref::keyword("OBJECTS").to_matchable(),
                    Ref::keyword("TABLES").to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("EXTERNAL").to_matchable(),
                        Ref::keyword("TABLES").to_matchable(),
                    ])
                    .to_matchable(),
                    Ref::keyword("VIEWS").to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("MATERIALIZED").to_matchable(),
                        Ref::keyword("VIEWS").to_matchable(),
                    ])
                    .to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("MASKING").to_matchable(),
                        Ref::keyword("POLICIES").to_matchable(),
                    ])
                    .to_matchable(),
                    Ref::keyword("COLUMNS").to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("FILE").to_matchable(),
                        Ref::keyword("FORMATS").to_matchable(),
                    ])
                    .to_matchable(),
                    Ref::keyword("SEQUENCES").to_matchable(),
                    Ref::keyword("STAGES").to_matchable(),
                    Ref::keyword("PIPES").to_matchable(),
                    Ref::keyword("STREAMS").to_matchable(),
                    Ref::keyword("TASKS").to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("USER").to_matchable(),
                        Ref::keyword("FUNCTIONS").to_matchable(),
                    ])
                    .to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("EXTERNAL").to_matchable(),
                        Ref::keyword("FUNCTIONS").to_matchable(),
                    ])
                    .to_matchable(),
                    Ref::keyword("PROCEDURES").to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("FUTURE").to_matchable(),
                        Ref::keyword("GRANTS").to_matchable(),
                    ])
                    .to_matchable(),
                ]);

                let object_scope_types = one_of(vec![
                    Ref::keyword("ACCOUNT").to_matchable(),
                    Ref::keyword("SESSION").to_matchable(),
                    Sequence::new(vec![
                        one_of(vec![
                            Ref::keyword("DATABASE").to_matchable(),
                            Ref::keyword("SCHEMA").to_matchable(),
                            Ref::keyword("SHARE").to_matchable(),
                            Ref::keyword("ROLE").to_matchable(),
                            Ref::keyword("TABLE").to_matchable(),
                            Ref::keyword("TASK").to_matchable(),
                            Ref::keyword("USER").to_matchable(),
                            Ref::keyword("WAREHOUSE").to_matchable(),
                            Ref::keyword("VIEW").to_matchable(),
                        ])
                        .to_matchable(),
                        Ref::new("ObjectReferenceSegment").optional().to_matchable(),
                    ])
                    .to_matchable(),
                ]);

                Sequence::new(vec![
                    Ref::keyword("SHOW").to_matchable(),
                    Ref::keyword("TERSE").optional().to_matchable(),
                    object_types_plural.to_matchable(),
                    Ref::keyword("HISTORY").optional().to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("LIKE").to_matchable(),
                        Ref::new("QuotedLiteralSegment").to_matchable(),
                    ])
                    .config(|this| this.optional())
                    .to_matchable(),
                    Sequence::new(vec![
                        one_of(vec![
                            Ref::keyword("ON").to_matchable(),
                            Ref::keyword("TO").to_matchable(),
                            Ref::keyword("OF").to_matchable(),
                            Ref::keyword("IN").to_matchable(),
                        ])
                        .to_matchable(),
                        one_of(vec![
                            Sequence::new(vec![object_scope_types.to_matchable()]).to_matchable(),
                            Ref::new("ObjectReferenceSegment").to_matchable(),
                        ])
                        .to_matchable(),
                    ])
                    .config(|this| this.optional())
                    .to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("STARTS").to_matchable(),
                        Ref::keyword("WITH").to_matchable(),
                        Ref::new("QuotedLiteralSegment").to_matchable(),
                    ])
                    .config(|this| this.optional())
                    .to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("WITH").to_matchable(),
                        Ref::keyword("PRIMARY").to_matchable(),
                        Ref::new("ObjectReferenceSegment").to_matchable(),
                    ])
                    .config(|this| this.optional())
                    .to_matchable(),
                    Sequence::new(vec![
                        Ref::new("LimitClauseSegment").to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("FROM").to_matchable(),
                            Ref::new("QuotedLiteralSegment").to_matchable(),
                        ])
                        .config(|this| this.optional())
                        .to_matchable(),
                    ])
                    .config(|this| this.optional())
                    .to_matchable(),
                ])
                .to_matchable()
            })
            .to_matchable()
            .into(),
        ),
        (
            "AlterUserStatementSegment".into(),
            NodeMatcher::new(SyntaxKind::AlterUserStatement, |_| {
                Sequence::new(vec![
                    Ref::keyword("ALTER").to_matchable(),
                    Ref::keyword("USER").to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("IF").to_matchable(),
                        Ref::keyword("EXISTS").to_matchable(),
                    ])
                    .config(|this| this.optional())
                    .to_matchable(),
                    Ref::new("RoleReferenceSegment").to_matchable(),
                    one_of(vec![
                        Sequence::new(vec![
                            Ref::keyword("RENAME").to_matchable(),
                            Ref::keyword("TO").to_matchable(),
                            Ref::new("ObjectReferenceSegment").to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("RESET").to_matchable(),
                            Ref::keyword("PASSWORD").to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("ABORT").to_matchable(),
                            Ref::keyword("ALL").to_matchable(),
                            Ref::keyword("QUERIES").to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("ADD").to_matchable(),
                            Ref::keyword("DELEGATED").to_matchable(),
                            Ref::keyword("AUTHORIZATION").to_matchable(),
                            Ref::keyword("OF").to_matchable(),
                            Ref::keyword("ROLE").to_matchable(),
                            Ref::new("ObjectReferenceSegment").to_matchable(),
                            Ref::keyword("TO").to_matchable(),
                            Ref::keyword("SECURITY").to_matchable(),
                            Ref::keyword("INTEGRATION").to_matchable(),
                            Ref::new("ObjectReferenceSegment").to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("REMOVE").to_matchable(),
                            Ref::keyword("DELEGATED").to_matchable(),
                            one_of(vec![
                                Sequence::new(vec![
                                    Ref::keyword("AUTHORIZATION").to_matchable(),
                                    Ref::keyword("OF").to_matchable(),
                                    Ref::keyword("ROLE").to_matchable(),
                                    Ref::new("ObjectReferenceSegment").to_matchable(),
                                ])
                                .to_matchable(),
                                Ref::keyword("AUTHORIZATIONS").to_matchable(),
                            ])
                            .to_matchable(),
                            Ref::keyword("FROM").to_matchable(),
                            Ref::keyword("SECURITY").to_matchable(),
                            Ref::keyword("INTEGRATION").to_matchable(),
                            Ref::new("ObjectReferenceSegment").to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("SET").to_matchable(),
                            Delimited::new(vec![
                                Sequence::new(vec![
                                    Ref::new("ParameterNameSegment").to_matchable(),
                                    Ref::new("EqualsSegment").to_matchable(),
                                    one_of(vec![
                                        Ref::new("LiteralGrammar").to_matchable(),
                                        Ref::new("ObjectReferenceSegment").to_matchable(),
                                    ])
                                    .to_matchable(),
                                ])
                                .to_matchable(),
                            ])
                            .to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("UNSET").to_matchable(),
                            Delimited::new(vec![Ref::new("ParameterNameSegment").to_matchable()])
                                .to_matchable(),
                        ])
                        .to_matchable(),
                    ])
                    .to_matchable(),
                ])
                .to_matchable()
            })
            .to_matchable()
            .into(),
        ),
    ]);

    snowflake_dialect.replace_grammar(
        "CreateRoleStatementSegment",
        Sequence::new(vec![
            Ref::keyword("CREATE").to_matchable(),
            Sequence::new(vec![
                Ref::keyword("OR").to_matchable(),
                Ref::keyword("REPLACE").to_matchable(),
            ])
            .config(|this| this.optional())
            .to_matchable(),
            Ref::keyword("ROLE").to_matchable(),
            Sequence::new(vec![
                Ref::keyword("IF").to_matchable(),
                Ref::keyword("NOT").to_matchable(),
                Ref::keyword("EXISTS").to_matchable(),
            ])
            .config(|this| this.optional())
            .to_matchable(),
            Ref::new("RoleReferenceSegment").to_matchable(),
            Sequence::new(vec![
                Ref::keyword("COMMENT").to_matchable(),
                Ref::new("EqualsSegment").to_matchable(),
                Ref::new("QuotedLiteralSegment").to_matchable(),
            ])
            .config(|this| this.optional())
            .to_matchable(),
        ])
        .to_matchable(),
    );

    snowflake_dialect.replace_grammar(
        "ExplainStatementSegment",
        Sequence::new(vec![
            Ref::keyword("EXPLAIN").to_matchable(),
            Sequence::new(vec![
                Ref::keyword("USING").to_matchable(),
                one_of(vec![
                    Ref::keyword("TABULAR").to_matchable(),
                    Ref::keyword("JSON").to_matchable(),
                    Ref::keyword("TEXT").to_matchable(),
                ])
                .to_matchable(),
            ])
            .config(|this| this.optional())
            .to_matchable(),
            ansi::explainable_stmt().to_matchable(),
        ])
        .to_matchable(),
    );

    snowflake_dialect.add([
        (
            "AlterSessionStatementSegment".into(),
            NodeMatcher::new(SyntaxKind::AlterSessionStatement, |_| {
                Sequence::new(vec![
                    Ref::keyword("ALTER").to_matchable(),
                    Ref::keyword("SESSION").to_matchable(),
                    one_of(vec![
                        Ref::new("AlterSessionSetClauseSegment").to_matchable(),
                        Ref::new("AlterSessionUnsetClauseSegment").to_matchable(),
                    ])
                    .to_matchable(),
                ])
                .to_matchable()
            })
            .to_matchable()
            .into(),
        ),
        (
            "AlterSessionSetClauseSegment".into(),
            NodeMatcher::new(SyntaxKind::AlterSessionSetStatement, |_| {
                Sequence::new(vec![
                    Ref::keyword("SET").to_matchable(),
                    Ref::new("ParameterNameSegment").to_matchable(),
                    Ref::new("EqualsSegment").to_matchable(),
                    one_of(vec![
                        Ref::new("BooleanLiteralGrammar").to_matchable(),
                        Ref::new("QuotedLiteralSegment").to_matchable(),
                        Ref::new("NumericLiteralSegment").to_matchable(),
                    ])
                    .to_matchable(),
                ])
                .to_matchable()
            })
            .to_matchable()
            .into(),
        ),
        (
            "AlterSessionUnsetClauseSegment".into(),
            NodeMatcher::new(SyntaxKind::AlterSessionUnsetClause, |_| {
                Sequence::new(vec![
                    Ref::keyword("UNSET").to_matchable(),
                    Delimited::new(vec![Ref::new("ParameterNameSegment").to_matchable()])
                        .to_matchable(),
                ])
                .to_matchable()
            })
            .to_matchable()
            .into(),
        ),
        (
            "AlterTaskStatementSegment".into(),
            NodeMatcher::new(SyntaxKind::AlterTaskStatement, |_| {
                Sequence::new(vec![
                    Ref::keyword("ALTER").to_matchable(),
                    Ref::keyword("TASK").to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("IF").to_matchable(),
                        Ref::keyword("EXISTS").to_matchable(),
                    ])
                    .config(|this| this.optional())
                    .to_matchable(),
                    Ref::new("ObjectReferenceSegment").to_matchable(),
                    one_of(vec![
                        Ref::keyword("RESUME").to_matchable(),
                        Ref::keyword("SUSPEND").to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("REMOVE").to_matchable(),
                            Ref::keyword("AFTER").to_matchable(),
                            Ref::new("ObjectReferenceSegment").to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("ADD").to_matchable(),
                            Ref::keyword("AFTER").to_matchable(),
                            Ref::new("ObjectReferenceSegment").to_matchable(),
                        ])
                        .to_matchable(),
                        Ref::new("AlterTaskSpecialSetClauseSegment").to_matchable(),
                        Ref::new("AlterTaskSetClauseSegment").to_matchable(),
                        Ref::new("AlterTaskUnsetClauseSegment").to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("MODIFY").to_matchable(),
                            Ref::keyword("AS").to_matchable(),
                            ansi::explainable_stmt().to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("MODIFY").to_matchable(),
                            Ref::keyword("WHEN").to_matchable(),
                            Ref::new("BooleanLiteralGrammar").to_matchable(),
                        ])
                        .to_matchable(),
                    ])
                    .to_matchable(),
                ])
                .to_matchable()
            })
            .to_matchable()
            .into(),
        ),
        (
            "AlterTaskSpecialSetClauseSegment".into(),
            NodeMatcher::new(SyntaxKind::AlterTaskSpecialSetClause, |_| {
                Sequence::new(vec![
                    Ref::keyword("SET").to_matchable(),
                    any_set_of(vec![
                        Sequence::new(vec![
                            Ref::keyword("WAREHOUSE").to_matchable(),
                            Ref::new("EqualsSegment").to_matchable(),
                            Ref::new("ObjectReferenceSegment").to_matchable(),
                        ])
                        .config(|this| this.optional())
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("SCHEDULE").to_matchable(),
                            Ref::new("EqualsSegment").to_matchable(),
                            Ref::new("QuotedLiteralSegment").to_matchable(),
                        ])
                        .config(|this| this.optional())
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("ALLOW_OVERLAPPING_EXECUTION").to_matchable(),
                            Ref::new("EqualsSegment").to_matchable(),
                            Ref::new("BooleanLiteralGrammar").to_matchable(),
                        ])
                        .config(|this| this.optional())
                        .to_matchable(),
                    ])
                    .config(|this| this.min_times(1))
                    .to_matchable(),
                ])
                .to_matchable()
            })
            .to_matchable()
            .into(),
        ),
        (
            "AlterTaskSetClauseSegment".into(),
            NodeMatcher::new(SyntaxKind::AlterTaskSetClause, |_| {
                Sequence::new(vec![
                    Ref::keyword("SET").to_matchable(),
                    Delimited::new(vec![
                        Sequence::new(vec![
                            Ref::new("ParameterNameSegment").to_matchable(),
                            Ref::new("EqualsSegment").to_matchable(),
                            one_of(vec![
                                Ref::new("BooleanLiteralGrammar").to_matchable(),
                                Ref::new("QuotedLiteralSegment").to_matchable(),
                                Ref::new("NumericLiteralSegment").to_matchable(),
                            ])
                            .to_matchable(),
                        ])
                        .to_matchable(),
                    ])
                    .to_matchable(),
                ])
                .to_matchable()
            })
            .to_matchable()
            .into(),
        ),
        (
            "AlterTaskUnsetClauseSegment".into(),
            NodeMatcher::new(SyntaxKind::AlterTaskUnsetClause, |_| {
                Sequence::new(vec![
                    Ref::keyword("UNSET").to_matchable(),
                    Delimited::new(vec![Ref::new("ParameterNameSegment").to_matchable()])
                        .to_matchable(),
                ])
                .to_matchable()
            })
            .to_matchable()
            .into(),
        ),
        (
            //Snowflake's EXECUTE IMMEDIATE clause.
            // https://docs.snowflake.com/en/sql-reference/sql/execute-immediate
            "ExecuteImmediateClauseSegment".into(),
            NodeMatcher::new(SyntaxKind::ExecuteImmediateClause, |_| {
                Sequence::new(vec![
                    Ref::keyword("EXECUTE").to_matchable(),
                    Ref::keyword("IMMEDIATE").to_matchable(),
                    one_of(vec![
                        Ref::new("QuotedLiteralSegment").to_matchable(),
                        Ref::new("ReferencedVariableNameSegment").to_matchable(),
                        Sequence::new(vec![
                            Ref::new("ColonSegment").to_matchable(),
                            Ref::new("LocalVariableNameSegment").to_matchable(),
                        ])
                        .to_matchable(),
                    ])
                    .to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("USING").to_matchable(),
                        Bracketed::new(vec![
                            Delimited::new(vec![
                                Ref::new("LocalVariableNameSegment").to_matchable(),
                            ])
                            .to_matchable(),
                        ])
                        .to_matchable(),
                    ])
                    .config(|this| this.optional())
                    .to_matchable(),
                ])
                .to_matchable()
            })
            .to_matchable()
            .into(),
        ),
        (
            "ExecuteTaskClauseSegment".into(),
            NodeMatcher::new(SyntaxKind::ExecuteTaskClause, |_| {
                Sequence::new(vec![
                    Ref::keyword("EXECUTE").to_matchable(),
                    Ref::keyword("TASK").to_matchable(),
                    Ref::new("ObjectReferenceSegment").to_matchable(),
                ])
                .to_matchable()
            })
            .to_matchable()
            .into(),
        ),
        (
            "CreateSequenceStatementSegment".into(),
            NodeMatcher::new(SyntaxKind::CreateSequenceStatement, |_| {
                Sequence::new(vec![
                    Ref::keyword("CREATE").to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("OR").to_matchable(),
                        Ref::keyword("REPLACE").to_matchable(),
                    ])
                    .config(|this| this.optional())
                    .to_matchable(),
                    Ref::keyword("SEQUENCE").to_matchable(),
                    Ref::new("IfNotExistsGrammar").optional().to_matchable(),
                    Ref::new("SequenceReferenceSegment").to_matchable(),
                    Ref::keyword("WITH").optional().to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("START").to_matchable(),
                        Ref::keyword("WITH").optional().to_matchable(),
                        Ref::new("EqualsSegment").optional().to_matchable(),
                        Ref::new("IntegerSegment").to_matchable(),
                    ])
                    .config(|this| this.optional())
                    .to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("INCREMENT").to_matchable(),
                        Ref::keyword("BY").optional().to_matchable(),
                        Ref::new("EqualsSegment").optional().to_matchable(),
                        Ref::new("IntegerSegment").to_matchable(),
                    ])
                    .config(|this| this.optional())
                    .to_matchable(),
                    one_of(vec![
                        Ref::keyword("ORDER").to_matchable(),
                        Ref::keyword("NOORDER").to_matchable(),
                    ])
                    .config(|this| this.optional())
                    .to_matchable(),
                    Ref::new("CommentEqualsClauseSegment")
                        .optional()
                        .to_matchable(),
                ])
                .to_matchable()
            })
            .to_matchable()
            .into(),
        ),
        (
            "AlterSequenceStatementSegment".into(),
            NodeMatcher::new(SyntaxKind::AlterSequenceStatement, |_| {
                Sequence::new(vec![
                    Ref::keyword("ALTER").to_matchable(),
                    Ref::keyword("SEQUENCE").to_matchable(),
                    Ref::new("IfExistsGrammar").optional().to_matchable(),
                    Ref::new("SequenceReferenceSegment").to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("SET").optional().to_matchable(),
                        any_set_of(vec![
                            Sequence::new(vec![
                                Ref::keyword("INCREMENT").to_matchable(),
                                Ref::keyword("BY").optional().to_matchable(),
                                Ref::new("EqualsSegment").optional().to_matchable(),
                                Ref::new("IntegerSegment").to_matchable(),
                            ])
                            .config(|this| this.optional())
                            .to_matchable(),
                            one_of(vec![
                                Ref::keyword("ORDER").to_matchable(),
                                Ref::keyword("NOORDER").to_matchable(),
                            ])
                            .to_matchable(),
                            Ref::new("CommentEqualsClauseSegment").to_matchable(),
                        ])
                        .to_matchable(),
                    ])
                    .config(|this| this.optional())
                    .to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("UNSET").to_matchable(),
                        Ref::keyword("COMMENT").to_matchable(),
                    ])
                    .config(|this| this.optional())
                    .to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("RENAME").to_matchable(),
                        Ref::keyword("TO").to_matchable(),
                        Ref::new("SequenceReferenceSegment").to_matchable(),
                    ])
                    .config(|this| this.optional())
                    .to_matchable(),
                ])
                .to_matchable()
            })
            .to_matchable()
            .into(),
        ),
    ]);

    snowflake_dialect.replace_grammar(
        "MergeUpdateClauseSegment",
        Sequence::new(vec![
            Ref::keyword("UPDATE").to_matchable(),
            Ref::new("SetClauseListSegment").to_matchable(),
            Ref::new("WhereClauseSegment").optional().to_matchable(),
        ])
        .to_matchable(),
    );

    snowflake_dialect.replace_grammar(
        "MergeDeleteClauseSegment",
        Sequence::new(vec![
            Ref::keyword("DELETE").to_matchable(),
            Ref::new("WhereClauseSegment").optional().to_matchable(),
        ])
        .to_matchable(),
    );

    snowflake_dialect.replace_grammar(
        "MergeInsertClauseSegment",
        Sequence::new(vec![
            Ref::keyword("INSERT").to_matchable(),
            MetaSegment::indent().to_matchable(),
            Ref::new("BracketedColumnReferenceListGrammar")
                .optional()
                .to_matchable(),
            MetaSegment::dedent().to_matchable(),
            Ref::new("ValuesClauseSegment").optional().to_matchable(),
            Ref::new("WhereClauseSegment").optional().to_matchable(),
        ])
        .to_matchable(),
    );

    snowflake_dialect.add([
        (
            "DeleteStatementSegment".into(),
            NodeMatcher::new(SyntaxKind::DeleteStatement, |_| {
                Sequence::new(vec![
                    Ref::keyword("DELETE").to_matchable(),
                    Ref::keyword("FROM").to_matchable(),
                    Ref::new("TableReferenceSegment").to_matchable(),
                    Ref::new("AliasExpressionSegment").optional().to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("USING").to_matchable(),
                        MetaSegment::indent().to_matchable(),
                        Delimited::new(vec![
                            Sequence::new(vec![
                                Ref::new("TableExpressionSegment").to_matchable(),
                                Ref::new("AliasExpressionSegment").optional().to_matchable(),
                            ])
                            .to_matchable(),
                        ])
                        .to_matchable(),
                        MetaSegment::dedent().to_matchable(),
                    ])
                    .config(|this| this.optional())
                    .to_matchable(),
                    Ref::new("WhereClauseSegment").optional().to_matchable(),
                ])
                .to_matchable()
            })
            .to_matchable()
            .into(),
        ),
        (
            "DescribeStatementSegment".into(),
            NodeMatcher::new(SyntaxKind::DescribeStatement, |_| {
                Sequence::new(vec![
                    one_of(vec![
                        Ref::keyword("DESCRIBE").to_matchable(),
                        Ref::keyword("DESC").to_matchable(),
                    ])
                    .to_matchable(),
                    one_of(vec![
                        Sequence::new(vec![
                            Ref::keyword("RESULT").to_matchable(),
                            one_of(vec![
                                Ref::new("QuotedLiteralSegment").to_matchable(),
                                Sequence::new(vec![
                                    Ref::keyword("LAST_QUERY_ID").to_matchable(),
                                    Bracketed::new(vec![]).to_matchable(),
                                ])
                                .to_matchable(),
                            ])
                            .to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("NETWORK").to_matchable(),
                            Ref::keyword("POLICY").to_matchable(),
                            Ref::new("ObjectReferenceSegment").to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("SHARE").to_matchable(),
                            Ref::new("ObjectReferenceSegment").to_matchable(),
                            Sequence::new(vec![
                                Ref::new("DotSegment").to_matchable(),
                                Ref::new("ObjectReferenceSegment").to_matchable(),
                            ])
                            .config(|this| this.optional())
                            .to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("USER").to_matchable(),
                            Ref::new("ObjectReferenceSegment").to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("WAREHOUSE").to_matchable(),
                            Ref::new("ObjectReferenceSegment").to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("DATABASE").to_matchable(),
                            Ref::new("DatabaseReferenceSegment").to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            one_of(vec![
                                Ref::keyword("API").to_matchable(),
                                Ref::keyword("NOTIFICATION").to_matchable(),
                                Ref::keyword("SECURITY").to_matchable(),
                                Ref::keyword("STORAGE").to_matchable(),
                            ])
                            .config(|this| this.optional())
                            .to_matchable(),
                            Ref::keyword("INTEGRATION").to_matchable(),
                            Ref::new("ObjectReferenceSegment").to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("SESSION").to_matchable(),
                            Ref::keyword("POLICY").to_matchable(),
                            Ref::new("ObjectReferenceSegment").to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("SCHEMA").to_matchable(),
                            Ref::new("SchemaReferenceSegment").to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("TABLE").to_matchable(),
                            Ref::new("TableReferenceSegment").to_matchable(),
                            Sequence::new(vec![
                                Ref::keyword("TYPE").to_matchable(),
                                Ref::new("EqualsSegment").to_matchable(),
                                one_of(vec![
                                    Ref::keyword("COLUMNS").to_matchable(),
                                    Ref::keyword("STAGE").to_matchable(),
                                ])
                                .to_matchable(),
                            ])
                            .config(|this| this.optional())
                            .to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("EXTERNAL").to_matchable(),
                            Ref::keyword("TABLE").to_matchable(),
                            Ref::new("TableReferenceSegment").to_matchable(),
                            Sequence::new(vec![
                                Ref::keyword("TYPE").to_matchable(),
                                Ref::new("EqualsSegment").to_matchable(),
                                one_of(vec![
                                    Ref::keyword("COLUMNS").to_matchable(),
                                    Ref::keyword("STAGE").to_matchable(),
                                ])
                                .to_matchable(),
                            ])
                            .config(|this| this.optional())
                            .to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("VIEW").to_matchable(),
                            Ref::new("TableReferenceSegment").to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("MATERIALIZED").to_matchable(),
                            Ref::keyword("VIEW").to_matchable(),
                            Ref::new("TableReferenceSegment").to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("SEQUENCE").to_matchable(),
                            Ref::new("SequenceReferenceSegment").to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("MASKING").to_matchable(),
                            Ref::keyword("POLICY").to_matchable(),
                            Ref::new("ObjectReferenceSegment").to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("ROW").to_matchable(),
                            Ref::keyword("ACCESS").to_matchable(),
                            Ref::keyword("POLICY").to_matchable(),
                            Ref::new("ObjectReferenceSegment").to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("FILE").to_matchable(),
                            Ref::keyword("FORMAT").to_matchable(),
                            Ref::new("ObjectReferenceSegment").to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("STAGE").to_matchable(),
                            Ref::new("ObjectReferenceSegment").to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("PIPE").to_matchable(),
                            Ref::new("ObjectReferenceSegment").to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("STREAM").to_matchable(),
                            Ref::new("ObjectReferenceSegment").to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("TASK").to_matchable(),
                            Ref::new("ObjectReferenceSegment").to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("FUNCTION").to_matchable(),
                            Ref::new("FunctionNameSegment").to_matchable(),
                            Bracketed::new(vec![
                                Delimited::new(vec![Ref::new("DatatypeSegment").to_matchable()])
                                    .config(|this| this.optional())
                                    .to_matchable(),
                            ])
                            .to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("PROCEDURE").to_matchable(),
                            Ref::new("FunctionNameSegment").to_matchable(),
                            Bracketed::new(vec![
                                Delimited::new(vec![Ref::new("DatatypeSegment").to_matchable()])
                                    .config(|this| this.optional())
                                    .to_matchable(),
                            ])
                            .to_matchable(),
                        ])
                        .to_matchable(),
                    ])
                    .to_matchable(),
                ])
                .to_matchable()
            })
            .to_matchable()
            .into(),
        ),
    ]);

    snowflake_dialect.replace_grammar(
        "TransactionStatementSegment",
        one_of(vec![
            Sequence::new(vec![
                Ref::keyword("BEGIN").to_matchable(),
                one_of(vec![
                    Ref::keyword("WORK").to_matchable(),
                    Ref::keyword("TRANSACTION").to_matchable(),
                ])
                .config(|this| this.optional())
                .to_matchable(),
                Sequence::new(vec![
                    Ref::keyword("NAME").to_matchable(),
                    Ref::new("ObjectReferenceSegment").to_matchable(),
                ])
                .config(|this| this.optional())
                .to_matchable(),
            ])
            .to_matchable(),
            Sequence::new(vec![
                Ref::keyword("START").to_matchable(),
                Ref::keyword("TRANSACTION").to_matchable(),
                Sequence::new(vec![
                    Ref::keyword("NAME").to_matchable(),
                    Ref::new("ObjectReferenceSegment").to_matchable(),
                ])
                .config(|this| this.optional())
                .to_matchable(),
            ])
            .to_matchable(),
            Sequence::new(vec![
                Ref::keyword("COMMIT").to_matchable(),
                Ref::keyword("WORK").optional().to_matchable(),
            ])
            .to_matchable(),
            Ref::keyword("ROLLBACK").to_matchable(),
        ])
        .to_matchable(),
    );

    snowflake_dialect.replace_grammar(
        "TruncateStatementSegment",
        Sequence::new(vec![
            Ref::keyword("TRUNCATE").to_matchable(),
            Ref::keyword("TABLE").optional().to_matchable(),
            Sequence::new(vec![
                Ref::keyword("IF").to_matchable(),
                Ref::keyword("EXISTS").to_matchable(),
            ])
            .config(|this| this.optional())
            .to_matchable(),
            Ref::new("TableReferenceSegment").to_matchable(),
        ])
        .to_matchable(),
    );

    snowflake_dialect.add([
        (
            "UnsetStatementSegment".into(),
            NodeMatcher::new(SyntaxKind::UnsetStatement, |_| {
                Sequence::new(vec![
                    Ref::keyword("UNSET").to_matchable(),
                    one_of(vec![
                        Ref::new("LocalVariableNameSegment").to_matchable(),
                        Bracketed::new(vec![
                            Delimited::new(vec![
                                Ref::new("LocalVariableNameSegment").to_matchable(),
                            ])
                            .to_matchable(),
                        ])
                        .to_matchable(),
                    ])
                    .to_matchable(),
                ])
                .to_matchable()
            })
            .to_matchable()
            .into(),
        ),
        (
            "UndropStatementSegment".into(),
            NodeMatcher::new(SyntaxKind::UndropStatement, |_| {
                Sequence::new(vec![
                    Ref::keyword("UNDROP").to_matchable(),
                    one_of(vec![
                        Sequence::new(vec![
                            Ref::keyword("DATABASE").to_matchable(),
                            Ref::new("DatabaseReferenceSegment").to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("SCHEMA").to_matchable(),
                            Ref::new("SchemaReferenceSegment").to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("TABLE").to_matchable(),
                            Ref::new("TableReferenceSegment").to_matchable(),
                        ])
                        .to_matchable(),
                    ])
                    .to_matchable(),
                ])
                .to_matchable()
            })
            .to_matchable()
            .into(),
        ),
        (
            "CommentStatementSegment".into(),
            NodeMatcher::new(SyntaxKind::CommentStatement, |_| {
                Sequence::new(vec![
                    Ref::keyword("COMMENT").to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("IF").to_matchable(),
                        Ref::keyword("EXISTS").to_matchable(),
                    ])
                    .config(|this| this.optional())
                    .to_matchable(),
                    Ref::keyword("ON").to_matchable(),
                    one_of(vec![
                        Ref::keyword("COLUMN").to_matchable(),
                        Ref::keyword("TABLE").to_matchable(),
                        Ref::keyword("VIEW").to_matchable(),
                        Ref::keyword("SCHEMA").to_matchable(),
                        Ref::keyword("DATABASE").to_matchable(),
                        Ref::keyword("WAREHOUSE").to_matchable(),
                        Ref::keyword("USER").to_matchable(),
                        Ref::keyword("STAGE").to_matchable(),
                        Ref::keyword("FUNCTION").to_matchable(),
                        Ref::keyword("PROCEDURE").to_matchable(),
                        Ref::keyword("SEQUENCE").to_matchable(),
                        Ref::keyword("SHARE").to_matchable(),
                        Ref::keyword("PIPE").to_matchable(),
                        Ref::keyword("STREAM").to_matchable(),
                        Ref::keyword("TASK").to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("NETWORK").to_matchable(),
                            Ref::keyword("POLICY").to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            one_of(vec![
                                Ref::keyword("API").to_matchable(),
                                Ref::keyword("NOTIFICATION").to_matchable(),
                                Ref::keyword("SECURITY").to_matchable(),
                                Ref::keyword("STORAGE").to_matchable(),
                            ])
                            .to_matchable(),
                            Ref::keyword("INTEGRATION").to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("SESSION").to_matchable(),
                            Ref::keyword("POLICY").to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("EXTERNAL").to_matchable(),
                            Ref::keyword("TABLE").to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("MATERIALIZED").to_matchable(),
                            Ref::keyword("VIEW").to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("MASKING").to_matchable(),
                            Ref::keyword("POLICY").to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("ROW").to_matchable(),
                            Ref::keyword("ACCESS").to_matchable(),
                            Ref::keyword("POLICY").to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("FILE").to_matchable(),
                            Ref::keyword("FORMAT").to_matchable(),
                        ])
                        .to_matchable(),
                    ])
                    .to_matchable(),
                    Ref::new("ObjectReferenceSegment").to_matchable(),
                    Ref::keyword("IS").to_matchable(),
                    Ref::new("QuotedLiteralSegment").to_matchable(),
                ])
                .to_matchable()
            })
            .to_matchable()
            .into(),
        ),
    ]);

    snowflake_dialect.replace_grammar(
        "UseStatementSegment",
        Sequence::new(vec![
            Ref::keyword("USE").to_matchable(),
            one_of(vec![
                Sequence::new(vec![
                    Ref::keyword("ROLE").to_matchable(),
                    Ref::new("ObjectReferenceSegment").to_matchable(),
                ])
                .to_matchable(),
                Sequence::new(vec![
                    Ref::keyword("WAREHOUSE").to_matchable(),
                    Ref::new("ObjectReferenceSegment").to_matchable(),
                ])
                .to_matchable(),
                Sequence::new(vec![
                    Ref::keyword("DATABASE").optional().to_matchable(),
                    Ref::new("DatabaseReferenceSegment").to_matchable(),
                ])
                .to_matchable(),
                Sequence::new(vec![
                    Ref::keyword("SCHEMA").optional().to_matchable(),
                    Ref::new("SchemaReferenceSegment").to_matchable(),
                ])
                .to_matchable(),
                Sequence::new(vec![
                    Ref::keyword("SECONDARY").to_matchable(),
                    Ref::keyword("ROLES").to_matchable(),
                    one_of(vec![
                        Ref::keyword("ALL").to_matchable(),
                        Ref::keyword("NONE").to_matchable(),
                    ])
                    .to_matchable(),
                ])
                .to_matchable(),
            ])
            .to_matchable(),
        ])
        .to_matchable(),
    );

    snowflake_dialect.add([(
        "CallStatementSegment".into(),
        NodeMatcher::new(SyntaxKind::CallStatement, |_| {
            Sequence::new(vec![
                Ref::keyword("CALL").to_matchable(),
                Sequence::new(vec![
                    Ref::new("FunctionNameSegment").to_matchable(),
                    Bracketed::new(vec![
                        Ref::new("FunctionContentsGrammar")
                            .optional()
                            .to_matchable(),
                    ])
                    .config(|this| this.parse_mode(ParseMode::Greedy))
                    .to_matchable(),
                ])
                .to_matchable(),
            ])
            .to_matchable()
        })
        .to_matchable()
        .into(),
    )]);

    snowflake_dialect.replace_grammar(
        "LimitClauseSegment",
        one_of(vec![
            Sequence::new(vec![
                Ref::keyword("LIMIT").to_matchable(),
                MetaSegment::indent().to_matchable(),
                Ref::new("LimitLiteralGrammar").to_matchable(),
                MetaSegment::dedent().to_matchable(),
                Sequence::new(vec![
                    Ref::keyword("OFFSET").to_matchable(),
                    MetaSegment::indent().to_matchable(),
                    Ref::new("LimitLiteralGrammar").to_matchable(),
                    MetaSegment::dedent().to_matchable(),
                ])
                .config(|this| this.optional())
                .to_matchable(),
            ])
            .to_matchable(),
            Sequence::new(vec![
                Sequence::new(vec![
                    Ref::keyword("OFFSET").to_matchable(),
                    MetaSegment::indent().to_matchable(),
                    Ref::new("LimitLiteralGrammar").to_matchable(),
                    one_of(vec![
                        Ref::keyword("ROW").to_matchable(),
                        Ref::keyword("ROWS").to_matchable(),
                    ])
                    .config(|this| this.optional())
                    .to_matchable(),
                    MetaSegment::dedent().to_matchable(),
                ])
                .config(|this| this.optional())
                .to_matchable(),
                Ref::keyword("FETCH").to_matchable(),
                MetaSegment::indent().to_matchable(),
                one_of(vec![
                    Ref::keyword("FIRST").to_matchable(),
                    Ref::keyword("NEXT").to_matchable(),
                ])
                .config(|this| this.optional())
                .to_matchable(),
                Ref::new("LimitLiteralGrammar").to_matchable(),
                one_of(vec![
                    Ref::keyword("ROW").to_matchable(),
                    Ref::keyword("ROWS").to_matchable(),
                ])
                .config(|this| this.optional())
                .to_matchable(),
                Ref::keyword("ONLY").optional().to_matchable(),
                MetaSegment::dedent().to_matchable(),
            ])
            .to_matchable(),
        ])
        .to_matchable(),
    );

    snowflake_dialect.replace_grammar(
        "SelectClauseSegment",
        ansi::select_clause_segment().copy(
            None,
            None,
            None,
            None,
            vec![
                Ref::keyword("FETCH").to_matchable(),
                Ref::keyword("OFFSET").to_matchable(),
            ],
            false,
        ),
    );

    snowflake_dialect.replace_grammar(
        "OrderByClauseSegment",
        Sequence::new(vec![
            Ref::keyword("ORDER").to_matchable(),
            Ref::keyword("BY").to_matchable(),
            MetaSegment::indent().to_matchable(),
            Delimited::new(vec![
                Sequence::new(vec![
                    one_of(vec![
                        Ref::new("ColumnReferenceSegment").to_matchable(),
                        Ref::new("NumericLiteralSegment").to_matchable(),
                        Ref::new("ExpressionSegment").to_matchable(),
                    ])
                    .to_matchable(),
                    one_of(vec![
                        Ref::keyword("ASC").to_matchable(),
                        Ref::keyword("DESC").to_matchable(),
                    ])
                    .config(|this| this.optional())
                    .to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("NULLS").to_matchable(),
                        one_of(vec![
                            Ref::keyword("FIRST").to_matchable(),
                            Ref::keyword("LAST").to_matchable(),
                        ])
                        .to_matchable(),
                    ])
                    .config(|this| this.optional())
                    .to_matchable(),
                ])
                .to_matchable(),
            ])
            .config(|this| {
                this.terminators = vec![
                    Ref::keyword("LIMIT").to_matchable(),
                    Ref::keyword("FETCH").to_matchable(),
                    Ref::keyword("OFFSET").to_matchable(),
                    Ref::new("FrameClauseUnitGrammar").to_matchable(),
                ]
            })
            .to_matchable(),
            MetaSegment::dedent().to_matchable(),
        ])
        .to_matchable(),
    );

    snowflake_dialect.replace_grammar("FrameClauseSegment", {
        let frame_extent = one_of(vec![
            Sequence::new(vec![
                Ref::keyword("CURRENT").to_matchable(),
                Ref::keyword("ROW").to_matchable(),
            ])
            .to_matchable(),
            Sequence::new(vec![
                one_of(vec![
                    Ref::new("NumericLiteralSegment").to_matchable(),
                    Ref::new("ReferencedVariableNameSegment").to_matchable(),
                    Ref::keyword("UNBOUNDED").to_matchable(),
                ])
                .to_matchable(),
                one_of(vec![
                    Ref::keyword("PRECEDING").to_matchable(),
                    Ref::keyword("FOLLOWING").to_matchable(),
                ])
                .to_matchable(),
            ])
            .to_matchable(),
        ]);

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

    snowflake_dialect.add([
        (
            "DropProcedureStatementSegment".into(),
            NodeMatcher::new(SyntaxKind::DropProcedureStatement, |_| {
                Sequence::new(vec![
                    Ref::keyword("DROP").to_matchable(),
                    Ref::keyword("PROCEDURE").to_matchable(),
                    Ref::new("IfExistsGrammar").optional().to_matchable(),
                    Ref::new("FunctionNameSegment").to_matchable(),
                    Ref::new("FunctionParameterListGrammar").to_matchable(),
                ])
                .to_matchable()
            })
            .to_matchable()
            .into(),
        ),
        (
            "DropExternalTableStatementSegment".into(),
            NodeMatcher::new(SyntaxKind::DropExternalTableStatement, |_| {
                Sequence::new(vec![
                    Ref::keyword("DROP").to_matchable(),
                    Ref::keyword("EXTERNAL").to_matchable(),
                    Ref::keyword("TABLE").to_matchable(),
                    Ref::new("IfExistsGrammar").optional().to_matchable(),
                    Ref::new("TableReferenceSegment").to_matchable(),
                    Ref::new("DropBehaviorGrammar").optional().to_matchable(),
                ])
                .to_matchable()
            })
            .to_matchable()
            .into(),
        ),
        (
            "DropFunctionStatementSegment".into(),
            NodeMatcher::new(SyntaxKind::DropFunctionStatement, |_| {
                Sequence::new(vec![
                    Ref::keyword("DROP").to_matchable(),
                    Ref::keyword("EXTERNAL").optional().to_matchable(),
                    Ref::keyword("FUNCTION").to_matchable(),
                    Ref::new("IfExistsGrammar").optional().to_matchable(),
                    Ref::new("FunctionNameSegment").to_matchable(),
                    Ref::new("FunctionParameterListGrammar").to_matchable(),
                ])
                .to_matchable()
            })
            .to_matchable()
            .into(),
        ),
        (
            "DropMaterializedViewStatementSegment".into(),
            NodeMatcher::new(SyntaxKind::DropMaterializedViewStatement, |_| {
                Sequence::new(vec![
                    Ref::keyword("DROP").to_matchable(),
                    Ref::keyword("MATERIALIZED").to_matchable(),
                    Ref::keyword("VIEW").to_matchable(),
                    Ref::new("IfExistsGrammar").optional().to_matchable(),
                    Ref::new("TableReferenceSegment").to_matchable(),
                ])
                .to_matchable()
            })
            .to_matchable()
            .into(),
        ),
        (
            "DropObjectStatementSegment".into(),
            NodeMatcher::new(SyntaxKind::DropObjectStatement, |_| {
                Sequence::new(vec![
                    Ref::keyword("DROP").to_matchable(),
                    one_of(vec![
                        Sequence::new(vec![
                            one_of(vec![
                                Ref::keyword("CONNECTION").to_matchable(),
                                Sequence::new(vec![
                                    Ref::keyword("FILE").to_matchable(),
                                    Ref::keyword("FORMAT").to_matchable(),
                                ])
                                .to_matchable(),
                                Sequence::new(vec![
                                    one_of(vec![
                                        Ref::keyword("API").to_matchable(),
                                        Ref::keyword("NOTIFICATION").to_matchable(),
                                        Ref::keyword("SECURITY").to_matchable(),
                                        Ref::keyword("STORAGE").to_matchable(),
                                    ])
                                    .config(|this| this.optional())
                                    .to_matchable(),
                                    Ref::keyword("INTEGRATION").to_matchable(),
                                ])
                                .to_matchable(),
                                Ref::keyword("PIPE").to_matchable(),
                                Sequence::new(vec![
                                    Ref::keyword("ROW").to_matchable(),
                                    Ref::keyword("ACCESS").to_matchable(),
                                    Ref::keyword("POLICY").to_matchable(),
                                ])
                                .to_matchable(),
                                Ref::keyword("STAGE").to_matchable(),
                                Ref::keyword("STREAM").to_matchable(),
                                Ref::keyword("TAG").to_matchable(),
                                Ref::keyword("TASK").to_matchable(),
                            ])
                            .to_matchable(),
                            Ref::new("IfExistsGrammar").optional().to_matchable(),
                            Ref::new("ObjectReferenceSegment").to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            one_of(vec![
                                Sequence::new(vec![
                                    Ref::keyword("RESOURCE").to_matchable(),
                                    Ref::keyword("MONITOR").to_matchable(),
                                ])
                                .to_matchable(),
                                Ref::keyword("SHARE").to_matchable(),
                            ])
                            .to_matchable(),
                            Ref::new("ObjectReferenceSegment").to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            one_of(vec![
                                Sequence::new(vec![
                                    Ref::keyword("MANAGED").to_matchable(),
                                    Ref::keyword("ACCOUNT").to_matchable(),
                                ])
                                .to_matchable(),
                                Sequence::new(vec![
                                    Ref::keyword("MASKING").to_matchable(),
                                    Ref::keyword("POLICY").to_matchable(),
                                ])
                                .to_matchable(),
                            ])
                            .to_matchable(),
                            Ref::new("SingleIdentifierGrammar").to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            one_of(vec![
                                Sequence::new(vec![
                                    Ref::keyword("NETWORK").to_matchable(),
                                    Ref::keyword("POLICY").to_matchable(),
                                ])
                                .to_matchable(),
                            ])
                            .to_matchable(),
                            Ref::new("IfExistsGrammar").optional().to_matchable(),
                            Ref::new("SingleIdentifierGrammar").to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            one_of(vec![
                                Ref::keyword("WAREHOUSE").to_matchable(),
                                Sequence::new(vec![
                                    Ref::keyword("SESSION").to_matchable(),
                                    Ref::keyword("POLICY").to_matchable(),
                                ])
                                .to_matchable(),
                            ])
                            .to_matchable(),
                            Ref::new("IfExistsGrammar").optional().to_matchable(),
                            Ref::new("SingleIdentifierGrammar").to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("SEQUENCE").to_matchable(),
                            Ref::new("IfExistsGrammar").optional().to_matchable(),
                            Ref::new("ObjectReferenceSegment").to_matchable(),
                            Ref::new("DropBehaviorGrammar").optional().to_matchable(),
                        ])
                        .to_matchable(),
                    ])
                    .to_matchable(),
                ])
                .to_matchable()
            })
            .to_matchable()
            .into(),
        ),
        (
            "ListStatementSegment".into(),
            NodeMatcher::new(SyntaxKind::ListStatement, |_| {
                Sequence::new(vec![
                    one_of(vec![
                        Ref::keyword("LIST").to_matchable(),
                        Ref::keyword("LS").to_matchable(),
                    ])
                    .to_matchable(),
                    Ref::new("StagePath").to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("PATTERN").to_matchable(),
                        Ref::new("EqualsSegment").to_matchable(),
                        Ref::new("QuotedLiteralSegment").to_matchable(),
                    ])
                    .config(|this| this.optional())
                    .to_matchable(),
                ])
                .to_matchable()
            })
            .to_matchable()
            .into(),
        ),
        (
            "GetStatementSegment".into(),
            NodeMatcher::new(SyntaxKind::GetStatement, |_| {
                Sequence::new(vec![
                    Ref::keyword("GET").to_matchable(),
                    Ref::new("StagePath").to_matchable(),
                    one_of(vec![
                        Ref::new("UnquotedFilePath").to_matchable(),
                        Ref::new("QuotedLiteralSegment").to_matchable(),
                    ])
                    .to_matchable(),
                    any_set_of(vec![
                        Sequence::new(vec![
                            Ref::keyword("PARALLEL").to_matchable(),
                            Ref::new("EqualsSegment").to_matchable(),
                            Ref::new("IntegerSegment").to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("PATTERN").to_matchable(),
                            Ref::new("EqualsSegment").to_matchable(),
                            one_of(vec![
                                Ref::new("QuotedLiteralSegment").to_matchable(),
                                Ref::new("ReferencedVariableNameSegment").to_matchable(),
                            ])
                            .to_matchable(),
                        ])
                        .to_matchable(),
                    ])
                    .to_matchable(),
                ])
                .to_matchable()
            })
            .to_matchable()
            .into(),
        ),
        (
            "PutStatementSegment".into(),
            NodeMatcher::new(SyntaxKind::PutStatement, |_| {
                Sequence::new(vec![
                    Ref::keyword("PUT").to_matchable(),
                    one_of(vec![
                        Ref::new("UnquotedFilePath").to_matchable(),
                        Ref::new("QuotedLiteralSegment").to_matchable(),
                    ])
                    .to_matchable(),
                    Ref::new("StagePath").to_matchable(),
                    any_set_of(vec![
                        Sequence::new(vec![
                            Ref::keyword("PARALLEL").to_matchable(),
                            Ref::new("EqualsSegment").to_matchable(),
                            Ref::new("IntegerSegment").to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("AUTO_COMPRESS").to_matchable(),
                            Ref::new("EqualsSegment").to_matchable(),
                            Ref::new("BooleanLiteralGrammar").to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("SOURCE_COMPRESSION").to_matchable(),
                            Ref::new("EqualsSegment").to_matchable(),
                            Ref::new("CompressionType").to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("OVERWRITE").to_matchable(),
                            Ref::new("EqualsSegment").to_matchable(),
                            Ref::new("BooleanLiteralGrammar").to_matchable(),
                        ])
                        .to_matchable(),
                    ])
                    .to_matchable(),
                ])
                .to_matchable()
            })
            .to_matchable()
            .into(),
        ),
        (
            "RemoveStatementSegment".into(),
            NodeMatcher::new(SyntaxKind::RemoveStatement, |_| {
                Sequence::new(vec![
                    one_of(vec![
                        Ref::keyword("REMOVE").to_matchable(),
                        Ref::keyword("RM").to_matchable(),
                    ])
                    .to_matchable(),
                    Ref::new("StagePath").to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("PATTERN").to_matchable(),
                        Ref::new("EqualsSegment").to_matchable(),
                        one_of(vec![
                            Ref::new("QuotedLiteralSegment").to_matchable(),
                            Ref::new("ReferencedVariableNameSegment").to_matchable(),
                        ])
                        .to_matchable(),
                    ])
                    .config(|this| this.optional())
                    .to_matchable(),
                ])
                .to_matchable()
            })
            .to_matchable()
            .into(),
        ),
    ]);

    snowflake_dialect.replace_grammar(
        "SetOperatorSegment",
        one_of(vec![
            Sequence::new(vec![
                Ref::keyword("UNION").to_matchable(),
                one_of(vec![
                    Ref::keyword("DISTINCT").to_matchable(),
                    Ref::keyword("ALL").to_matchable(),
                ])
                .config(|this| this.optional())
                .to_matchable(),
            ])
            .to_matchable(),
            Sequence::new(vec![
                one_of(vec![
                    Ref::keyword("INTERSECT").to_matchable(),
                    Ref::keyword("EXCEPT").to_matchable(),
                ])
                .to_matchable(),
                Ref::keyword("ALL").optional().to_matchable(),
            ])
            .to_matchable(),
            Ref::keyword("MINUS").to_matchable(),
        ])
        .to_matchable(),
    );

    snowflake_dialect.add([(
        "ShorthandCastSegment".into(),
        NodeMatcher::new(SyntaxKind::CastExpression, |_| {
            Sequence::new(vec![
                one_of(vec![
                    Ref::new("Expression_D_Grammar").to_matchable(),
                    Ref::new("CaseExpressionSegment").to_matchable(),
                ])
                .to_matchable(),
                AnyNumberOf::new(vec![
                    Sequence::new(vec![
                        Ref::new("CastOperatorSegment").to_matchable(),
                        Ref::new("DatatypeSegment").to_matchable(),
                        one_of(vec![
                            Ref::new("TimeZoneGrammar").to_matchable(),
                            AnyNumberOf::new(vec![Ref::new("ArrayAccessorSegment").to_matchable()])
                                .to_matchable(),
                        ])
                        .config(|this| this.optional())
                        .to_matchable(),
                    ])
                    .to_matchable(),
                ])
                .config(|this| this.min_times(1))
                .to_matchable(),
            ])
            .to_matchable()
        })
        .to_matchable()
        .into(),
    )]);

    // Resource Monitor statements
    snowflake_dialect.add([
        (
            // A `RESOURCE MONITOR` options statement.
            // https://docs.snowflake.com/en/sql-reference/sql/create-resource-monitor
            // https://docs.snowflake.com/en/sql-reference/sql/alter-resource-monitor
            "ResourceMonitorOptionsSegment".into(),
            AnyNumberOf::new(vec![
                Sequence::new(vec![
                    Ref::keyword("CREDIT_QUOTA").to_matchable(),
                    Ref::new("EqualsSegment").to_matchable(),
                    Ref::new("NumericLiteralSegment").to_matchable(),
                ])
                .to_matchable(),
                Sequence::new(vec![
                    Ref::keyword("FREQUENCY").to_matchable(),
                    Ref::new("EqualsSegment").to_matchable(),
                    one_of(vec![
                        Ref::keyword("DAILY").to_matchable(),
                        Ref::keyword("WEEKLY").to_matchable(),
                        Ref::keyword("MONTHLY").to_matchable(),
                        Ref::keyword("YEARLY").to_matchable(),
                        Ref::keyword("NEVER").to_matchable(),
                    ])
                    .to_matchable(),
                ])
                .to_matchable(),
                Sequence::new(vec![
                    Ref::keyword("START_TIMESTAMP").to_matchable(),
                    Ref::new("EqualsSegment").to_matchable(),
                    one_of(vec![
                        Ref::new("QuotedLiteralSegment").to_matchable(),
                        Ref::keyword("IMMEDIATELY").to_matchable(),
                    ])
                    .to_matchable(),
                ])
                .to_matchable(),
                Sequence::new(vec![
                    Ref::keyword("END_TIMESTAMP").to_matchable(),
                    Ref::new("EqualsSegment").to_matchable(),
                    Ref::new("QuotedLiteralSegment").to_matchable(),
                ])
                .to_matchable(),
                Sequence::new(vec![
                    Ref::keyword("NOTIFY_USERS").to_matchable(),
                    Ref::new("EqualsSegment").to_matchable(),
                    Bracketed::new(vec![
                        Delimited::new(vec![Ref::new("SingleIdentifierGrammar").to_matchable()])
                            .to_matchable(),
                    ])
                    .to_matchable(),
                ])
                .to_matchable(),
                Sequence::new(vec![
                    Ref::keyword("TRIGGERS").to_matchable(),
                    AnyNumberOf::new(vec![
                        Sequence::new(vec![
                            Ref::keyword("ON").to_matchable(),
                            Ref::new("NumericLiteralSegment").to_matchable(),
                            Ref::keyword("PERCENT").to_matchable(),
                            Ref::keyword("DO").to_matchable(),
                            one_of(vec![
                                Ref::keyword("NOTIFY").to_matchable(),
                                Ref::keyword("SUSPEND").to_matchable(),
                                Ref::keyword("SUSPEND_IMMEDIATE").to_matchable(),
                            ])
                            .to_matchable(),
                        ])
                        .to_matchable(),
                    ])
                    .to_matchable(),
                ])
                .to_matchable(),
            ])
            .to_matchable()
            .into(),
        ),
        (
            // A `CREATE RESOURCE MONITOR` statement.
            // https://docs.snowflake.com/en/sql-reference/sql/create-resource-monitor
            "CreateResourceMonitorStatementSegment".into(),
            Sequence::new(vec![
                Ref::keyword("CREATE").to_matchable(),
                Ref::new("OrReplaceGrammar").optional().to_matchable(),
                Ref::new("IfNotExistsGrammar").optional().to_matchable(),
                Sequence::new(vec![
                    Ref::keyword("RESOURCE").to_matchable(),
                    Ref::keyword("MONITOR").to_matchable(),
                ])
                .to_matchable(),
                Ref::new("ObjectReferenceSegment").to_matchable(),
                Ref::keyword("WITH").to_matchable(),
                Ref::new("ResourceMonitorOptionsSegment").to_matchable(),
            ])
            .to_matchable()
            .into(),
        ),
        (
            // An `ALTER RESOURCE MONITOR` statement.
            // https://docs.snowflake.com/en/sql-reference/sql/alter-resource-monitor
            "AlterResourceMonitorStatementSegment".into(),
            Sequence::new(vec![
                Ref::keyword("ALTER").to_matchable(),
                Sequence::new(vec![
                    Ref::keyword("RESOURCE").to_matchable(),
                    Ref::keyword("MONITOR").to_matchable(),
                ])
                .to_matchable(),
                Ref::new("IfExistsGrammar").optional().to_matchable(),
                Ref::new("ObjectReferenceSegment").to_matchable(),
                Ref::keyword("SET").to_matchable(),
                Ref::new("ResourceMonitorOptionsSegment").to_matchable(),
            ])
            .to_matchable()
            .into(),
        ),
        (
            // A `DROP RESOURCE MONITOR` statement.
            // https://docs.snowflake.com/en/sql-reference/sql/drop-resource-monitor
            "DropResourceMonitorStatementSegment".into(),
            Sequence::new(vec![
                Ref::keyword("DROP").to_matchable(),
                Sequence::new(vec![
                    Ref::keyword("RESOURCE").to_matchable(),
                    Ref::keyword("MONITOR").to_matchable(),
                ])
                .to_matchable(),
                Ref::new("IfExistsGrammar").optional().to_matchable(),
                Ref::new("ObjectReferenceSegment").to_matchable(),
            ])
            .to_matchable()
            .into(),
        ),
        (
            // An `ALTER DATABASE` statement.
            // https://docs.snowflake.com/en/sql-reference/sql/alter-database
            "AlterDatabaseSegment".into(),
            NodeMatcher::new(SyntaxKind::AlterDatabaseStatement, |_| {
                Sequence::new(vec![
                    Ref::keyword("ALTER").to_matchable(),
                    Ref::keyword("DATABASE").to_matchable(),
                    Ref::new("IfExistsGrammar").optional().to_matchable(),
                    Ref::new("ObjectReferenceSegment").to_matchable(),
                    one_of(vec![
                        Sequence::new(vec![
                            Ref::keyword("RENAME").to_matchable(),
                            Ref::keyword("TO").to_matchable(),
                            Ref::new("ObjectReferenceSegment").to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("SWAP").to_matchable(),
                            Ref::keyword("WITH").to_matchable(),
                            Ref::new("ObjectReferenceSegment").to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("SET").to_matchable(),
                            one_of(vec![
                                Ref::new("TagEqualsSegment").to_matchable(),
                                Delimited::new(vec![
                                    Sequence::new(vec![
                                        Ref::new("ParameterNameSegment").to_matchable(),
                                        Ref::new("EqualsSegment").to_matchable(),
                                        one_of(vec![
                                            Ref::new("BooleanLiteralGrammar").to_matchable(),
                                            Ref::new("QuotedLiteralSegment").to_matchable(),
                                            Ref::new("NumericLiteralSegment").to_matchable(),
                                        ])
                                        .to_matchable(),
                                    ])
                                    .to_matchable(),
                                ])
                                .to_matchable(),
                            ])
                            .to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("UNSET").to_matchable(),
                            Ref::keyword("TAG").to_matchable(),
                            Delimited::new(vec![Ref::new("TagReferenceSegment").to_matchable()])
                                .to_matchable(),
                        ])
                        .to_matchable(),
                        Sequence::new(vec![
                            Ref::keyword("UNSET").to_matchable(),
                            Delimited::new(vec![
                                one_of(vec![
                                    Ref::keyword("DATA_RETENTION_TIME_IN_DAYS").to_matchable(),
                                    Ref::keyword("MAX_DATA_EXTENSION_TIME_IN_DAYS").to_matchable(),
                                    Ref::keyword("DEFAULT_DDL_COLLATION").to_matchable(),
                                    Ref::keyword("COMMENT").to_matchable(),
                                ])
                                .to_matchable(),
                            ])
                            .to_matchable(),
                        ])
                        .to_matchable(),
                    ])
                    .to_matchable(),
                ])
                .to_matchable()
            })
            .to_matchable()
            .into(),
        ),
        (
            // An `ALTER MASKING POLICY` statement.
            // https://docs.snowflake.com/en/sql-reference/sql/alter-masking-policy
            "AlterMaskingPolicySegment".into(),
            Sequence::new(vec![
                Ref::keyword("ALTER").to_matchable(),
                Ref::keyword("MASKING").to_matchable(),
                Ref::keyword("POLICY").to_matchable(),
                Ref::new("IfExistsGrammar").optional().to_matchable(),
                Ref::new("ObjectReferenceSegment").to_matchable(),
                one_of(vec![
                    Sequence::new(vec![
                        Ref::keyword("RENAME").to_matchable(),
                        Ref::keyword("TO").to_matchable(),
                        Ref::new("ObjectReferenceSegment").to_matchable(),
                    ])
                    .to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("SET").to_matchable(),
                        Ref::keyword("BODY").to_matchable(),
                        Ref::new("FunctionAssignerSegment").to_matchable(),
                        Ref::new("ExpressionSegment").to_matchable(),
                    ])
                    .to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("SET").to_matchable(),
                        Ref::new("TagEqualsSegment").to_matchable(),
                    ])
                    .to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("UNSET").to_matchable(),
                        Ref::keyword("TAG").to_matchable(),
                        Delimited::new(vec![Ref::new("TagReferenceSegment").to_matchable()])
                            .to_matchable(),
                    ])
                    .to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("SET").to_matchable(),
                        Ref::keyword("COMMENT").to_matchable(),
                        Ref::new("EqualsSegment").to_matchable(),
                        Ref::new("QuotedLiteralSegment").to_matchable(),
                    ])
                    .to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("UNSET").to_matchable(),
                        Ref::keyword("COMMENT").to_matchable(),
                    ])
                    .to_matchable(),
                ])
                .to_matchable(),
            ])
            .to_matchable()
            .into(),
        ),
        (
            // An `ALTER NETWORK POLICY` statement.
            // https://docs.snowflake.com/en/sql-reference/sql/alter-network-policy
            "AlterNetworkPolicyStatementSegment".into(),
            Sequence::new(vec![
                Ref::keyword("ALTER").to_matchable(),
                Ref::keyword("NETWORK").to_matchable(),
                Ref::keyword("POLICY").to_matchable(),
                Ref::new("IfExistsGrammar").optional().to_matchable(),
                Ref::new("SingleIdentifierGrammar").to_matchable(),
                one_of(vec![
                    Sequence::new(vec![
                        Ref::keyword("SET").to_matchable(),
                        any_set_of(vec![
                            Sequence::new(vec![
                                Ref::keyword("ALLOWED_NETWORK_RULE_LIST").to_matchable(),
                                Ref::new("EqualsSegment").to_matchable(),
                                Bracketed::new(vec![
                                    Delimited::new(vec![
                                        Ref::new("QuotedLiteralSegment").to_matchable(),
                                    ])
                                    .to_matchable(),
                                ])
                                .to_matchable(),
                            ])
                            .to_matchable(),
                            Sequence::new(vec![
                                Ref::keyword("BLOCKED_NETWORK_RULE_LIST").to_matchable(),
                                Ref::new("EqualsSegment").to_matchable(),
                                Bracketed::new(vec![
                                    Delimited::new(vec![
                                        Ref::new("QuotedLiteralSegment").to_matchable(),
                                    ])
                                    .to_matchable(),
                                ])
                                .to_matchable(),
                            ])
                            .to_matchable(),
                            Sequence::new(vec![
                                Ref::keyword("ALLOWED_IP_LIST").to_matchable(),
                                Ref::new("EqualsSegment").to_matchable(),
                                Bracketed::new(vec![
                                    Delimited::new(vec![
                                        Ref::new("QuotedLiteralSegment").to_matchable(),
                                    ])
                                    .to_matchable(),
                                ])
                                .to_matchable(),
                            ])
                            .to_matchable(),
                            Sequence::new(vec![
                                Ref::keyword("BLOCKED_IP_LIST").to_matchable(),
                                Ref::new("EqualsSegment").to_matchable(),
                                Bracketed::new(vec![
                                    Delimited::new(vec![
                                        Ref::new("QuotedLiteralSegment").to_matchable(),
                                    ])
                                    .to_matchable(),
                                ])
                                .to_matchable(),
                            ])
                            .to_matchable(),
                            Sequence::new(vec![
                                Ref::keyword("COMMENT").to_matchable(),
                                Ref::new("EqualsSegment").to_matchable(),
                                Ref::new("QuotedLiteralSegment").to_matchable(),
                            ])
                            .to_matchable(),
                        ])
                        .to_matchable(),
                    ])
                    .to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("UNSET").to_matchable(),
                        Ref::keyword("COMMENT").to_matchable(),
                    ])
                    .to_matchable(),
                    Sequence::new(vec![
                        one_of(vec![
                            Ref::keyword("ADD").to_matchable(),
                            Ref::keyword("REMOVE").to_matchable(),
                        ])
                        .to_matchable(),
                        one_of(vec![
                            Ref::keyword("ALLOWED_NETWORK_RULE_LIST").to_matchable(),
                            Ref::keyword("BLOCKED_NETWORK_RULE_LIST").to_matchable(),
                        ])
                        .to_matchable(),
                        Ref::new("EqualsSegment").to_matchable(),
                        Ref::new("QuotedLiteralSegment").to_matchable(),
                    ])
                    .to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("RENAME").to_matchable(),
                        Ref::keyword("TO").to_matchable(),
                        Ref::new("SingleIdentifierGrammar").to_matchable(),
                    ])
                    .to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("SET").to_matchable(),
                        Ref::new("TagEqualsSegment").to_matchable(),
                    ])
                    .to_matchable(),
                    Sequence::new(vec![
                        Ref::keyword("UNSET").to_matchable(),
                        Ref::keyword("TAG").to_matchable(),
                        Ref::new("TagReferenceSegment").to_matchable(),
                        AnyNumberOf::new(vec![
                            Ref::new("CommaSegment").to_matchable(),
                            Ref::new("TagReferenceSegment").to_matchable(),
                        ])
                        .config(|this| this.optional())
                        .to_matchable(),
                    ])
                    .to_matchable(),
                ])
                .to_matchable(),
            ])
            .to_matchable()
            .into(),
        ),
    ]);

    snowflake_dialect.expand();
    snowflake_dialect
}
