// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

//! This module defines:
//! 1) a list of constants for every keyword
//! 2) an `ALL_KEYWORDS` array with every keyword in it
//!    This is not a list of *reserved* keywords: some of these can be
//!    parsed as identifiers if the parser decides so. This means that
//!    new keywords can be added here without affecting the parse result.
//!
//!    As a matter of fact, most of these keywords are not used at all
//!    and could be removed.
//! 3) a `RESERVED_FOR_TABLE_ALIAS` array with keywords reserved in a
//!    "table alias" context.

#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};

#[cfg(feature = "visitor")]
use sqlparser_derive::{Visit, VisitMut};

/// Defines a string constant for a single keyword: `kw_def!(SELECT);`
/// expands to `pub const SELECT = "SELECT";`
macro_rules! kw_def {
    ($ident:ident = $string_keyword:expr) => {
        #[doc = concat!("The `", $string_keyword, "` SQL keyword.")]
        pub const $ident: &'static str = $string_keyword;
    };
    ($ident:ident) => {
        kw_def!($ident = stringify!($ident));
    };
}

/// Expands to a list of `kw_def!()` invocations for each keyword
/// and defines an ALL_KEYWORDS array of the defined constants.
macro_rules! define_keywords {
    ($(
        $ident:ident $(= $string_keyword:expr)?
    ),*) => {
        #[derive(Debug, Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Hash)]
        #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
        #[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
        #[allow(non_camel_case_types)]
        /// An enumeration of SQL keywords recognized by the parser.
        pub enum Keyword {
            /// Represents no keyword.
            NoKeyword,
            $(
                #[doc = concat!("The `", stringify!($ident), "` SQL keyword.")]
                $ident
            ),*
        }

        /// Array of all `Keyword` enum values in declaration order.
        pub const ALL_KEYWORDS_INDEX: &[Keyword] = &[
            $(Keyword::$ident),*
        ];

        $(kw_def!($ident $(= $string_keyword)?);)*
        /// Array of all SQL keywords as string constants.
        pub const ALL_KEYWORDS: &[&str] = &[
            $($ident),*
        ];

        impl core::fmt::Display for Keyword {
            fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
                match self {
                    Keyword::NoKeyword => write!(f, "NoKeyword"),
                    $(Keyword::$ident => write!(f, "{}", $ident),)*
                }
            }
        }
    };
}

// The following keywords should be sorted to be able to match using binary search
define_keywords!(
    ABORT,
    ABS,
    ABSENT,
    ABSOLUTE,
    ACCEPTANYDATE,
    ACCEPTINVCHARS,
    ACCESS,
    ACCOUNT,
    ACTION,
    ADD,
    ADDQUOTES,
    ADMIN,
    AFTER,
    AGAINST,
    AGGREGATE,
    AGGREGATION,
    ALERT,
    ALGORITHM,
    ALIAS,
    ALIGNMENT,
    ALL,
    ALLOCATE,
    ALLOWOVERWRITE,
    ALTER,
    ALWAYS,
    ANALYZE,
    AND,
    ANTI,
    ANY,
    APPLICATION,
    APPLY,
    APPLYBUDGET,
    ARCHIVE,
    ARE,
    ARRAY,
    ARRAY_MAX_CARDINALITY,
    AS,
    ASC,
    ASENSITIVE,
    ASOF,
    ASSERT,
    ASYMMETRIC,
    AT,
    ATOMIC,
    ATTACH,
    AUDIT,
    AUTHENTICATION,
    AUTHORIZATION,
    AUTHORIZATIONS,
    AUTO,
    AUTOEXTEND_SIZE,
    AUTOINCREMENT,
    AUTO_INCREMENT,
    AVG,
    AVG_ROW_LENGTH,
    AVRO,
    BACKUP,
    BACKWARD,
    BASE64,
    BASE_LOCATION,
    BEFORE,
    BEGIN,
    BEGIN_FRAME,
    BEGIN_PARTITION,
    BERNOULLI,
    BETWEEN,
    BIGDECIMAL,
    BIGINT,
    BIGNUMERIC,
    BINARY,
    BIND,
    BINDING,
    BIT,
    BLANKSASNULL,
    BLOB,
    BLOCK,
    BLOOM,
    BLOOMFILTER,
    BOOL,
    BOOLEAN,
    BOOST,
    BOTH,
    BOX,
    BRIN,
    BROWSE,
    BTREE,
    BUCKET,
    BUCKETS,
    BY,
    BYPASSRLS,
    BYTEA,
    BYTES,
    BZIP2,
    CACHE,
    CALL,
    CALLED,
    CANONICAL,
    CARDINALITY,
    CASCADE,
    CASCADED,
    CASE,
    CASES,
    CAST,
    CATALOG,
    CATALOGS,
    CATALOG_SYNC,
    CATALOG_SYNC_NAMESPACE_FLATTEN_DELIMITER,
    CATALOG_SYNC_NAMESPACE_MODE,
    CATCH,
    CATEGORY,
    CEIL,
    CEILING,
    CENTURY,
    CHAIN,
    CHANGE,
    CHANGES,
    CHANGE_TRACKING,
    CHANNEL,
    CHAR,
    CHARACTER,
    CHARACTERISTICS,
    CHARACTERS,
    CHARACTER_LENGTH,
    CHARSET,
    CHAR_LENGTH,
    CHECK,
    CHECKSUM,
    CIRCLE,
    CLASS,
    CLEANPATH,
    CLEAR,
    CLOB,
    CLONE,
    CLOSE,
    CLUSTER,
    CLUSTERED,
    CLUSTERING,
    COALESCE,
    COLLATABLE,
    COLLATE,
    COLLATION,
    COLLECT,
    COLLECTION,
    COLUMN,
    COLUMNS,
    COLUMNSTORE,
    COMMENT,
    COMMIT,
    COMMITTED,
    COMMUTATOR,
    COMPATIBLE,
    COMPRESS,
    COMPRESSION,
    COMPUPDATE,
    COMPUTE,
    CONCURRENTLY,
    CONDITION,
    CONFLICT,
    CONNECT,
    CONNECTION,
    CONNECTOR,
    CONNECT_BY_ROOT,
    CONSTRAINT,
    CONTACT,
    CONTAINS,
    CONTINUE,
    CONVERT,
    COPY,
    COPY_OPTIONS,
    CORR,
    CORRESPONDING,
    COST,
    COUNT,
    COVAR_POP,
    COVAR_SAMP,
    CREATE,
    CREATEDB,
    CREATEROLE,
    CREDENTIALS,
    CROSS,
    CSV,
    CUBE,
    CUME_DIST,
    CURRENT,
    CURRENT_CATALOG,
    CURRENT_DATE,
    CURRENT_DEFAULT_TRANSFORM_GROUP,
    CURRENT_PATH,
    CURRENT_ROLE,
    CURRENT_ROW,
    CURRENT_SCHEMA,
    CURRENT_TIME,
    CURRENT_TIMESTAMP,
    CURRENT_TRANSFORM_GROUP_FOR_TYPE,
    CURRENT_USER,
    CURSOR,
    CYCLE,
    DATA,
    DATABASE,
    DATABASES,
    DATA_RETENTION_TIME_IN_DAYS,
    DATE,
    DATE32,
    DATEFORMAT,
    DATETIME,
    DATETIME64,
    DAY,
    DAYOFWEEK,
    DAYOFYEAR,
    DAYS,
    DCPROPERTIES,
    DEALLOCATE,
    DEC,
    DECADE,
    DECIMAL,
    DECLARE,
    DEDUPLICATE,
    DEFAULT,
    DEFAULTS,
    DEFAULT_DDL_COLLATION,
    DEFAULT_MFA_METHOD,
    DEFAULT_SECONDARY_ROLES,
    DEFERRABLE,
    DEFERRED,
    DEFINE,
    DEFINED,
    DEFINER,
    DELAY,
    DELAYED,
    DELAY_KEY_WRITE,
    DELEGATED,
    DELETE,
    DELIMITED,
    DELIMITER,
    DELTA,
    DENSE_RANK,
    DENY,
    DEPENDS,
    DEREF,
    DESC,
    DESCRIBE,
    DETACH,
    DETAIL,
    DETERMINISTIC,
    DIMENSIONS,
    DIRECTORY,
    DISABLE,
    DISCARD,
    DISCONNECT,
    DISTINCT,
    DISTINCTROW,
    DISTKEY,
    DISTRIBUTE,
    DISTSTYLE,
    DIV,
    DO,
    DOMAIN,
    DOUBLE,
    DOW,
    DOWNSTREAM,
    DOY,
    DROP,
    DRY,
    DUO,
    DUPLICATE,
    DYNAMIC,
    EACH,
    ELEMENT,
    ELEMENTS,
    ELSE,
    ELSEIF,
    EMPTY,
    EMPTYASNULL,
    ENABLE,
    ENABLE_SCHEMA_EVOLUTION,
    ENCODING,
    ENCRYPTED,
    ENCRYPTION,
    END,
    END_EXEC = "END-EXEC",
    ENDPOINT,
    END_FRAME,
    END_PARTITION,
    ENFORCED,
    ENGINE,
    ENGINE_ATTRIBUTE,
    ENROLL,
    ENUM,
    ENUM16,
    ENUM8,
    EPHEMERAL,
    EPOCH,
    EQUALS,
    ERROR,
    ESCAPE,
    ESCAPED,
    ESTIMATE,
    EVEN,
    EVENT,
    EVERY,
    EVOLVE,
    EXCEPT,
    EXCEPTION,
    EXCHANGE,
    EXCLUDE,
    EXCLUDING,
    EXCLUSIVE,
    EXEC,
    EXECUTE,
    EXECUTION,
    EXISTS,
    EXP,
    EXPANSION,
    EXPLAIN,
    EXPLICIT,
    EXPORT,
    EXTEND,
    EXTENDED,
    EXTENSION,
    EXTERNAL,
    EXTERNAL_VOLUME,
    EXTRACT,
    FACTS,
    FAIL,
    FAILOVER,
    FALSE,
    FAMILY,
    FETCH,
    FIELDS,
    FILE,
    FILES,
    FILE_FORMAT,
    FILL,
    FILTER,
    FINAL,
    FIRST,
    FIRST_VALUE,
    FIXEDSTRING,
    FIXEDWIDTH,
    FLATTEN,
    FLOAT,
    FLOAT32,
    FLOAT4,
    FLOAT64,
    FLOAT8,
    FLOOR,
    FLUSH,
    FN,
    FOLLOWING,
    FOR,
    FORCE,
    FORCE_NOT_NULL,
    FORCE_NULL,
    FORCE_QUOTE,
    FOREIGN,
    FORMAT,
    FORMATTED,
    FORWARD,
    FRAME_ROW,
    FREE,
    FREEZE,
    FROM,
    FSCK,
    FULFILLMENT,
    FULL,
    FULLTEXT,
    FUNCTION,
    FUNCTIONS,
    FUSION,
    FUTURE,
    GB,
    GENERAL,
    GENERATE,
    GENERATED,
    GEOGRAPHY,
    GET,
    GIN,
    GIST,
    GLOBAL,
    GRANT,
    GRANTED,
    GRANTS,
    GRAPHVIZ,
    GROUP,
    GROUPING,
    GROUPS,
    GZIP,
    HASH,
    HASHES,
    HAVING,
    HEADER,
    HEAP,
    HIGH_PRIORITY,
    HISTORY,
    HIVEVAR,
    HOLD,
    HOSTS,
    HOUR,
    HOURS,
    HUGEINT,
    IAM_ROLE,
    ICEBERG,
    ID,
    IDENTIFIED,
    IDENTITY,
    IDENTITY_INSERT,
    IF,
    IGNORE,
    IGNOREHEADER,
    ILIKE,
    IMMEDIATE,
    IMMUTABLE,
    IMPORT,
    IMPORTED,
    IN,
    INCLUDE,
    INCLUDE_NULL_VALUES,
    INCLUDING,
    INCREMENT,
    INCREMENTAL,
    INDEX,
    INDICATOR,
    INHERIT,
    INHERITS,
    INITIALIZE,
    INITIALLY,
    INNER,
    INOUT,
    INPATH,
    INPLACE,
    INPUT,
    INPUTFORMAT,
    INSENSITIVE,
    INSERT,
    INSERT_METHOD,
    INSTALL,
    INSTANT,
    INSTEAD,
    INT,
    INT128,
    INT16,
    INT2,
    INT256,
    INT32,
    INT4,
    INT64,
    INT8,
    INTEGER,
    INTEGRATION,
    INTERNALLENGTH,
    INTERPOLATE,
    INTERSECT,
    INTERSECTION,
    INTERVAL,
    INTO,
    INVISIBLE,
    INVOKER,
    IO,
    IS,
    ISODOW,
    ISOLATION,
    ISOWEEK,
    ISOYEAR,
    ITEMS,
    JAR,
    JOIN,
    JSON,
    JSONB,
    JSONFILE,
    JSON_TABLE,
    JULIAN,
    KEY,
    KEYS,
    KEY_BLOCK_SIZE,
    KILL,
    LAG,
    LAMBDA,
    LANGUAGE,
    LARGE,
    LAST,
    LAST_VALUE,
    LATERAL,
    LEAD,
    LEADING,
    LEAKPROOF,
    LEAST,
    LEFT,
    LEFTARG,
    LEVEL,
    LIFECYCLE,
    LIKE,
    LIKE_REGEX,
    LIMIT,
    LINE,
    LINES,
    LIST,
    LISTEN,
    LISTING,
    LN,
    LOAD,
    LOCAL,
    LOCALTIME,
    LOCALTIMESTAMP,
    LOCATION,
    LOCK,
    LOCKED,
    LOG,
    LOGIN,
    LOGS,
    LONG,
    LONGBLOB,
    LONGTEXT,
    LOWCARDINALITY,
    LOWER,
    LOW_PRIORITY,
    LS,
    LSEG,
    MACRO,
    MAIN,
    MANAGE,
    MANAGED,
    MANAGEDLOCATION,
    MANIFEST,
    MAP,
    MASKING,
    MATCH,
    MATCHED,
    MATCHES,
    MATCH_CONDITION,
    MATCH_RECOGNIZE,
    MATERIALIZE,
    MATERIALIZED,
    MAX,
    MAXFILESIZE,
    MAXVALUE,
    MAX_DATA_EXTENSION_TIME_IN_DAYS,
    MAX_ROWS,
    MB,
    MEASURES,
    MEDIUMBLOB,
    MEDIUMINT,
    MEDIUMTEXT,
    MEMBER,
    MERGE,
    MERGES,
    MESSAGE,
    METADATA,
    METHOD,
    METRIC,
    METRICS,
    MFA,
    MICROSECOND,
    MICROSECONDS,
    MILLENIUM,
    MILLENNIUM,
    MILLISECOND,
    MILLISECONDS,
    MIN,
    MINUS,
    MINUTE,
    MINUTES,
    MINVALUE,
    MIN_ROWS,
    MOD,
    MODE,
    MODIFIES,
    MODIFY,
    MODULE,
    MODULUS,
    MONITOR,
    MONTH,
    MONTHS,
    MSCK,
    MULTIRANGE_TYPE_NAME,
    MULTISET,
    MUTATION,
    NAME,
    NAMES,
    NANOSECOND,
    NANOSECONDS,
    NATIONAL,
    NATURAL,
    NCHAR,
    NCLOB,
    NEGATOR,
    NEST,
    NESTED,
    NETWORK,
    NEW,
    NEXT,
    NFC,
    NFD,
    NFKC,
    NFKD,
    NO,
    NOBYPASSRLS,
    NOCOMPRESS,
    NOCREATEDB,
    NOCREATEROLE,
    NOCYCLE,
    NOINHERIT,
    NOLOGIN,
    NONE,
    NOORDER,
    NOREPLICATION,
    NORMALIZE,
    NORMALIZED,
    NOSCAN,
    NOSUPERUSER,
    NOT,
    NOTHING,
    NOTIFY,
    NOTNULL,
    NOWAIT,
    NO_WRITE_TO_BINLOG,
    NTH_VALUE,
    NTILE,
    NULL,
    NULLABLE,
    NULLIF,
    NULLS,
    NUMBER,
    NUMERIC,
    NVARCHAR,
    OBJECT,
    OBJECTS,
    OCCURRENCES_REGEX,
    OCTETS,
    OCTET_LENGTH,
    OF,
    OFF,
    OFFSET,
    OFFSETS,
    OLD,
    OMIT,
    ON,
    ONE,
    ONLY,
    ON_CREATE,
    ON_SCHEDULE,
    OPEN,
    OPENJSON,
    OPERATE,
    OPERATOR,
    OPTIMIZATION,
    OPTIMIZE,
    OPTIMIZED,
    OPTIMIZER_COSTS,
    OPTION,
    OPTIONS,
    OR,
    ORC,
    ORDER,
    ORDINALITY,
    ORGANIZATION,
    OTHER,
    OTP,
    OUT,
    OUTER,
    OUTPUT,
    OUTPUTFORMAT,
    OVER,
    OVERFLOW,
    OVERLAPS,
    OVERLAY,
    OVERRIDE,
    OVERWRITE,
    OWNED,
    OWNER,
    OWNERSHIP,
    PACKAGE,
    PACKAGES,
    PACK_KEYS,
    PARALLEL,
    PARAMETER,
    PARQUET,
    PART,
    PARTIAL,
    PARTITION,
    PARTITIONED,
    PARTITIONS,
    PASSEDBYVALUE,
    PASSING,
    PASSKEY,
    PASSWORD,
    PAST,
    PATH,
    PATTERN,
    PCTFREE,
    PER,
    PERCENT,
    PERCENTILE_CONT,
    PERCENTILE_DISC,
    PERCENT_RANK,
    PERIOD,
    PERMISSIVE,
    PERSISTENT,
    PIVOT,
    PLACING,
    PLAIN,
    PLAN,
    PLANS,
    POINT,
    POLICY,
    POLYGON,
    POOL,
    PORTION,
    POSITION,
    POSITION_REGEX,
    POWER,
    PRAGMA,
    PRECEDES,
    PRECEDING,
    PRECISION,
    PREFERRED,
    PREPARE,
    PRESERVE,
    PRESET,
    PREWHERE,
    PRIMARY,
    PRINT,
    PRIOR,
    PRIVILEGES,
    PROCEDURE,
    PROCESSLIST,
    PROFILE,
    PROGRAM,
    PROJECTION,
    PUBLIC,
    PURCHASE,
    PURGE,
    QUALIFY,
    QUARTER,
    QUERIES,
    QUERY,
    QUOTE,
    RAISE,
    RAISERROR,
    RANGE,
    RANK,
    RAW,
    RCFILE,
    READ,
    READS,
    READ_ONLY,
    REAL,
    RECEIVE,
    RECLUSTER,
    RECURSIVE,
    REF,
    REFERENCES,
    REFERENCING,
    REFRESH,
    REFRESH_MODE,
    REGCLASS,
    REGEXP,
    REGION,
    REGR_AVGX,
    REGR_AVGY,
    REGR_COUNT,
    REGR_INTERCEPT,
    REGR_R2,
    REGR_SLOPE,
    REGR_SXX,
    REGR_SXY,
    REGR_SYY,
    REINDEX,
    RELATIVE,
    RELAY,
    RELEASE,
    RELEASES,
    REMAINDER,
    REMOTE,
    REMOVE,
    REMOVEQUOTES,
    RENAME,
    REORG,
    REPAIR,
    REPEATABLE,
    REPLACE,
    REPLACE_INVALID_CHARACTERS,
    REPLICA,
    REPLICATE,
    REPLICATION,
    REQUIRE,
    RESET,
    RESOLVE,
    RESOURCE,
    RESPECT,
    RESTART,
    RESTRICT,
    RESTRICTED,
    RESTRICTIONS,
    RESTRICTIVE,
    RESULT,
    RESULTSET,
    RESUME,
    RETAIN,
    RETURN,
    RETURNING,
    RETURNS,
    REVOKE,
    RIGHT,
    RIGHTARG,
    RLIKE,
    RM,
    ROLE,
    ROLES,
    ROLLBACK,
    ROLLUP,
    ROOT,
    ROW,
    ROWGROUPSIZE,
    ROWID,
    ROWS,
    ROW_FORMAT,
    ROW_NUMBER,
    RULE,
    RUN,
    SAFE,
    SAFE_CAST,
    SAMPLE,
    SAVEPOINT,
    SCHEMA,
    SCHEMAS,
    SCOPE,
    SCROLL,
    SEARCH,
    SECOND,
    SECONDARY,
    SECONDARY_ENGINE_ATTRIBUTE,
    SECONDS,
    SECRET,
    SECURE,
    SECURITY,
    SEED,
    SELECT,
    SEMANTIC_VIEW,
    SEMI,
    SEND,
    SENSITIVE,
    SEPARATOR,
    SEQUENCE,
    SEQUENCEFILE,
    SEQUENCES,
    SERDE,
    SERDEPROPERTIES,
    SERIALIZABLE,
    SERVER,
    SERVICE,
    SESSION,
    SESSION_USER,
    SET,
    SETERROR,
    SETOF,
    SETS,
    SETTINGS,
    SHARE,
    SHARED,
    SHARING,
    SHOW,
    SIGNED,
    SIMILAR,
    SIMPLE,
    SIZE,
    SKIP,
    SLOW,
    SMALLINT,
    SNAPSHOT,
    SOME,
    SORT,
    SORTED,
    SORTKEY,
    SOURCE,
    SPATIAL,
    SPECIFIC,
    SPECIFICTYPE,
    SPGIST,
    SQL,
    SQLEXCEPTION,
    SQLSTATE,
    SQLWARNING,
    SQL_BIG_RESULT,
    SQL_BUFFER_RESULT,
    SQL_CALC_FOUND_ROWS,
    SQL_NO_CACHE,
    SQL_SMALL_RESULT,
    SQRT,
    SRID,
    STABLE,
    STAGE,
    START,
    STARTS,
    STATEMENT,
    STATIC,
    STATISTICS,
    STATS_AUTO_RECALC,
    STATS_PERSISTENT,
    STATS_SAMPLE_PAGES,
    STATUPDATE,
    STATUS,
    STDDEV_POP,
    STDDEV_SAMP,
    STDIN,
    STDOUT,
    STEP,
    STORAGE,
    STORAGE_INTEGRATION,
    STORAGE_SERIALIZATION_POLICY,
    STORED,
    STRAIGHT_JOIN,
    STREAM,
    STRICT,
    STRING,
    STRUCT,
    SUBMULTISET,
    SUBSCRIPT,
    SUBSTR,
    SUBSTRING,
    SUBSTRING_REGEX,
    SUBTYPE,
    SUBTYPE_DIFF,
    SUBTYPE_OPCLASS,
    SUCCEEDS,
    SUM,
    SUPER,
    SUPERUSER,
    SUPPORT,
    SUSPEND,
    SWAP,
    SYMMETRIC,
    SYNC,
    SYNONYM,
    SYSTEM,
    SYSTEM_TIME,
    SYSTEM_USER,
    TABLE,
    TABLES,
    TABLESAMPLE,
    TABLESPACE,
    TAG,
    TARGET,
    TARGET_LAG,
    TASK,
    TBLPROPERTIES,
    TEMP,
    TEMPORARY,
    TEMPTABLE,
    TERMINATED,
    TERSE,
    TEXT,
    TEXTFILE,
    THEN,
    THROW,
    TIES,
    TIME,
    TIMEFORMAT,
    TIMESTAMP,
    TIMESTAMPTZ,
    TIMESTAMP_NTZ,
    TIMETZ,
    TIMEZONE,
    TIMEZONE_ABBR,
    TIMEZONE_HOUR,
    TIMEZONE_MINUTE,
    TIMEZONE_REGION,
    TINYBLOB,
    TINYINT,
    TINYTEXT,
    TO,
    TOP,
    TOTALS,
    TOTP,
    TRACE,
    TRAILING,
    TRAN,
    TRANSACTION,
    TRANSIENT,
    TRANSLATE,
    TRANSLATE_REGEX,
    TRANSLATION,
    TREAT,
    TREE,
    TRIGGER,
    TRIM,
    TRIM_ARRAY,
    TRUE,
    TRUNCATE,
    TRUNCATECOLUMNS,
    TRY,
    TRY_CAST,
    TRY_CONVERT,
    TSQUERY,
    TSVECTOR,
    TUPLE,
    TYPE,
    TYPMOD_IN,
    TYPMOD_OUT,
    UBIGINT,
    UESCAPE,
    UHUGEINT,
    UINT128,
    UINT16,
    UINT256,
    UINT32,
    UINT64,
    UINT8,
    UNBOUNDED,
    UNCACHE,
    UNCOMMITTED,
    UNDEFINED,
    UNFREEZE,
    UNION,
    UNIQUE,
    UNKNOWN,
    UNLISTEN,
    UNLOAD,
    UNLOCK,
    UNLOGGED,
    UNMATCHED,
    UNNEST,
    UNPIVOT,
    UNSAFE,
    UNSET,
    UNSIGNED,
    UNTIL,
    UPDATE,
    UPPER,
    URL,
    USAGE,
    USE,
    USER,
    USER_RESOURCES,
    USING,
    USMALLINT,
    UTINYINT,
    UUID,
    VACUUM,
    VALID,
    VALIDATE,
    VALIDATION_MODE,
    VALUE,
    VALUES,
    VALUE_OF,
    VARBINARY,
    VARBIT,
    VARCHAR,
    VARCHAR2,
    VARIABLE,
    VARIABLES,
    VARIADIC,
    VARYING,
    VAR_POP,
    VAR_SAMP,
    VERBOSE,
    VERSION,
    VERSIONING,
    VERSIONS,
    VIEW,
    VIEWS,
    VIRTUAL,
    VOLATILE,
    VOLUME,
    WAITFOR,
    WAREHOUSE,
    WAREHOUSES,
    WEEK,
    WEEKS,
    WHEN,
    WHENEVER,
    WHERE,
    WHILE,
    WIDTH_BUCKET,
    WINDOW,
    WITH,
    WITHIN,
    WITHOUT,
    WITHOUT_ARRAY_WRAPPER,
    WORK,
    WORKLOAD_IDENTITY,
    WRAPPER,
    WRITE,
    XML,
    XMLNAMESPACES,
    XMLTABLE,
    XOR,
    YEAR,
    YEARS,
    YES,
    ZONE,
    ZORDER,
    ZSTD
);

/// These keywords can't be used as a table alias, so that `FROM table_name alias`
/// can be parsed unambiguously without looking ahead.
pub const RESERVED_FOR_TABLE_ALIAS: &[Keyword] = &[
    // Reserved as both a table and a column alias:
    Keyword::WITH,
    Keyword::EXPLAIN,
    Keyword::ANALYZE,
    Keyword::SELECT,
    Keyword::WHERE,
    Keyword::GROUP,
    Keyword::SORT,
    Keyword::HAVING,
    Keyword::ORDER,
    Keyword::PIVOT,
    Keyword::UNPIVOT,
    Keyword::TOP,
    Keyword::LATERAL,
    Keyword::VIEW,
    Keyword::LIMIT,
    Keyword::OFFSET,
    Keyword::FETCH,
    Keyword::UNION,
    Keyword::EXCEPT,
    Keyword::INTERSECT,
    Keyword::MINUS,
    // Reserved only as a table alias in the `FROM`/`JOIN` clauses:
    Keyword::ON,
    Keyword::JOIN,
    Keyword::INNER,
    Keyword::CROSS,
    Keyword::FULL,
    Keyword::LEFT,
    Keyword::RIGHT,
    Keyword::NATURAL,
    Keyword::USING,
    Keyword::CLUSTER,
    Keyword::DISTRIBUTE,
    Keyword::GLOBAL,
    Keyword::ANTI,
    Keyword::SEMI,
    Keyword::RETURNING,
    Keyword::OUTPUT,
    Keyword::ASOF,
    Keyword::MATCH_CONDITION,
    // for MSSQL-specific OUTER APPLY (seems reserved in most dialects)
    Keyword::OUTER,
    Keyword::SET,
    Keyword::QUALIFY,
    Keyword::WINDOW,
    Keyword::END,
    Keyword::FOR,
    // for MYSQL PARTITION SELECTION
    Keyword::PARTITION,
    // for Clickhouse ARRAY JOIN (ARRAY must not be parsed as a table alias)
    Keyword::ARRAY,
    // for Clickhouse PREWHERE
    Keyword::PREWHERE,
    Keyword::SETTINGS,
    Keyword::FORMAT,
    // for Snowflake START WITH .. CONNECT BY
    Keyword::START,
    Keyword::CONNECT,
    // Reserved for snowflake MATCH_RECOGNIZE
    Keyword::MATCH_RECOGNIZE,
    // Reserved for Snowflake table sample
    Keyword::SAMPLE,
    Keyword::TABLESAMPLE,
    Keyword::FROM,
    Keyword::OPEN,
];

/// Can't be used as a column alias, so that `SELECT <expr> alias`
/// can be parsed unambiguously without looking ahead.
pub const RESERVED_FOR_COLUMN_ALIAS: &[Keyword] = &[
    // Reserved as both a table and a column alias:
    Keyword::WITH,
    Keyword::EXPLAIN,
    Keyword::ANALYZE,
    Keyword::SELECT,
    Keyword::WHERE,
    Keyword::GROUP,
    Keyword::SORT,
    Keyword::HAVING,
    Keyword::ORDER,
    Keyword::TOP,
    Keyword::LATERAL,
    Keyword::VIEW,
    Keyword::LIMIT,
    Keyword::OFFSET,
    Keyword::FETCH,
    Keyword::UNION,
    Keyword::EXCEPT,
    Keyword::EXCLUDE,
    Keyword::INTERSECT,
    Keyword::MINUS,
    Keyword::CLUSTER,
    Keyword::DISTRIBUTE,
    Keyword::RETURNING,
    Keyword::VALUES,
    // Reserved only as a column alias in the `SELECT` clause
    Keyword::FROM,
    Keyword::INTO,
    Keyword::END,
];

/// Global list of reserved keywords allowed after FROM.
/// Parser should call Dialect::get_reserved_keyword_after_from
/// to allow for each dialect to customize the list.
pub const RESERVED_FOR_TABLE_FACTOR: &[Keyword] = &[
    Keyword::INTO,
    Keyword::LIMIT,
    Keyword::HAVING,
    Keyword::WHERE,
];

/// Global list of reserved keywords that cannot be parsed as identifiers
/// without special handling like quoting. Parser should call `Dialect::is_reserved_for_identifier`
/// to allow for each dialect to customize the list.
pub const RESERVED_FOR_IDENTIFIER: &[Keyword] = &[
    Keyword::EXISTS,
    Keyword::INTERVAL,
    Keyword::STRUCT,
    Keyword::TRIM,
];
