Edit on GitHub

sqlglot.dialects.mysql

   1from __future__ import annotations
   2
   3import typing as t
   4
   5from sqlglot import exp, generator, parser, tokens, transforms
   6from sqlglot.dialects.dialect import (
   7    Dialect,
   8    NormalizationStrategy,
   9    arrow_json_extract_sql,
  10    date_add_interval_sql,
  11    datestrtodate_sql,
  12    build_formatted_time,
  13    isnull_to_is_null,
  14    length_or_char_length_sql,
  15    max_or_greatest,
  16    min_or_least,
  17    no_ilike_sql,
  18    no_paren_current_date_sql,
  19    no_pivot_sql,
  20    no_tablesample_sql,
  21    no_trycast_sql,
  22    build_date_delta,
  23    build_date_delta_with_interval,
  24    rename_func,
  25    strposition_sql,
  26    unit_to_var,
  27    trim_sql,
  28    timestrtotime_sql,
  29)
  30from sqlglot.generator import unsupported_args
  31from sqlglot.helper import seq_get
  32from sqlglot.tokens import TokenType
  33from sqlglot.typing.mysql import EXPRESSION_METADATA
  34
  35
  36def _show_parser(*args: t.Any, **kwargs: t.Any) -> t.Callable[[MySQL.Parser], exp.Show]:
  37    def _parse(self: MySQL.Parser) -> exp.Show:
  38        return self._parse_show_mysql(*args, **kwargs)
  39
  40    return _parse
  41
  42
  43def _date_trunc_sql(self: MySQL.Generator, expression: exp.DateTrunc) -> str:
  44    expr = self.sql(expression, "this")
  45    unit = expression.text("unit").upper()
  46
  47    if unit == "WEEK":
  48        concat = f"CONCAT(YEAR({expr}), ' ', WEEK({expr}, 1), ' 1')"
  49        date_format = "%Y %u %w"
  50    elif unit == "MONTH":
  51        concat = f"CONCAT(YEAR({expr}), ' ', MONTH({expr}), ' 1')"
  52        date_format = "%Y %c %e"
  53    elif unit == "QUARTER":
  54        concat = f"CONCAT(YEAR({expr}), ' ', QUARTER({expr}) * 3 - 2, ' 1')"
  55        date_format = "%Y %c %e"
  56    elif unit == "YEAR":
  57        concat = f"CONCAT(YEAR({expr}), ' 1 1')"
  58        date_format = "%Y %c %e"
  59    else:
  60        if unit != "DAY":
  61            self.unsupported(f"Unexpected interval unit: {unit}")
  62        return self.func("DATE", expr)
  63
  64    return self.func("STR_TO_DATE", concat, f"'{date_format}'")
  65
  66
  67# All specifiers for time parts (as opposed to date parts)
  68# https://dev.mysql.com/doc/refman/8.0/en/date-and-time-functions.html#function_date-format
  69TIME_SPECIFIERS = {"f", "H", "h", "I", "i", "k", "l", "p", "r", "S", "s", "T"}
  70
  71
  72def _has_time_specifier(date_format: str) -> bool:
  73    i = 0
  74    length = len(date_format)
  75
  76    while i < length:
  77        if date_format[i] == "%":
  78            i += 1
  79            if i < length and date_format[i] in TIME_SPECIFIERS:
  80                return True
  81        i += 1
  82    return False
  83
  84
  85def _str_to_date(args: t.List) -> exp.StrToDate | exp.StrToTime:
  86    mysql_date_format = seq_get(args, 1)
  87    date_format = MySQL.format_time(mysql_date_format)
  88    this = seq_get(args, 0)
  89
  90    if mysql_date_format and _has_time_specifier(mysql_date_format.name):
  91        return exp.StrToTime(this=this, format=date_format)
  92
  93    return exp.StrToDate(this=this, format=date_format)
  94
  95
  96def _str_to_date_sql(
  97    self: MySQL.Generator, expression: exp.StrToDate | exp.StrToTime | exp.TsOrDsToDate
  98) -> str:
  99    return self.func("STR_TO_DATE", expression.this, self.format_time(expression))
 100
 101
 102def _unix_to_time_sql(self: MySQL.Generator, expression: exp.UnixToTime) -> str:
 103    scale = expression.args.get("scale")
 104    timestamp = expression.this
 105
 106    if scale in (None, exp.UnixToTime.SECONDS):
 107        return self.func("FROM_UNIXTIME", timestamp, self.format_time(expression))
 108
 109    return self.func(
 110        "FROM_UNIXTIME",
 111        exp.Div(this=timestamp, expression=exp.func("POW", 10, scale)),
 112        self.format_time(expression),
 113    )
 114
 115
 116def date_add_sql(
 117    kind: str,
 118) -> t.Callable[[generator.Generator, exp.Expression], str]:
 119    def func(self: generator.Generator, expression: exp.Expression) -> str:
 120        return self.func(
 121            f"DATE_{kind}",
 122            expression.this,
 123            exp.Interval(this=expression.expression, unit=unit_to_var(expression)),
 124        )
 125
 126    return func
 127
 128
 129def _ts_or_ds_to_date_sql(self: MySQL.Generator, expression: exp.TsOrDsToDate) -> str:
 130    time_format = expression.args.get("format")
 131    return _str_to_date_sql(self, expression) if time_format else self.func("DATE", expression.this)
 132
 133
 134def _remove_ts_or_ds_to_date(
 135    to_sql: t.Optional[t.Callable[[MySQL.Generator, exp.Expression], str]] = None,
 136    args: t.Tuple[str, ...] = ("this",),
 137) -> t.Callable[[MySQL.Generator, exp.Func], str]:
 138    def func(self: MySQL.Generator, expression: exp.Func) -> str:
 139        for arg_key in args:
 140            arg = expression.args.get(arg_key)
 141            if isinstance(arg, exp.TsOrDsToDate) and not arg.args.get("format"):
 142                expression.set(arg_key, arg.this)
 143
 144        return to_sql(self, expression) if to_sql else self.function_fallback_sql(expression)
 145
 146    return func
 147
 148
 149class MySQL(Dialect):
 150    PROMOTE_TO_INFERRED_DATETIME_TYPE = True
 151
 152    # https://dev.mysql.com/doc/refman/8.0/en/identifiers.html
 153    IDENTIFIERS_CAN_START_WITH_DIGIT = True
 154
 155    # We default to treating all identifiers as case-sensitive, since it matches MySQL's
 156    # behavior on Linux systems. For MacOS and Windows systems, one can override this
 157    # setting by specifying `dialect="mysql, normalization_strategy = lowercase"`.
 158    #
 159    # See also https://dev.mysql.com/doc/refman/8.2/en/identifier-case-sensitivity.html
 160    NORMALIZATION_STRATEGY = NormalizationStrategy.CASE_SENSITIVE
 161
 162    TIME_FORMAT = "'%Y-%m-%d %T'"
 163    DPIPE_IS_STRING_CONCAT = False
 164    SUPPORTS_USER_DEFINED_TYPES = False
 165    SUPPORTS_SEMI_ANTI_JOIN = False
 166    SAFE_DIVISION = True
 167    SAFE_TO_ELIMINATE_DOUBLE_NEGATION = False
 168    LEAST_GREATEST_IGNORES_NULLS = False
 169
 170    EXPRESSION_METADATA = EXPRESSION_METADATA.copy()
 171
 172    # https://prestodb.io/docs/current/functions/datetime.html#mysql-date-functions
 173    TIME_MAPPING = {
 174        "%M": "%B",
 175        "%c": "%-m",
 176        "%e": "%-d",
 177        "%h": "%I",
 178        "%i": "%M",
 179        "%s": "%S",
 180        "%u": "%W",
 181        "%k": "%-H",
 182        "%l": "%-I",
 183        "%T": "%H:%M:%S",
 184        "%W": "%A",
 185    }
 186
 187    VALID_INTERVAL_UNITS = {
 188        *Dialect.VALID_INTERVAL_UNITS,
 189        "SECOND_MICROSECOND",
 190        "MINUTE_MICROSECOND",
 191        "MINUTE_SECOND",
 192        "HOUR_MICROSECOND",
 193        "HOUR_SECOND",
 194        "HOUR_MINUTE",
 195        "DAY_MICROSECOND",
 196        "DAY_SECOND",
 197        "DAY_MINUTE",
 198        "DAY_HOUR",
 199        "YEAR_MONTH",
 200    }
 201
 202    class Tokenizer(tokens.Tokenizer):
 203        QUOTES = ["'", '"']
 204        COMMENTS = ["--", "#", ("/*", "*/")]
 205        IDENTIFIERS = ["`"]
 206        STRING_ESCAPES = ["'", '"', "\\"]
 207        BIT_STRINGS = [("b'", "'"), ("B'", "'"), ("0b", "")]
 208        HEX_STRINGS = [("x'", "'"), ("X'", "'"), ("0x", "")]
 209        # https://dev.mysql.com/doc/refman/8.4/en/string-literals.html
 210        ESCAPE_FOLLOW_CHARS = ["0", "b", "n", "r", "t", "Z", "%", "_"]
 211
 212        NESTED_COMMENTS = False
 213
 214        KEYWORDS = {
 215            **tokens.Tokenizer.KEYWORDS,
 216            "BLOB": TokenType.BLOB,
 217            "CHARSET": TokenType.CHARACTER_SET,
 218            "DISTINCTROW": TokenType.DISTINCT,
 219            "EXPLAIN": TokenType.DESCRIBE,
 220            "FORCE": TokenType.FORCE,
 221            "IGNORE": TokenType.IGNORE,
 222            "KEY": TokenType.KEY,
 223            "LOCK TABLES": TokenType.COMMAND,
 224            "LONGBLOB": TokenType.LONGBLOB,
 225            "LONGTEXT": TokenType.LONGTEXT,
 226            "MEDIUMBLOB": TokenType.MEDIUMBLOB,
 227            "MEDIUMINT": TokenType.MEDIUMINT,
 228            "MEDIUMTEXT": TokenType.MEDIUMTEXT,
 229            "MEMBER OF": TokenType.MEMBER_OF,
 230            "MOD": TokenType.MOD,
 231            "SEPARATOR": TokenType.SEPARATOR,
 232            "SERIAL": TokenType.SERIAL,
 233            "SIGNED": TokenType.BIGINT,
 234            "SIGNED INTEGER": TokenType.BIGINT,
 235            "SOUNDS LIKE": TokenType.SOUNDS_LIKE,
 236            "START": TokenType.BEGIN,
 237            "TIMESTAMP": TokenType.TIMESTAMPTZ,
 238            "TINYBLOB": TokenType.TINYBLOB,
 239            "TINYTEXT": TokenType.TINYTEXT,
 240            "UNLOCK TABLES": TokenType.COMMAND,
 241            "UNSIGNED": TokenType.UBIGINT,
 242            "UNSIGNED INTEGER": TokenType.UBIGINT,
 243            "YEAR": TokenType.YEAR,
 244            "_ARMSCII8": TokenType.INTRODUCER,
 245            "_ASCII": TokenType.INTRODUCER,
 246            "_BIG5": TokenType.INTRODUCER,
 247            "_BINARY": TokenType.INTRODUCER,
 248            "_CP1250": TokenType.INTRODUCER,
 249            "_CP1251": TokenType.INTRODUCER,
 250            "_CP1256": TokenType.INTRODUCER,
 251            "_CP1257": TokenType.INTRODUCER,
 252            "_CP850": TokenType.INTRODUCER,
 253            "_CP852": TokenType.INTRODUCER,
 254            "_CP866": TokenType.INTRODUCER,
 255            "_CP932": TokenType.INTRODUCER,
 256            "_DEC8": TokenType.INTRODUCER,
 257            "_EUCJPMS": TokenType.INTRODUCER,
 258            "_EUCKR": TokenType.INTRODUCER,
 259            "_GB18030": TokenType.INTRODUCER,
 260            "_GB2312": TokenType.INTRODUCER,
 261            "_GBK": TokenType.INTRODUCER,
 262            "_GEOSTD8": TokenType.INTRODUCER,
 263            "_GREEK": TokenType.INTRODUCER,
 264            "_HEBREW": TokenType.INTRODUCER,
 265            "_HP8": TokenType.INTRODUCER,
 266            "_KEYBCS2": TokenType.INTRODUCER,
 267            "_KOI8R": TokenType.INTRODUCER,
 268            "_KOI8U": TokenType.INTRODUCER,
 269            "_LATIN1": TokenType.INTRODUCER,
 270            "_LATIN2": TokenType.INTRODUCER,
 271            "_LATIN5": TokenType.INTRODUCER,
 272            "_LATIN7": TokenType.INTRODUCER,
 273            "_MACCE": TokenType.INTRODUCER,
 274            "_MACROMAN": TokenType.INTRODUCER,
 275            "_SJIS": TokenType.INTRODUCER,
 276            "_SWE7": TokenType.INTRODUCER,
 277            "_TIS620": TokenType.INTRODUCER,
 278            "_UCS2": TokenType.INTRODUCER,
 279            "_UJIS": TokenType.INTRODUCER,
 280            # https://dev.mysql.com/doc/refman/8.0/en/string-literals.html
 281            "_UTF8": TokenType.INTRODUCER,
 282            "_UTF16": TokenType.INTRODUCER,
 283            "_UTF16LE": TokenType.INTRODUCER,
 284            "_UTF32": TokenType.INTRODUCER,
 285            "_UTF8MB3": TokenType.INTRODUCER,
 286            "_UTF8MB4": TokenType.INTRODUCER,
 287            "@@": TokenType.SESSION_PARAMETER,
 288        }
 289
 290        COMMANDS = {*tokens.Tokenizer.COMMANDS, TokenType.REPLACE} - {TokenType.SHOW}
 291
 292    class Parser(parser.Parser):
 293        FUNC_TOKENS = {
 294            *parser.Parser.FUNC_TOKENS,
 295            TokenType.DATABASE,
 296            TokenType.MOD,
 297            TokenType.SCHEMA,
 298            TokenType.VALUES,
 299            TokenType.CHARACTER_SET,
 300        }
 301
 302        CONJUNCTION = {
 303            **parser.Parser.CONJUNCTION,
 304            TokenType.DAMP: exp.And,
 305            TokenType.XOR: exp.Xor,
 306        }
 307
 308        DISJUNCTION = {
 309            **parser.Parser.DISJUNCTION,
 310            TokenType.DPIPE: exp.Or,
 311        }
 312
 313        TABLE_ALIAS_TOKENS = (
 314            parser.Parser.TABLE_ALIAS_TOKENS - parser.Parser.TABLE_INDEX_HINT_TOKENS
 315        )
 316
 317        RANGE_PARSERS = {
 318            **parser.Parser.RANGE_PARSERS,
 319            TokenType.SOUNDS_LIKE: lambda self, this: self.expression(
 320                exp.EQ,
 321                this=self.expression(exp.Soundex, this=this),
 322                expression=self.expression(exp.Soundex, this=self._parse_term()),
 323            ),
 324            TokenType.MEMBER_OF: lambda self, this: self.expression(
 325                exp.JSONArrayContains,
 326                this=this,
 327                expression=self._parse_wrapped(self._parse_expression),
 328            ),
 329        }
 330
 331        FUNCTIONS = {
 332            **parser.Parser.FUNCTIONS,
 333            "BIT_AND": exp.BitwiseAndAgg.from_arg_list,
 334            "BIT_OR": exp.BitwiseOrAgg.from_arg_list,
 335            "BIT_XOR": exp.BitwiseXorAgg.from_arg_list,
 336            "BIT_COUNT": exp.BitwiseCount.from_arg_list,
 337            "CONVERT_TZ": lambda args: exp.ConvertTimezone(
 338                source_tz=seq_get(args, 1), target_tz=seq_get(args, 2), timestamp=seq_get(args, 0)
 339            ),
 340            "CURDATE": exp.CurrentDate.from_arg_list,
 341            "CURTIME": exp.CurrentTime.from_arg_list,
 342            "DATE": lambda args: exp.TsOrDsToDate(this=seq_get(args, 0)),
 343            "DATE_ADD": build_date_delta_with_interval(exp.DateAdd),
 344            "DATE_FORMAT": build_formatted_time(exp.TimeToStr, "mysql"),
 345            "DATE_SUB": build_date_delta_with_interval(exp.DateSub),
 346            "DAY": lambda args: exp.Day(this=exp.TsOrDsToDate(this=seq_get(args, 0))),
 347            "DAYOFMONTH": lambda args: exp.DayOfMonth(this=exp.TsOrDsToDate(this=seq_get(args, 0))),
 348            "DAYOFWEEK": lambda args: exp.DayOfWeek(this=exp.TsOrDsToDate(this=seq_get(args, 0))),
 349            "DAYOFYEAR": lambda args: exp.DayOfYear(this=exp.TsOrDsToDate(this=seq_get(args, 0))),
 350            "FORMAT": exp.NumberToStr.from_arg_list,
 351            "FROM_UNIXTIME": build_formatted_time(exp.UnixToTime, "mysql"),
 352            "ISNULL": isnull_to_is_null,
 353            "LENGTH": lambda args: exp.Length(this=seq_get(args, 0), binary=True),
 354            "MAKETIME": exp.TimeFromParts.from_arg_list,
 355            "MONTH": lambda args: exp.Month(this=exp.TsOrDsToDate(this=seq_get(args, 0))),
 356            "MONTHNAME": lambda args: exp.TimeToStr(
 357                this=exp.TsOrDsToDate(this=seq_get(args, 0)),
 358                format=exp.Literal.string("%B"),
 359            ),
 360            "SCHEMA": exp.CurrentSchema.from_arg_list,
 361            "DATABASE": exp.CurrentSchema.from_arg_list,
 362            "STR_TO_DATE": _str_to_date,
 363            "TIMESTAMPDIFF": build_date_delta(exp.TimestampDiff),
 364            "TO_DAYS": lambda args: exp.paren(
 365                exp.DateDiff(
 366                    this=exp.TsOrDsToDate(this=seq_get(args, 0)),
 367                    expression=exp.TsOrDsToDate(this=exp.Literal.string("0000-01-01")),
 368                    unit=exp.var("DAY"),
 369                )
 370                + 1
 371            ),
 372            "VERSION": exp.CurrentVersion.from_arg_list,
 373            "WEEK": lambda args: exp.Week(
 374                this=exp.TsOrDsToDate(this=seq_get(args, 0)), mode=seq_get(args, 1)
 375            ),
 376            "WEEKOFYEAR": lambda args: exp.WeekOfYear(this=exp.TsOrDsToDate(this=seq_get(args, 0))),
 377            "YEAR": lambda args: exp.Year(this=exp.TsOrDsToDate(this=seq_get(args, 0))),
 378        }
 379
 380        FUNCTION_PARSERS = {
 381            **parser.Parser.FUNCTION_PARSERS,
 382            "GROUP_CONCAT": lambda self: self._parse_group_concat(),
 383            # https://dev.mysql.com/doc/refman/5.7/en/miscellaneous-functions.html#function_values
 384            "VALUES": lambda self: self.expression(
 385                exp.Anonymous, this="VALUES", expressions=[self._parse_id_var()]
 386            ),
 387            "JSON_VALUE": lambda self: self._parse_json_value(),
 388            "SUBSTR": lambda self: self._parse_substring(),
 389        }
 390
 391        STATEMENT_PARSERS = {
 392            **parser.Parser.STATEMENT_PARSERS,
 393            TokenType.SHOW: lambda self: self._parse_show(),
 394        }
 395
 396        SHOW_PARSERS = {
 397            "BINARY LOGS": _show_parser("BINARY LOGS"),
 398            "MASTER LOGS": _show_parser("BINARY LOGS"),
 399            "BINLOG EVENTS": _show_parser("BINLOG EVENTS"),
 400            "CHARACTER SET": _show_parser("CHARACTER SET"),
 401            "CHARSET": _show_parser("CHARACTER SET"),
 402            "COLLATION": _show_parser("COLLATION"),
 403            "FULL COLUMNS": _show_parser("COLUMNS", target="FROM", full=True),
 404            "COLUMNS": _show_parser("COLUMNS", target="FROM"),
 405            "CREATE DATABASE": _show_parser("CREATE DATABASE", target=True),
 406            "CREATE EVENT": _show_parser("CREATE EVENT", target=True),
 407            "CREATE FUNCTION": _show_parser("CREATE FUNCTION", target=True),
 408            "CREATE PROCEDURE": _show_parser("CREATE PROCEDURE", target=True),
 409            "CREATE TABLE": _show_parser("CREATE TABLE", target=True),
 410            "CREATE TRIGGER": _show_parser("CREATE TRIGGER", target=True),
 411            "CREATE VIEW": _show_parser("CREATE VIEW", target=True),
 412            "DATABASES": _show_parser("DATABASES"),
 413            "SCHEMAS": _show_parser("DATABASES"),
 414            "ENGINE": _show_parser("ENGINE", target=True),
 415            "STORAGE ENGINES": _show_parser("ENGINES"),
 416            "ENGINES": _show_parser("ENGINES"),
 417            "ERRORS": _show_parser("ERRORS"),
 418            "EVENTS": _show_parser("EVENTS"),
 419            "FUNCTION CODE": _show_parser("FUNCTION CODE", target=True),
 420            "FUNCTION STATUS": _show_parser("FUNCTION STATUS"),
 421            "GRANTS": _show_parser("GRANTS", target="FOR"),
 422            "INDEX": _show_parser("INDEX", target="FROM"),
 423            "MASTER STATUS": _show_parser("MASTER STATUS"),
 424            "OPEN TABLES": _show_parser("OPEN TABLES"),
 425            "PLUGINS": _show_parser("PLUGINS"),
 426            "PROCEDURE CODE": _show_parser("PROCEDURE CODE", target=True),
 427            "PROCEDURE STATUS": _show_parser("PROCEDURE STATUS"),
 428            "PRIVILEGES": _show_parser("PRIVILEGES"),
 429            "FULL PROCESSLIST": _show_parser("PROCESSLIST", full=True),
 430            "PROCESSLIST": _show_parser("PROCESSLIST"),
 431            "PROFILE": _show_parser("PROFILE"),
 432            "PROFILES": _show_parser("PROFILES"),
 433            "RELAYLOG EVENTS": _show_parser("RELAYLOG EVENTS"),
 434            "REPLICAS": _show_parser("REPLICAS"),
 435            "SLAVE HOSTS": _show_parser("REPLICAS"),
 436            "REPLICA STATUS": _show_parser("REPLICA STATUS"),
 437            "SLAVE STATUS": _show_parser("REPLICA STATUS"),
 438            "GLOBAL STATUS": _show_parser("STATUS", global_=True),
 439            "SESSION STATUS": _show_parser("STATUS"),
 440            "STATUS": _show_parser("STATUS"),
 441            "TABLE STATUS": _show_parser("TABLE STATUS"),
 442            "FULL TABLES": _show_parser("TABLES", full=True),
 443            "TABLES": _show_parser("TABLES"),
 444            "TRIGGERS": _show_parser("TRIGGERS"),
 445            "GLOBAL VARIABLES": _show_parser("VARIABLES", global_=True),
 446            "SESSION VARIABLES": _show_parser("VARIABLES"),
 447            "VARIABLES": _show_parser("VARIABLES"),
 448            "WARNINGS": _show_parser("WARNINGS"),
 449        }
 450
 451        PROPERTY_PARSERS = {
 452            **parser.Parser.PROPERTY_PARSERS,
 453            "LOCK": lambda self: self._parse_property_assignment(exp.LockProperty),
 454            "PARTITION BY": lambda self: self._parse_partition_property(),
 455        }
 456
 457        SET_PARSERS = {
 458            **parser.Parser.SET_PARSERS,
 459            "PERSIST": lambda self: self._parse_set_item_assignment("PERSIST"),
 460            "PERSIST_ONLY": lambda self: self._parse_set_item_assignment("PERSIST_ONLY"),
 461            "CHARACTER SET": lambda self: self._parse_set_item_charset("CHARACTER SET"),
 462            "CHARSET": lambda self: self._parse_set_item_charset("CHARACTER SET"),
 463            "NAMES": lambda self: self._parse_set_item_names(),
 464        }
 465
 466        CONSTRAINT_PARSERS = {
 467            **parser.Parser.CONSTRAINT_PARSERS,
 468            "FULLTEXT": lambda self: self._parse_index_constraint(kind="FULLTEXT"),
 469            "INDEX": lambda self: self._parse_index_constraint(),
 470            "KEY": lambda self: self._parse_index_constraint(),
 471            "SPATIAL": lambda self: self._parse_index_constraint(kind="SPATIAL"),
 472            "ZEROFILL": lambda self: self.expression(exp.ZeroFillColumnConstraint),
 473        }
 474
 475        ALTER_PARSERS = {
 476            **parser.Parser.ALTER_PARSERS,
 477            "MODIFY": lambda self: self._parse_alter_table_alter(),
 478        }
 479
 480        ALTER_ALTER_PARSERS = {
 481            **parser.Parser.ALTER_ALTER_PARSERS,
 482            "INDEX": lambda self: self._parse_alter_table_alter_index(),
 483        }
 484
 485        SCHEMA_UNNAMED_CONSTRAINTS = {
 486            *parser.Parser.SCHEMA_UNNAMED_CONSTRAINTS,
 487            "FULLTEXT",
 488            "INDEX",
 489            "KEY",
 490            "SPATIAL",
 491        }
 492
 493        PROFILE_TYPES: parser.OPTIONS_TYPE = {
 494            **dict.fromkeys(("ALL", "CPU", "IPC", "MEMORY", "SOURCE", "SWAPS"), tuple()),
 495            "BLOCK": ("IO",),
 496            "CONTEXT": ("SWITCHES",),
 497            "PAGE": ("FAULTS",),
 498        }
 499
 500        TYPE_TOKENS = {
 501            *parser.Parser.TYPE_TOKENS,
 502            TokenType.SET,
 503        }
 504
 505        ENUM_TYPE_TOKENS = {
 506            *parser.Parser.ENUM_TYPE_TOKENS,
 507            TokenType.SET,
 508        }
 509
 510        # SELECT [ ALL | DISTINCT | DISTINCTROW ] [ <OPERATION_MODIFIERS> ]
 511        OPERATION_MODIFIERS = {
 512            "HIGH_PRIORITY",
 513            "STRAIGHT_JOIN",
 514            "SQL_SMALL_RESULT",
 515            "SQL_BIG_RESULT",
 516            "SQL_BUFFER_RESULT",
 517            "SQL_NO_CACHE",
 518            "SQL_CALC_FOUND_ROWS",
 519        }
 520
 521        LOG_DEFAULTS_TO_LN = True
 522        STRING_ALIASES = True
 523        VALUES_FOLLOWED_BY_PAREN = False
 524        SUPPORTS_PARTITION_SELECTION = True
 525
 526        def _parse_generated_as_identity(
 527            self,
 528        ) -> (
 529            exp.GeneratedAsIdentityColumnConstraint
 530            | exp.ComputedColumnConstraint
 531            | exp.GeneratedAsRowColumnConstraint
 532        ):
 533            this = super()._parse_generated_as_identity()
 534
 535            if self._match_texts(("STORED", "VIRTUAL")):
 536                persisted = self._prev.text.upper() == "STORED"
 537
 538                if isinstance(this, exp.ComputedColumnConstraint):
 539                    this.set("persisted", persisted)
 540                elif isinstance(this, exp.GeneratedAsIdentityColumnConstraint):
 541                    this = self.expression(
 542                        exp.ComputedColumnConstraint, this=this.expression, persisted=persisted
 543                    )
 544
 545            return this
 546
 547        def _parse_primary_key_part(self) -> t.Optional[exp.Expression]:
 548            this = self._parse_id_var()
 549            if not self._match(TokenType.L_PAREN):
 550                return this
 551
 552            expression = self._parse_number()
 553            self._match_r_paren()
 554            return self.expression(exp.ColumnPrefix, this=this, expression=expression)
 555
 556        def _parse_index_constraint(
 557            self, kind: t.Optional[str] = None
 558        ) -> exp.IndexColumnConstraint:
 559            if kind:
 560                self._match_texts(("INDEX", "KEY"))
 561
 562            this = self._parse_id_var(any_token=False)
 563            index_type = self._match(TokenType.USING) and self._advance_any() and self._prev.text
 564            expressions = self._parse_wrapped_csv(self._parse_ordered)
 565
 566            options = []
 567            while True:
 568                if self._match_text_seq("KEY_BLOCK_SIZE"):
 569                    self._match(TokenType.EQ)
 570                    opt = exp.IndexConstraintOption(key_block_size=self._parse_number())
 571                elif self._match(TokenType.USING):
 572                    opt = exp.IndexConstraintOption(using=self._advance_any() and self._prev.text)
 573                elif self._match_text_seq("WITH", "PARSER"):
 574                    opt = exp.IndexConstraintOption(parser=self._parse_var(any_token=True))
 575                elif self._match(TokenType.COMMENT):
 576                    opt = exp.IndexConstraintOption(comment=self._parse_string())
 577                elif self._match_text_seq("VISIBLE"):
 578                    opt = exp.IndexConstraintOption(visible=True)
 579                elif self._match_text_seq("INVISIBLE"):
 580                    opt = exp.IndexConstraintOption(visible=False)
 581                elif self._match_text_seq("ENGINE_ATTRIBUTE"):
 582                    self._match(TokenType.EQ)
 583                    opt = exp.IndexConstraintOption(engine_attr=self._parse_string())
 584                elif self._match_text_seq("SECONDARY_ENGINE_ATTRIBUTE"):
 585                    self._match(TokenType.EQ)
 586                    opt = exp.IndexConstraintOption(secondary_engine_attr=self._parse_string())
 587                else:
 588                    opt = None
 589
 590                if not opt:
 591                    break
 592
 593                options.append(opt)
 594
 595            return self.expression(
 596                exp.IndexColumnConstraint,
 597                this=this,
 598                expressions=expressions,
 599                kind=kind,
 600                index_type=index_type,
 601                options=options,
 602            )
 603
 604        def _parse_show_mysql(
 605            self,
 606            this: str,
 607            target: bool | str = False,
 608            full: t.Optional[bool] = None,
 609            global_: t.Optional[bool] = None,
 610        ) -> exp.Show:
 611            json = self._match_text_seq("JSON")
 612
 613            if target:
 614                if isinstance(target, str):
 615                    self._match_text_seq(*target.split(" "))
 616                target_id = self._parse_id_var()
 617            else:
 618                target_id = None
 619
 620            log = self._parse_string() if self._match_text_seq("IN") else None
 621
 622            if this in ("BINLOG EVENTS", "RELAYLOG EVENTS"):
 623                position = self._parse_number() if self._match_text_seq("FROM") else None
 624                db = None
 625            else:
 626                position = None
 627                db = None
 628
 629                if self._match(TokenType.FROM):
 630                    db = self._parse_id_var()
 631                elif self._match(TokenType.DOT):
 632                    db = target_id
 633                    target_id = self._parse_id_var()
 634
 635            channel = self._parse_id_var() if self._match_text_seq("FOR", "CHANNEL") else None
 636
 637            like = self._parse_string() if self._match_text_seq("LIKE") else None
 638            where = self._parse_where()
 639
 640            if this == "PROFILE":
 641                types = self._parse_csv(lambda: self._parse_var_from_options(self.PROFILE_TYPES))
 642                query = self._parse_number() if self._match_text_seq("FOR", "QUERY") else None
 643                offset = self._parse_number() if self._match_text_seq("OFFSET") else None
 644                limit = self._parse_number() if self._match_text_seq("LIMIT") else None
 645            else:
 646                types, query = None, None
 647                offset, limit = self._parse_oldstyle_limit()
 648
 649            mutex = True if self._match_text_seq("MUTEX") else None
 650            mutex = False if self._match_text_seq("STATUS") else mutex
 651
 652            for_table = self._parse_id_var() if self._match_text_seq("FOR", "TABLE") else None
 653            for_group = self._parse_string() if self._match_text_seq("FOR", "GROUP") else None
 654            for_user = self._parse_string() if self._match_text_seq("FOR", "USER") else None
 655            for_role = self._parse_string() if self._match_text_seq("FOR", "ROLE") else None
 656            into_outfile = self._parse_string() if self._match_text_seq("INTO", "OUTFILE") else None
 657
 658            return self.expression(
 659                exp.Show,
 660                this=this,
 661                target=target_id,
 662                full=full,
 663                log=log,
 664                position=position,
 665                db=db,
 666                channel=channel,
 667                like=like,
 668                where=where,
 669                types=types,
 670                query=query,
 671                offset=offset,
 672                limit=limit,
 673                mutex=mutex,
 674                for_table=for_table,
 675                for_group=for_group,
 676                for_user=for_user,
 677                for_role=for_role,
 678                into_outfile=into_outfile,
 679                json=json,
 680                global_=global_,
 681            )
 682
 683        def _parse_oldstyle_limit(
 684            self,
 685        ) -> t.Tuple[t.Optional[exp.Expression], t.Optional[exp.Expression]]:
 686            limit = None
 687            offset = None
 688            if self._match_text_seq("LIMIT"):
 689                parts = self._parse_csv(self._parse_number)
 690                if len(parts) == 1:
 691                    limit = parts[0]
 692                elif len(parts) == 2:
 693                    limit = parts[1]
 694                    offset = parts[0]
 695
 696            return offset, limit
 697
 698        def _parse_set_item_charset(self, kind: str) -> exp.Expression:
 699            this = self._parse_string() or self._parse_unquoted_field()
 700            return self.expression(exp.SetItem, this=this, kind=kind)
 701
 702        def _parse_set_item_names(self) -> exp.Expression:
 703            charset = self._parse_string() or self._parse_unquoted_field()
 704            if self._match_text_seq("COLLATE"):
 705                collate = self._parse_string() or self._parse_unquoted_field()
 706            else:
 707                collate = None
 708
 709            return self.expression(exp.SetItem, this=charset, collate=collate, kind="NAMES")
 710
 711        def _parse_type(
 712            self, parse_interval: bool = True, fallback_to_identifier: bool = False
 713        ) -> t.Optional[exp.Expression]:
 714            # mysql binary is special and can work anywhere, even in order by operations
 715            # it operates like a no paren func
 716            if self._match(TokenType.BINARY, advance=False):
 717                data_type = self._parse_types(check_func=True, allow_identifiers=False)
 718
 719                if isinstance(data_type, exp.DataType):
 720                    return self.expression(exp.Cast, this=self._parse_column(), to=data_type)
 721
 722            return super()._parse_type(
 723                parse_interval=parse_interval, fallback_to_identifier=fallback_to_identifier
 724            )
 725
 726        def _parse_alter_table_alter_index(self) -> exp.AlterIndex:
 727            index = self._parse_field(any_token=True)
 728
 729            if self._match_text_seq("VISIBLE"):
 730                visible = True
 731            elif self._match_text_seq("INVISIBLE"):
 732                visible = False
 733            else:
 734                visible = None
 735
 736            return self.expression(exp.AlterIndex, this=index, visible=visible)
 737
 738        def _parse_partition_property(
 739            self,
 740        ) -> t.Optional[exp.Expression] | t.List[exp.Expression]:
 741            partition_cls: t.Optional[t.Type[exp.Expression]] = None
 742            value_parser = None
 743
 744            if self._match_text_seq("RANGE"):
 745                partition_cls = exp.PartitionByRangeProperty
 746                value_parser = self._parse_partition_range_value
 747            elif self._match_text_seq("LIST"):
 748                partition_cls = exp.PartitionByListProperty
 749                value_parser = self._parse_partition_list_value
 750
 751            if not partition_cls or not value_parser:
 752                return None
 753
 754            partition_expressions = self._parse_wrapped_csv(self._parse_assignment)
 755
 756            # For Doris and Starrocks
 757            if not self._match_text_seq("(", "PARTITION", advance=False):
 758                return partition_expressions
 759
 760            create_expressions = self._parse_wrapped_csv(value_parser)
 761
 762            return self.expression(
 763                partition_cls,
 764                partition_expressions=partition_expressions,
 765                create_expressions=create_expressions,
 766            )
 767
 768        def _parse_partition_range_value(self) -> t.Optional[exp.Expression]:
 769            self._match_text_seq("PARTITION")
 770            name = self._parse_id_var()
 771
 772            if not self._match_text_seq("VALUES", "LESS", "THAN"):
 773                return name
 774
 775            values = self._parse_wrapped_csv(self._parse_expression)
 776
 777            if (
 778                len(values) == 1
 779                and isinstance(values[0], exp.Column)
 780                and values[0].name.upper() == "MAXVALUE"
 781            ):
 782                values = [exp.var("MAXVALUE")]
 783
 784            part_range = self.expression(exp.PartitionRange, this=name, expressions=values)
 785            return self.expression(exp.Partition, expressions=[part_range])
 786
 787        def _parse_partition_list_value(self) -> exp.Partition:
 788            self._match_text_seq("PARTITION")
 789            name = self._parse_id_var()
 790            self._match_text_seq("VALUES", "IN")
 791            values = self._parse_wrapped_csv(self._parse_expression)
 792            part_list = self.expression(exp.PartitionList, this=name, expressions=values)
 793            return self.expression(exp.Partition, expressions=[part_list])
 794
 795        def _parse_primary_key(
 796            self,
 797            wrapped_optional: bool = False,
 798            in_props: bool = False,
 799            named_primary_key: bool = False,
 800        ) -> exp.PrimaryKeyColumnConstraint | exp.PrimaryKey:
 801            return super()._parse_primary_key(
 802                wrapped_optional=wrapped_optional, in_props=in_props, named_primary_key=True
 803            )
 804
 805    class Generator(generator.Generator):
 806        INTERVAL_ALLOWS_PLURAL_FORM = False
 807        LOCKING_READS_SUPPORTED = True
 808        NULL_ORDERING_SUPPORTED: t.Optional[bool] = None
 809        JOIN_HINTS = False
 810        TABLE_HINTS = True
 811        DUPLICATE_KEY_UPDATE_WITH_SET = False
 812        QUERY_HINT_SEP = " "
 813        VALUES_AS_TABLE = False
 814        NVL2_SUPPORTED = False
 815        LAST_DAY_SUPPORTS_DATE_PART = False
 816        JSON_TYPE_REQUIRED_FOR_EXTRACTION = True
 817        JSON_PATH_BRACKETED_KEY_SUPPORTED = False
 818        JSON_KEY_VALUE_PAIR_SEP = ","
 819        SUPPORTS_TO_NUMBER = False
 820        PARSE_JSON_NAME: t.Optional[str] = None
 821        PAD_FILL_PATTERN_IS_REQUIRED = True
 822        WRAP_DERIVED_VALUES = False
 823        VARCHAR_REQUIRES_SIZE = True
 824        SUPPORTS_MEDIAN = False
 825        UPDATE_STATEMENT_SUPPORTS_FROM = False
 826
 827        TRANSFORMS = {
 828            **generator.Generator.TRANSFORMS,
 829            exp.ArrayAgg: rename_func("GROUP_CONCAT"),
 830            exp.BitwiseAndAgg: rename_func("BIT_AND"),
 831            exp.BitwiseOrAgg: rename_func("BIT_OR"),
 832            exp.BitwiseXorAgg: rename_func("BIT_XOR"),
 833            exp.BitwiseCount: rename_func("BIT_COUNT"),
 834            exp.Chr: lambda self, e: self.chr_sql(e, "CHAR"),
 835            exp.CurrentDate: no_paren_current_date_sql,
 836            exp.CurrentVersion: rename_func("VERSION"),
 837            exp.DateDiff: _remove_ts_or_ds_to_date(
 838                lambda self, e: self.func("DATEDIFF", e.this, e.expression), ("this", "expression")
 839            ),
 840            exp.DateAdd: _remove_ts_or_ds_to_date(date_add_sql("ADD")),
 841            exp.DateStrToDate: datestrtodate_sql,
 842            exp.DateSub: _remove_ts_or_ds_to_date(date_add_sql("SUB")),
 843            exp.DateTrunc: _date_trunc_sql,
 844            exp.Day: _remove_ts_or_ds_to_date(),
 845            exp.DayOfMonth: _remove_ts_or_ds_to_date(rename_func("DAYOFMONTH")),
 846            exp.DayOfWeek: _remove_ts_or_ds_to_date(rename_func("DAYOFWEEK")),
 847            exp.DayOfYear: _remove_ts_or_ds_to_date(rename_func("DAYOFYEAR")),
 848            exp.GroupConcat: lambda self,
 849            e: f"""GROUP_CONCAT({self.sql(e, "this")} SEPARATOR {self.sql(e, "separator") or "','"})""",
 850            exp.ILike: no_ilike_sql,
 851            exp.JSONExtractScalar: arrow_json_extract_sql,
 852            exp.Length: length_or_char_length_sql,
 853            exp.LogicalOr: rename_func("MAX"),
 854            exp.LogicalAnd: rename_func("MIN"),
 855            exp.Max: max_or_greatest,
 856            exp.Min: min_or_least,
 857            exp.Month: _remove_ts_or_ds_to_date(),
 858            exp.NullSafeEQ: lambda self, e: self.binary(e, "<=>"),
 859            exp.NullSafeNEQ: lambda self, e: f"NOT {self.binary(e, '<=>')}",
 860            exp.NumberToStr: rename_func("FORMAT"),
 861            exp.Pivot: no_pivot_sql,
 862            exp.Select: transforms.preprocess(
 863                [
 864                    transforms.eliminate_distinct_on,
 865                    transforms.eliminate_semi_and_anti_joins,
 866                    transforms.eliminate_qualify,
 867                    transforms.eliminate_full_outer_join,
 868                    transforms.unnest_generate_date_array_using_recursive_cte,
 869                ]
 870            ),
 871            exp.StrPosition: lambda self, e: strposition_sql(
 872                self, e, func_name="LOCATE", supports_position=True
 873            ),
 874            exp.StrToDate: _str_to_date_sql,
 875            exp.StrToTime: _str_to_date_sql,
 876            exp.Stuff: rename_func("INSERT"),
 877            exp.SessionUser: lambda *_: "SESSION_USER()",
 878            exp.TableSample: no_tablesample_sql,
 879            exp.TimeFromParts: rename_func("MAKETIME"),
 880            exp.TimestampAdd: date_add_interval_sql("DATE", "ADD"),
 881            exp.TimestampDiff: lambda self, e: self.func(
 882                "TIMESTAMPDIFF", unit_to_var(e), e.expression, e.this
 883            ),
 884            exp.TimestampSub: date_add_interval_sql("DATE", "SUB"),
 885            exp.TimeStrToUnix: rename_func("UNIX_TIMESTAMP"),
 886            exp.TimeStrToTime: lambda self, e: timestrtotime_sql(
 887                self,
 888                e,
 889                include_precision=not e.args.get("zone"),
 890            ),
 891            exp.TimeToStr: _remove_ts_or_ds_to_date(
 892                lambda self, e: self.func("DATE_FORMAT", e.this, self.format_time(e))
 893            ),
 894            exp.Trim: trim_sql,
 895            exp.Trunc: rename_func("TRUNCATE"),
 896            exp.TryCast: no_trycast_sql,
 897            exp.TsOrDsAdd: date_add_sql("ADD"),
 898            exp.TsOrDsDiff: lambda self, e: self.func("DATEDIFF", e.this, e.expression),
 899            exp.TsOrDsToDate: _ts_or_ds_to_date_sql,
 900            exp.Unicode: lambda self, e: f"ORD(CONVERT({self.sql(e.this)} USING utf32))",
 901            exp.UnixToTime: _unix_to_time_sql,
 902            exp.Week: _remove_ts_or_ds_to_date(),
 903            exp.WeekOfYear: _remove_ts_or_ds_to_date(rename_func("WEEKOFYEAR")),
 904            exp.Year: _remove_ts_or_ds_to_date(),
 905            exp.UtcTimestamp: rename_func("UTC_TIMESTAMP"),
 906            exp.UtcTime: rename_func("UTC_TIME"),
 907        }
 908
 909        UNSIGNED_TYPE_MAPPING = {
 910            exp.DataType.Type.UBIGINT: "BIGINT",
 911            exp.DataType.Type.UINT: "INT",
 912            exp.DataType.Type.UMEDIUMINT: "MEDIUMINT",
 913            exp.DataType.Type.USMALLINT: "SMALLINT",
 914            exp.DataType.Type.UTINYINT: "TINYINT",
 915            exp.DataType.Type.UDECIMAL: "DECIMAL",
 916            exp.DataType.Type.UDOUBLE: "DOUBLE",
 917        }
 918
 919        TIMESTAMP_TYPE_MAPPING = {
 920            exp.DataType.Type.DATETIME2: "DATETIME",
 921            exp.DataType.Type.SMALLDATETIME: "DATETIME",
 922            exp.DataType.Type.TIMESTAMP: "DATETIME",
 923            exp.DataType.Type.TIMESTAMPNTZ: "DATETIME",
 924            exp.DataType.Type.TIMESTAMPTZ: "TIMESTAMP",
 925            exp.DataType.Type.TIMESTAMPLTZ: "TIMESTAMP",
 926        }
 927
 928        TYPE_MAPPING = {
 929            **generator.Generator.TYPE_MAPPING,
 930            **UNSIGNED_TYPE_MAPPING,
 931            **TIMESTAMP_TYPE_MAPPING,
 932        }
 933
 934        TYPE_MAPPING.pop(exp.DataType.Type.MEDIUMTEXT)
 935        TYPE_MAPPING.pop(exp.DataType.Type.LONGTEXT)
 936        TYPE_MAPPING.pop(exp.DataType.Type.TINYTEXT)
 937        TYPE_MAPPING.pop(exp.DataType.Type.BLOB)
 938        TYPE_MAPPING.pop(exp.DataType.Type.MEDIUMBLOB)
 939        TYPE_MAPPING.pop(exp.DataType.Type.LONGBLOB)
 940        TYPE_MAPPING.pop(exp.DataType.Type.TINYBLOB)
 941
 942        PROPERTIES_LOCATION = {
 943            **generator.Generator.PROPERTIES_LOCATION,
 944            exp.TransientProperty: exp.Properties.Location.UNSUPPORTED,
 945            exp.VolatileProperty: exp.Properties.Location.UNSUPPORTED,
 946            exp.PartitionedByProperty: exp.Properties.Location.UNSUPPORTED,
 947            exp.PartitionByRangeProperty: exp.Properties.Location.POST_SCHEMA,
 948            exp.PartitionByListProperty: exp.Properties.Location.POST_SCHEMA,
 949        }
 950
 951        LIMIT_FETCH = "LIMIT"
 952
 953        LIMIT_ONLY_LITERALS = True
 954
 955        CHAR_CAST_MAPPING = dict.fromkeys(
 956            (
 957                exp.DataType.Type.LONGTEXT,
 958                exp.DataType.Type.LONGBLOB,
 959                exp.DataType.Type.MEDIUMBLOB,
 960                exp.DataType.Type.MEDIUMTEXT,
 961                exp.DataType.Type.TEXT,
 962                exp.DataType.Type.TINYBLOB,
 963                exp.DataType.Type.TINYTEXT,
 964                exp.DataType.Type.VARCHAR,
 965            ),
 966            "CHAR",
 967        )
 968        SIGNED_CAST_MAPPING = dict.fromkeys(
 969            (
 970                exp.DataType.Type.BIGINT,
 971                exp.DataType.Type.BOOLEAN,
 972                exp.DataType.Type.INT,
 973                exp.DataType.Type.SMALLINT,
 974                exp.DataType.Type.TINYINT,
 975                exp.DataType.Type.MEDIUMINT,
 976            ),
 977            "SIGNED",
 978        )
 979
 980        # MySQL doesn't support many datatypes in cast.
 981        # https://dev.mysql.com/doc/refman/8.0/en/cast-functions.html#function_cast
 982        CAST_MAPPING = {
 983            **CHAR_CAST_MAPPING,
 984            **SIGNED_CAST_MAPPING,
 985            exp.DataType.Type.UBIGINT: "UNSIGNED",
 986        }
 987
 988        TIMESTAMP_FUNC_TYPES = {
 989            exp.DataType.Type.TIMESTAMPTZ,
 990            exp.DataType.Type.TIMESTAMPLTZ,
 991        }
 992
 993        # https://dev.mysql.com/doc/refman/8.0/en/keywords.html
 994        RESERVED_KEYWORDS = {
 995            "accessible",
 996            "add",
 997            "all",
 998            "alter",
 999            "analyze",
1000            "and",
1001            "as",
1002            "asc",
1003            "asensitive",
1004            "before",
1005            "between",
1006            "bigint",
1007            "binary",
1008            "blob",
1009            "both",
1010            "by",
1011            "call",
1012            "cascade",
1013            "case",
1014            "change",
1015            "char",
1016            "character",
1017            "check",
1018            "collate",
1019            "column",
1020            "condition",
1021            "constraint",
1022            "continue",
1023            "convert",
1024            "create",
1025            "cross",
1026            "cube",
1027            "cume_dist",
1028            "current_date",
1029            "current_time",
1030            "current_timestamp",
1031            "current_user",
1032            "cursor",
1033            "database",
1034            "databases",
1035            "day_hour",
1036            "day_microsecond",
1037            "day_minute",
1038            "day_second",
1039            "dec",
1040            "decimal",
1041            "declare",
1042            "default",
1043            "delayed",
1044            "delete",
1045            "dense_rank",
1046            "desc",
1047            "describe",
1048            "deterministic",
1049            "distinct",
1050            "distinctrow",
1051            "div",
1052            "double",
1053            "drop",
1054            "dual",
1055            "each",
1056            "else",
1057            "elseif",
1058            "empty",
1059            "enclosed",
1060            "escaped",
1061            "except",
1062            "exists",
1063            "exit",
1064            "explain",
1065            "false",
1066            "fetch",
1067            "first_value",
1068            "float",
1069            "float4",
1070            "float8",
1071            "for",
1072            "force",
1073            "foreign",
1074            "from",
1075            "fulltext",
1076            "function",
1077            "generated",
1078            "get",
1079            "grant",
1080            "group",
1081            "grouping",
1082            "groups",
1083            "having",
1084            "high_priority",
1085            "hour_microsecond",
1086            "hour_minute",
1087            "hour_second",
1088            "if",
1089            "ignore",
1090            "in",
1091            "index",
1092            "infile",
1093            "inner",
1094            "inout",
1095            "insensitive",
1096            "insert",
1097            "int",
1098            "int1",
1099            "int2",
1100            "int3",
1101            "int4",
1102            "int8",
1103            "integer",
1104            "intersect",
1105            "interval",
1106            "into",
1107            "io_after_gtids",
1108            "io_before_gtids",
1109            "is",
1110            "iterate",
1111            "join",
1112            "json_table",
1113            "key",
1114            "keys",
1115            "kill",
1116            "lag",
1117            "last_value",
1118            "lateral",
1119            "lead",
1120            "leading",
1121            "leave",
1122            "left",
1123            "like",
1124            "limit",
1125            "linear",
1126            "lines",
1127            "load",
1128            "localtime",
1129            "localtimestamp",
1130            "lock",
1131            "long",
1132            "longblob",
1133            "longtext",
1134            "loop",
1135            "low_priority",
1136            "master_bind",
1137            "master_ssl_verify_server_cert",
1138            "match",
1139            "maxvalue",
1140            "mediumblob",
1141            "mediumint",
1142            "mediumtext",
1143            "middleint",
1144            "minute_microsecond",
1145            "minute_second",
1146            "mod",
1147            "modifies",
1148            "natural",
1149            "not",
1150            "no_write_to_binlog",
1151            "nth_value",
1152            "ntile",
1153            "null",
1154            "numeric",
1155            "of",
1156            "on",
1157            "optimize",
1158            "optimizer_costs",
1159            "option",
1160            "optionally",
1161            "or",
1162            "order",
1163            "out",
1164            "outer",
1165            "outfile",
1166            "over",
1167            "partition",
1168            "percent_rank",
1169            "precision",
1170            "primary",
1171            "procedure",
1172            "purge",
1173            "range",
1174            "rank",
1175            "read",
1176            "reads",
1177            "read_write",
1178            "real",
1179            "recursive",
1180            "references",
1181            "regexp",
1182            "release",
1183            "rename",
1184            "repeat",
1185            "replace",
1186            "require",
1187            "resignal",
1188            "restrict",
1189            "return",
1190            "revoke",
1191            "right",
1192            "rlike",
1193            "row",
1194            "rows",
1195            "row_number",
1196            "schema",
1197            "schemas",
1198            "second_microsecond",
1199            "select",
1200            "sensitive",
1201            "separator",
1202            "set",
1203            "show",
1204            "signal",
1205            "smallint",
1206            "spatial",
1207            "specific",
1208            "sql",
1209            "sqlexception",
1210            "sqlstate",
1211            "sqlwarning",
1212            "sql_big_result",
1213            "sql_calc_found_rows",
1214            "sql_small_result",
1215            "ssl",
1216            "starting",
1217            "stored",
1218            "straight_join",
1219            "system",
1220            "table",
1221            "terminated",
1222            "then",
1223            "tinyblob",
1224            "tinyint",
1225            "tinytext",
1226            "to",
1227            "trailing",
1228            "trigger",
1229            "true",
1230            "undo",
1231            "union",
1232            "unique",
1233            "unlock",
1234            "unsigned",
1235            "update",
1236            "usage",
1237            "use",
1238            "using",
1239            "utc_date",
1240            "utc_time",
1241            "utc_timestamp",
1242            "values",
1243            "varbinary",
1244            "varchar",
1245            "varcharacter",
1246            "varying",
1247            "virtual",
1248            "when",
1249            "where",
1250            "while",
1251            "window",
1252            "with",
1253            "write",
1254            "xor",
1255            "year_month",
1256            "zerofill",
1257        }
1258
1259        def computedcolumnconstraint_sql(self, expression: exp.ComputedColumnConstraint) -> str:
1260            persisted = "STORED" if expression.args.get("persisted") else "VIRTUAL"
1261            return f"GENERATED ALWAYS AS ({self.sql(expression.this.unnest())}) {persisted}"
1262
1263        def array_sql(self, expression: exp.Array) -> str:
1264            self.unsupported("Arrays are not supported by MySQL")
1265            return self.function_fallback_sql(expression)
1266
1267        def arraycontainsall_sql(self, expression: exp.ArrayContainsAll) -> str:
1268            self.unsupported("Array operations are not supported by MySQL")
1269            return self.function_fallback_sql(expression)
1270
1271        def dpipe_sql(self, expression: exp.DPipe) -> str:
1272            return self.func("CONCAT", *expression.flatten())
1273
1274        def extract_sql(self, expression: exp.Extract) -> str:
1275            unit = expression.name
1276            if unit and unit.lower() == "epoch":
1277                return self.func("UNIX_TIMESTAMP", expression.expression)
1278
1279            return super().extract_sql(expression)
1280
1281        def datatype_sql(self, expression: exp.DataType) -> str:
1282            if (
1283                self.VARCHAR_REQUIRES_SIZE
1284                and expression.is_type(exp.DataType.Type.VARCHAR)
1285                and not expression.expressions
1286            ):
1287                # `VARCHAR` must always have a size - if it doesn't, we always generate `TEXT`
1288                return "TEXT"
1289
1290            # https://dev.mysql.com/doc/refman/8.0/en/numeric-type-syntax.html
1291            result = super().datatype_sql(expression)
1292            if expression.this in self.UNSIGNED_TYPE_MAPPING:
1293                result = f"{result} UNSIGNED"
1294
1295            return result
1296
1297        def jsonarraycontains_sql(self, expression: exp.JSONArrayContains) -> str:
1298            return f"{self.sql(expression, 'this')} MEMBER OF({self.sql(expression, 'expression')})"
1299
1300        def cast_sql(self, expression: exp.Cast, safe_prefix: t.Optional[str] = None) -> str:
1301            if expression.to.this in self.TIMESTAMP_FUNC_TYPES:
1302                return self.func("TIMESTAMP", expression.this)
1303
1304            to = self.CAST_MAPPING.get(expression.to.this)
1305
1306            if to:
1307                expression.to.set("this", to)
1308            return super().cast_sql(expression)
1309
1310        def show_sql(self, expression: exp.Show) -> str:
1311            this = f" {expression.name}"
1312            full = " FULL" if expression.args.get("full") else ""
1313            global_ = " GLOBAL" if expression.args.get("global_") else ""
1314
1315            target = self.sql(expression, "target")
1316            target = f" {target}" if target else ""
1317            if expression.name in ("COLUMNS", "INDEX"):
1318                target = f" FROM{target}"
1319            elif expression.name == "GRANTS":
1320                target = f" FOR{target}"
1321            elif expression.name in ("LINKS", "PARTITIONS"):
1322                target = f" ON{target}" if target else ""
1323            elif expression.name == "PROJECTIONS":
1324                target = f" ON TABLE{target}" if target else ""
1325
1326            db = self._prefixed_sql("FROM", expression, "db")
1327
1328            like = self._prefixed_sql("LIKE", expression, "like")
1329            where = self.sql(expression, "where")
1330
1331            types = self.expressions(expression, key="types")
1332            types = f" {types}" if types else types
1333            query = self._prefixed_sql("FOR QUERY", expression, "query")
1334
1335            if expression.name == "PROFILE":
1336                offset = self._prefixed_sql("OFFSET", expression, "offset")
1337                limit = self._prefixed_sql("LIMIT", expression, "limit")
1338            else:
1339                offset = ""
1340                limit = self._oldstyle_limit_sql(expression)
1341
1342            log = self._prefixed_sql("IN", expression, "log")
1343            position = self._prefixed_sql("FROM", expression, "position")
1344
1345            channel = self._prefixed_sql("FOR CHANNEL", expression, "channel")
1346
1347            if expression.name == "ENGINE":
1348                mutex_or_status = " MUTEX" if expression.args.get("mutex") else " STATUS"
1349            else:
1350                mutex_or_status = ""
1351
1352            for_table = self._prefixed_sql("FOR TABLE", expression, "for_table")
1353            for_group = self._prefixed_sql("FOR GROUP", expression, "for_group")
1354            for_user = self._prefixed_sql("FOR USER", expression, "for_user")
1355            for_role = self._prefixed_sql("FOR ROLE", expression, "for_role")
1356            into_outfile = self._prefixed_sql("INTO OUTFILE", expression, "into_outfile")
1357            json = " JSON" if expression.args.get("json") else ""
1358
1359            return f"SHOW{full}{global_}{this}{json}{target}{for_table}{types}{db}{query}{log}{position}{channel}{mutex_or_status}{like}{where}{offset}{limit}{for_group}{for_user}{for_role}{into_outfile}"
1360
1361        def alterrename_sql(self, expression: exp.AlterRename, include_to: bool = True) -> str:
1362            """To avoid TO keyword in ALTER ... RENAME statements.
1363            It's moved from Doris, because it's the same for all MySQL, Doris, and StarRocks.
1364            """
1365            return super().alterrename_sql(expression, include_to=False)
1366
1367        def altercolumn_sql(self, expression: exp.AlterColumn) -> str:
1368            dtype = self.sql(expression, "dtype")
1369            if not dtype:
1370                return super().altercolumn_sql(expression)
1371
1372            this = self.sql(expression, "this")
1373            return f"MODIFY COLUMN {this} {dtype}"
1374
1375        def _prefixed_sql(self, prefix: str, expression: exp.Expression, arg: str) -> str:
1376            sql = self.sql(expression, arg)
1377            return f" {prefix} {sql}" if sql else ""
1378
1379        def _oldstyle_limit_sql(self, expression: exp.Show) -> str:
1380            limit = self.sql(expression, "limit")
1381            offset = self.sql(expression, "offset")
1382            if limit:
1383                limit_offset = f"{offset}, {limit}" if offset else limit
1384                return f" LIMIT {limit_offset}"
1385            return ""
1386
1387        def timestamptrunc_sql(self, expression: exp.TimestampTrunc) -> str:
1388            unit = expression.args.get("unit")
1389
1390            # Pick an old-enough date to avoid negative timestamp diffs
1391            start_ts = "'0000-01-01 00:00:00'"
1392
1393            # Source: https://stackoverflow.com/a/32955740
1394            timestamp_diff = build_date_delta(exp.TimestampDiff)([unit, start_ts, expression.this])
1395            interval = exp.Interval(this=timestamp_diff, unit=unit)
1396            dateadd = build_date_delta_with_interval(exp.DateAdd)([start_ts, interval])
1397
1398            return self.sql(dateadd)
1399
1400        def converttimezone_sql(self, expression: exp.ConvertTimezone) -> str:
1401            from_tz = expression.args.get("source_tz")
1402            to_tz = expression.args.get("target_tz")
1403            dt = expression.args.get("timestamp")
1404
1405            return self.func("CONVERT_TZ", dt, from_tz, to_tz)
1406
1407        def attimezone_sql(self, expression: exp.AtTimeZone) -> str:
1408            self.unsupported("AT TIME ZONE is not supported by MySQL")
1409            return self.sql(expression.this)
1410
1411        def isascii_sql(self, expression: exp.IsAscii) -> str:
1412            return f"REGEXP_LIKE({self.sql(expression.this)}, '^[[:ascii:]]*$')"
1413
1414        def ignorenulls_sql(self, expression: exp.IgnoreNulls) -> str:
1415            # https://dev.mysql.com/doc/refman/8.4/en/window-function-descriptions.html
1416            self.unsupported("MySQL does not support IGNORE NULLS.")
1417            return self.sql(expression.this)
1418
1419        @unsupported_args("this")
1420        def currentschema_sql(self, expression: exp.CurrentSchema) -> str:
1421            return self.func("SCHEMA")
1422
1423        def partition_sql(self, expression: exp.Partition) -> str:
1424            parent = expression.parent
1425            if isinstance(parent, (exp.PartitionByRangeProperty, exp.PartitionByListProperty)):
1426                return self.expressions(expression, flat=True)
1427            return super().partition_sql(expression)
1428
1429        def _partition_by_sql(
1430            self, expression: exp.PartitionByRangeProperty | exp.PartitionByListProperty, kind: str
1431        ) -> str:
1432            partitions = self.expressions(expression, key="partition_expressions", flat=True)
1433            create = self.expressions(expression, key="create_expressions", flat=True)
1434            return f"PARTITION BY {kind} ({partitions}) ({create})"
1435
1436        def partitionbyrangeproperty_sql(self, expression: exp.PartitionByRangeProperty) -> str:
1437            return self._partition_by_sql(expression, "RANGE")
1438
1439        def partitionbylistproperty_sql(self, expression: exp.PartitionByListProperty) -> str:
1440            return self._partition_by_sql(expression, "LIST")
1441
1442        def partitionlist_sql(self, expression: exp.PartitionList) -> str:
1443            name = self.sql(expression, "this")
1444            values = self.expressions(expression, flat=True)
1445            return f"PARTITION {name} VALUES IN ({values})"
1446
1447        def partitionrange_sql(self, expression: exp.PartitionRange) -> str:
1448            name = self.sql(expression, "this")
1449            values = self.expressions(expression, flat=True)
1450            return f"PARTITION {name} VALUES LESS THAN ({values})"
TIME_SPECIFIERS = {'H', 'S', 'i', 'h', 'k', 'I', 'p', 'l', 'r', 'f', 's', 'T'}
def date_add_sql( kind: str) -> Callable[[sqlglot.generator.Generator, sqlglot.expressions.Expression], str]:
117def date_add_sql(
118    kind: str,
119) -> t.Callable[[generator.Generator, exp.Expression], str]:
120    def func(self: generator.Generator, expression: exp.Expression) -> str:
121        return self.func(
122            f"DATE_{kind}",
123            expression.this,
124            exp.Interval(this=expression.expression, unit=unit_to_var(expression)),
125        )
126
127    return func
class MySQL(sqlglot.dialects.dialect.Dialect):
 150class MySQL(Dialect):
 151    PROMOTE_TO_INFERRED_DATETIME_TYPE = True
 152
 153    # https://dev.mysql.com/doc/refman/8.0/en/identifiers.html
 154    IDENTIFIERS_CAN_START_WITH_DIGIT = True
 155
 156    # We default to treating all identifiers as case-sensitive, since it matches MySQL's
 157    # behavior on Linux systems. For MacOS and Windows systems, one can override this
 158    # setting by specifying `dialect="mysql, normalization_strategy = lowercase"`.
 159    #
 160    # See also https://dev.mysql.com/doc/refman/8.2/en/identifier-case-sensitivity.html
 161    NORMALIZATION_STRATEGY = NormalizationStrategy.CASE_SENSITIVE
 162
 163    TIME_FORMAT = "'%Y-%m-%d %T'"
 164    DPIPE_IS_STRING_CONCAT = False
 165    SUPPORTS_USER_DEFINED_TYPES = False
 166    SUPPORTS_SEMI_ANTI_JOIN = False
 167    SAFE_DIVISION = True
 168    SAFE_TO_ELIMINATE_DOUBLE_NEGATION = False
 169    LEAST_GREATEST_IGNORES_NULLS = False
 170
 171    EXPRESSION_METADATA = EXPRESSION_METADATA.copy()
 172
 173    # https://prestodb.io/docs/current/functions/datetime.html#mysql-date-functions
 174    TIME_MAPPING = {
 175        "%M": "%B",
 176        "%c": "%-m",
 177        "%e": "%-d",
 178        "%h": "%I",
 179        "%i": "%M",
 180        "%s": "%S",
 181        "%u": "%W",
 182        "%k": "%-H",
 183        "%l": "%-I",
 184        "%T": "%H:%M:%S",
 185        "%W": "%A",
 186    }
 187
 188    VALID_INTERVAL_UNITS = {
 189        *Dialect.VALID_INTERVAL_UNITS,
 190        "SECOND_MICROSECOND",
 191        "MINUTE_MICROSECOND",
 192        "MINUTE_SECOND",
 193        "HOUR_MICROSECOND",
 194        "HOUR_SECOND",
 195        "HOUR_MINUTE",
 196        "DAY_MICROSECOND",
 197        "DAY_SECOND",
 198        "DAY_MINUTE",
 199        "DAY_HOUR",
 200        "YEAR_MONTH",
 201    }
 202
 203    class Tokenizer(tokens.Tokenizer):
 204        QUOTES = ["'", '"']
 205        COMMENTS = ["--", "#", ("/*", "*/")]
 206        IDENTIFIERS = ["`"]
 207        STRING_ESCAPES = ["'", '"', "\\"]
 208        BIT_STRINGS = [("b'", "'"), ("B'", "'"), ("0b", "")]
 209        HEX_STRINGS = [("x'", "'"), ("X'", "'"), ("0x", "")]
 210        # https://dev.mysql.com/doc/refman/8.4/en/string-literals.html
 211        ESCAPE_FOLLOW_CHARS = ["0", "b", "n", "r", "t", "Z", "%", "_"]
 212
 213        NESTED_COMMENTS = False
 214
 215        KEYWORDS = {
 216            **tokens.Tokenizer.KEYWORDS,
 217            "BLOB": TokenType.BLOB,
 218            "CHARSET": TokenType.CHARACTER_SET,
 219            "DISTINCTROW": TokenType.DISTINCT,
 220            "EXPLAIN": TokenType.DESCRIBE,
 221            "FORCE": TokenType.FORCE,
 222            "IGNORE": TokenType.IGNORE,
 223            "KEY": TokenType.KEY,
 224            "LOCK TABLES": TokenType.COMMAND,
 225            "LONGBLOB": TokenType.LONGBLOB,
 226            "LONGTEXT": TokenType.LONGTEXT,
 227            "MEDIUMBLOB": TokenType.MEDIUMBLOB,
 228            "MEDIUMINT": TokenType.MEDIUMINT,
 229            "MEDIUMTEXT": TokenType.MEDIUMTEXT,
 230            "MEMBER OF": TokenType.MEMBER_OF,
 231            "MOD": TokenType.MOD,
 232            "SEPARATOR": TokenType.SEPARATOR,
 233            "SERIAL": TokenType.SERIAL,
 234            "SIGNED": TokenType.BIGINT,
 235            "SIGNED INTEGER": TokenType.BIGINT,
 236            "SOUNDS LIKE": TokenType.SOUNDS_LIKE,
 237            "START": TokenType.BEGIN,
 238            "TIMESTAMP": TokenType.TIMESTAMPTZ,
 239            "TINYBLOB": TokenType.TINYBLOB,
 240            "TINYTEXT": TokenType.TINYTEXT,
 241            "UNLOCK TABLES": TokenType.COMMAND,
 242            "UNSIGNED": TokenType.UBIGINT,
 243            "UNSIGNED INTEGER": TokenType.UBIGINT,
 244            "YEAR": TokenType.YEAR,
 245            "_ARMSCII8": TokenType.INTRODUCER,
 246            "_ASCII": TokenType.INTRODUCER,
 247            "_BIG5": TokenType.INTRODUCER,
 248            "_BINARY": TokenType.INTRODUCER,
 249            "_CP1250": TokenType.INTRODUCER,
 250            "_CP1251": TokenType.INTRODUCER,
 251            "_CP1256": TokenType.INTRODUCER,
 252            "_CP1257": TokenType.INTRODUCER,
 253            "_CP850": TokenType.INTRODUCER,
 254            "_CP852": TokenType.INTRODUCER,
 255            "_CP866": TokenType.INTRODUCER,
 256            "_CP932": TokenType.INTRODUCER,
 257            "_DEC8": TokenType.INTRODUCER,
 258            "_EUCJPMS": TokenType.INTRODUCER,
 259            "_EUCKR": TokenType.INTRODUCER,
 260            "_GB18030": TokenType.INTRODUCER,
 261            "_GB2312": TokenType.INTRODUCER,
 262            "_GBK": TokenType.INTRODUCER,
 263            "_GEOSTD8": TokenType.INTRODUCER,
 264            "_GREEK": TokenType.INTRODUCER,
 265            "_HEBREW": TokenType.INTRODUCER,
 266            "_HP8": TokenType.INTRODUCER,
 267            "_KEYBCS2": TokenType.INTRODUCER,
 268            "_KOI8R": TokenType.INTRODUCER,
 269            "_KOI8U": TokenType.INTRODUCER,
 270            "_LATIN1": TokenType.INTRODUCER,
 271            "_LATIN2": TokenType.INTRODUCER,
 272            "_LATIN5": TokenType.INTRODUCER,
 273            "_LATIN7": TokenType.INTRODUCER,
 274            "_MACCE": TokenType.INTRODUCER,
 275            "_MACROMAN": TokenType.INTRODUCER,
 276            "_SJIS": TokenType.INTRODUCER,
 277            "_SWE7": TokenType.INTRODUCER,
 278            "_TIS620": TokenType.INTRODUCER,
 279            "_UCS2": TokenType.INTRODUCER,
 280            "_UJIS": TokenType.INTRODUCER,
 281            # https://dev.mysql.com/doc/refman/8.0/en/string-literals.html
 282            "_UTF8": TokenType.INTRODUCER,
 283            "_UTF16": TokenType.INTRODUCER,
 284            "_UTF16LE": TokenType.INTRODUCER,
 285            "_UTF32": TokenType.INTRODUCER,
 286            "_UTF8MB3": TokenType.INTRODUCER,
 287            "_UTF8MB4": TokenType.INTRODUCER,
 288            "@@": TokenType.SESSION_PARAMETER,
 289        }
 290
 291        COMMANDS = {*tokens.Tokenizer.COMMANDS, TokenType.REPLACE} - {TokenType.SHOW}
 292
 293    class Parser(parser.Parser):
 294        FUNC_TOKENS = {
 295            *parser.Parser.FUNC_TOKENS,
 296            TokenType.DATABASE,
 297            TokenType.MOD,
 298            TokenType.SCHEMA,
 299            TokenType.VALUES,
 300            TokenType.CHARACTER_SET,
 301        }
 302
 303        CONJUNCTION = {
 304            **parser.Parser.CONJUNCTION,
 305            TokenType.DAMP: exp.And,
 306            TokenType.XOR: exp.Xor,
 307        }
 308
 309        DISJUNCTION = {
 310            **parser.Parser.DISJUNCTION,
 311            TokenType.DPIPE: exp.Or,
 312        }
 313
 314        TABLE_ALIAS_TOKENS = (
 315            parser.Parser.TABLE_ALIAS_TOKENS - parser.Parser.TABLE_INDEX_HINT_TOKENS
 316        )
 317
 318        RANGE_PARSERS = {
 319            **parser.Parser.RANGE_PARSERS,
 320            TokenType.SOUNDS_LIKE: lambda self, this: self.expression(
 321                exp.EQ,
 322                this=self.expression(exp.Soundex, this=this),
 323                expression=self.expression(exp.Soundex, this=self._parse_term()),
 324            ),
 325            TokenType.MEMBER_OF: lambda self, this: self.expression(
 326                exp.JSONArrayContains,
 327                this=this,
 328                expression=self._parse_wrapped(self._parse_expression),
 329            ),
 330        }
 331
 332        FUNCTIONS = {
 333            **parser.Parser.FUNCTIONS,
 334            "BIT_AND": exp.BitwiseAndAgg.from_arg_list,
 335            "BIT_OR": exp.BitwiseOrAgg.from_arg_list,
 336            "BIT_XOR": exp.BitwiseXorAgg.from_arg_list,
 337            "BIT_COUNT": exp.BitwiseCount.from_arg_list,
 338            "CONVERT_TZ": lambda args: exp.ConvertTimezone(
 339                source_tz=seq_get(args, 1), target_tz=seq_get(args, 2), timestamp=seq_get(args, 0)
 340            ),
 341            "CURDATE": exp.CurrentDate.from_arg_list,
 342            "CURTIME": exp.CurrentTime.from_arg_list,
 343            "DATE": lambda args: exp.TsOrDsToDate(this=seq_get(args, 0)),
 344            "DATE_ADD": build_date_delta_with_interval(exp.DateAdd),
 345            "DATE_FORMAT": build_formatted_time(exp.TimeToStr, "mysql"),
 346            "DATE_SUB": build_date_delta_with_interval(exp.DateSub),
 347            "DAY": lambda args: exp.Day(this=exp.TsOrDsToDate(this=seq_get(args, 0))),
 348            "DAYOFMONTH": lambda args: exp.DayOfMonth(this=exp.TsOrDsToDate(this=seq_get(args, 0))),
 349            "DAYOFWEEK": lambda args: exp.DayOfWeek(this=exp.TsOrDsToDate(this=seq_get(args, 0))),
 350            "DAYOFYEAR": lambda args: exp.DayOfYear(this=exp.TsOrDsToDate(this=seq_get(args, 0))),
 351            "FORMAT": exp.NumberToStr.from_arg_list,
 352            "FROM_UNIXTIME": build_formatted_time(exp.UnixToTime, "mysql"),
 353            "ISNULL": isnull_to_is_null,
 354            "LENGTH": lambda args: exp.Length(this=seq_get(args, 0), binary=True),
 355            "MAKETIME": exp.TimeFromParts.from_arg_list,
 356            "MONTH": lambda args: exp.Month(this=exp.TsOrDsToDate(this=seq_get(args, 0))),
 357            "MONTHNAME": lambda args: exp.TimeToStr(
 358                this=exp.TsOrDsToDate(this=seq_get(args, 0)),
 359                format=exp.Literal.string("%B"),
 360            ),
 361            "SCHEMA": exp.CurrentSchema.from_arg_list,
 362            "DATABASE": exp.CurrentSchema.from_arg_list,
 363            "STR_TO_DATE": _str_to_date,
 364            "TIMESTAMPDIFF": build_date_delta(exp.TimestampDiff),
 365            "TO_DAYS": lambda args: exp.paren(
 366                exp.DateDiff(
 367                    this=exp.TsOrDsToDate(this=seq_get(args, 0)),
 368                    expression=exp.TsOrDsToDate(this=exp.Literal.string("0000-01-01")),
 369                    unit=exp.var("DAY"),
 370                )
 371                + 1
 372            ),
 373            "VERSION": exp.CurrentVersion.from_arg_list,
 374            "WEEK": lambda args: exp.Week(
 375                this=exp.TsOrDsToDate(this=seq_get(args, 0)), mode=seq_get(args, 1)
 376            ),
 377            "WEEKOFYEAR": lambda args: exp.WeekOfYear(this=exp.TsOrDsToDate(this=seq_get(args, 0))),
 378            "YEAR": lambda args: exp.Year(this=exp.TsOrDsToDate(this=seq_get(args, 0))),
 379        }
 380
 381        FUNCTION_PARSERS = {
 382            **parser.Parser.FUNCTION_PARSERS,
 383            "GROUP_CONCAT": lambda self: self._parse_group_concat(),
 384            # https://dev.mysql.com/doc/refman/5.7/en/miscellaneous-functions.html#function_values
 385            "VALUES": lambda self: self.expression(
 386                exp.Anonymous, this="VALUES", expressions=[self._parse_id_var()]
 387            ),
 388            "JSON_VALUE": lambda self: self._parse_json_value(),
 389            "SUBSTR": lambda self: self._parse_substring(),
 390        }
 391
 392        STATEMENT_PARSERS = {
 393            **parser.Parser.STATEMENT_PARSERS,
 394            TokenType.SHOW: lambda self: self._parse_show(),
 395        }
 396
 397        SHOW_PARSERS = {
 398            "BINARY LOGS": _show_parser("BINARY LOGS"),
 399            "MASTER LOGS": _show_parser("BINARY LOGS"),
 400            "BINLOG EVENTS": _show_parser("BINLOG EVENTS"),
 401            "CHARACTER SET": _show_parser("CHARACTER SET"),
 402            "CHARSET": _show_parser("CHARACTER SET"),
 403            "COLLATION": _show_parser("COLLATION"),
 404            "FULL COLUMNS": _show_parser("COLUMNS", target="FROM", full=True),
 405            "COLUMNS": _show_parser("COLUMNS", target="FROM"),
 406            "CREATE DATABASE": _show_parser("CREATE DATABASE", target=True),
 407            "CREATE EVENT": _show_parser("CREATE EVENT", target=True),
 408            "CREATE FUNCTION": _show_parser("CREATE FUNCTION", target=True),
 409            "CREATE PROCEDURE": _show_parser("CREATE PROCEDURE", target=True),
 410            "CREATE TABLE": _show_parser("CREATE TABLE", target=True),
 411            "CREATE TRIGGER": _show_parser("CREATE TRIGGER", target=True),
 412            "CREATE VIEW": _show_parser("CREATE VIEW", target=True),
 413            "DATABASES": _show_parser("DATABASES"),
 414            "SCHEMAS": _show_parser("DATABASES"),
 415            "ENGINE": _show_parser("ENGINE", target=True),
 416            "STORAGE ENGINES": _show_parser("ENGINES"),
 417            "ENGINES": _show_parser("ENGINES"),
 418            "ERRORS": _show_parser("ERRORS"),
 419            "EVENTS": _show_parser("EVENTS"),
 420            "FUNCTION CODE": _show_parser("FUNCTION CODE", target=True),
 421            "FUNCTION STATUS": _show_parser("FUNCTION STATUS"),
 422            "GRANTS": _show_parser("GRANTS", target="FOR"),
 423            "INDEX": _show_parser("INDEX", target="FROM"),
 424            "MASTER STATUS": _show_parser("MASTER STATUS"),
 425            "OPEN TABLES": _show_parser("OPEN TABLES"),
 426            "PLUGINS": _show_parser("PLUGINS"),
 427            "PROCEDURE CODE": _show_parser("PROCEDURE CODE", target=True),
 428            "PROCEDURE STATUS": _show_parser("PROCEDURE STATUS"),
 429            "PRIVILEGES": _show_parser("PRIVILEGES"),
 430            "FULL PROCESSLIST": _show_parser("PROCESSLIST", full=True),
 431            "PROCESSLIST": _show_parser("PROCESSLIST"),
 432            "PROFILE": _show_parser("PROFILE"),
 433            "PROFILES": _show_parser("PROFILES"),
 434            "RELAYLOG EVENTS": _show_parser("RELAYLOG EVENTS"),
 435            "REPLICAS": _show_parser("REPLICAS"),
 436            "SLAVE HOSTS": _show_parser("REPLICAS"),
 437            "REPLICA STATUS": _show_parser("REPLICA STATUS"),
 438            "SLAVE STATUS": _show_parser("REPLICA STATUS"),
 439            "GLOBAL STATUS": _show_parser("STATUS", global_=True),
 440            "SESSION STATUS": _show_parser("STATUS"),
 441            "STATUS": _show_parser("STATUS"),
 442            "TABLE STATUS": _show_parser("TABLE STATUS"),
 443            "FULL TABLES": _show_parser("TABLES", full=True),
 444            "TABLES": _show_parser("TABLES"),
 445            "TRIGGERS": _show_parser("TRIGGERS"),
 446            "GLOBAL VARIABLES": _show_parser("VARIABLES", global_=True),
 447            "SESSION VARIABLES": _show_parser("VARIABLES"),
 448            "VARIABLES": _show_parser("VARIABLES"),
 449            "WARNINGS": _show_parser("WARNINGS"),
 450        }
 451
 452        PROPERTY_PARSERS = {
 453            **parser.Parser.PROPERTY_PARSERS,
 454            "LOCK": lambda self: self._parse_property_assignment(exp.LockProperty),
 455            "PARTITION BY": lambda self: self._parse_partition_property(),
 456        }
 457
 458        SET_PARSERS = {
 459            **parser.Parser.SET_PARSERS,
 460            "PERSIST": lambda self: self._parse_set_item_assignment("PERSIST"),
 461            "PERSIST_ONLY": lambda self: self._parse_set_item_assignment("PERSIST_ONLY"),
 462            "CHARACTER SET": lambda self: self._parse_set_item_charset("CHARACTER SET"),
 463            "CHARSET": lambda self: self._parse_set_item_charset("CHARACTER SET"),
 464            "NAMES": lambda self: self._parse_set_item_names(),
 465        }
 466
 467        CONSTRAINT_PARSERS = {
 468            **parser.Parser.CONSTRAINT_PARSERS,
 469            "FULLTEXT": lambda self: self._parse_index_constraint(kind="FULLTEXT"),
 470            "INDEX": lambda self: self._parse_index_constraint(),
 471            "KEY": lambda self: self._parse_index_constraint(),
 472            "SPATIAL": lambda self: self._parse_index_constraint(kind="SPATIAL"),
 473            "ZEROFILL": lambda self: self.expression(exp.ZeroFillColumnConstraint),
 474        }
 475
 476        ALTER_PARSERS = {
 477            **parser.Parser.ALTER_PARSERS,
 478            "MODIFY": lambda self: self._parse_alter_table_alter(),
 479        }
 480
 481        ALTER_ALTER_PARSERS = {
 482            **parser.Parser.ALTER_ALTER_PARSERS,
 483            "INDEX": lambda self: self._parse_alter_table_alter_index(),
 484        }
 485
 486        SCHEMA_UNNAMED_CONSTRAINTS = {
 487            *parser.Parser.SCHEMA_UNNAMED_CONSTRAINTS,
 488            "FULLTEXT",
 489            "INDEX",
 490            "KEY",
 491            "SPATIAL",
 492        }
 493
 494        PROFILE_TYPES: parser.OPTIONS_TYPE = {
 495            **dict.fromkeys(("ALL", "CPU", "IPC", "MEMORY", "SOURCE", "SWAPS"), tuple()),
 496            "BLOCK": ("IO",),
 497            "CONTEXT": ("SWITCHES",),
 498            "PAGE": ("FAULTS",),
 499        }
 500
 501        TYPE_TOKENS = {
 502            *parser.Parser.TYPE_TOKENS,
 503            TokenType.SET,
 504        }
 505
 506        ENUM_TYPE_TOKENS = {
 507            *parser.Parser.ENUM_TYPE_TOKENS,
 508            TokenType.SET,
 509        }
 510
 511        # SELECT [ ALL | DISTINCT | DISTINCTROW ] [ <OPERATION_MODIFIERS> ]
 512        OPERATION_MODIFIERS = {
 513            "HIGH_PRIORITY",
 514            "STRAIGHT_JOIN",
 515            "SQL_SMALL_RESULT",
 516            "SQL_BIG_RESULT",
 517            "SQL_BUFFER_RESULT",
 518            "SQL_NO_CACHE",
 519            "SQL_CALC_FOUND_ROWS",
 520        }
 521
 522        LOG_DEFAULTS_TO_LN = True
 523        STRING_ALIASES = True
 524        VALUES_FOLLOWED_BY_PAREN = False
 525        SUPPORTS_PARTITION_SELECTION = True
 526
 527        def _parse_generated_as_identity(
 528            self,
 529        ) -> (
 530            exp.GeneratedAsIdentityColumnConstraint
 531            | exp.ComputedColumnConstraint
 532            | exp.GeneratedAsRowColumnConstraint
 533        ):
 534            this = super()._parse_generated_as_identity()
 535
 536            if self._match_texts(("STORED", "VIRTUAL")):
 537                persisted = self._prev.text.upper() == "STORED"
 538
 539                if isinstance(this, exp.ComputedColumnConstraint):
 540                    this.set("persisted", persisted)
 541                elif isinstance(this, exp.GeneratedAsIdentityColumnConstraint):
 542                    this = self.expression(
 543                        exp.ComputedColumnConstraint, this=this.expression, persisted=persisted
 544                    )
 545
 546            return this
 547
 548        def _parse_primary_key_part(self) -> t.Optional[exp.Expression]:
 549            this = self._parse_id_var()
 550            if not self._match(TokenType.L_PAREN):
 551                return this
 552
 553            expression = self._parse_number()
 554            self._match_r_paren()
 555            return self.expression(exp.ColumnPrefix, this=this, expression=expression)
 556
 557        def _parse_index_constraint(
 558            self, kind: t.Optional[str] = None
 559        ) -> exp.IndexColumnConstraint:
 560            if kind:
 561                self._match_texts(("INDEX", "KEY"))
 562
 563            this = self._parse_id_var(any_token=False)
 564            index_type = self._match(TokenType.USING) and self._advance_any() and self._prev.text
 565            expressions = self._parse_wrapped_csv(self._parse_ordered)
 566
 567            options = []
 568            while True:
 569                if self._match_text_seq("KEY_BLOCK_SIZE"):
 570                    self._match(TokenType.EQ)
 571                    opt = exp.IndexConstraintOption(key_block_size=self._parse_number())
 572                elif self._match(TokenType.USING):
 573                    opt = exp.IndexConstraintOption(using=self._advance_any() and self._prev.text)
 574                elif self._match_text_seq("WITH", "PARSER"):
 575                    opt = exp.IndexConstraintOption(parser=self._parse_var(any_token=True))
 576                elif self._match(TokenType.COMMENT):
 577                    opt = exp.IndexConstraintOption(comment=self._parse_string())
 578                elif self._match_text_seq("VISIBLE"):
 579                    opt = exp.IndexConstraintOption(visible=True)
 580                elif self._match_text_seq("INVISIBLE"):
 581                    opt = exp.IndexConstraintOption(visible=False)
 582                elif self._match_text_seq("ENGINE_ATTRIBUTE"):
 583                    self._match(TokenType.EQ)
 584                    opt = exp.IndexConstraintOption(engine_attr=self._parse_string())
 585                elif self._match_text_seq("SECONDARY_ENGINE_ATTRIBUTE"):
 586                    self._match(TokenType.EQ)
 587                    opt = exp.IndexConstraintOption(secondary_engine_attr=self._parse_string())
 588                else:
 589                    opt = None
 590
 591                if not opt:
 592                    break
 593
 594                options.append(opt)
 595
 596            return self.expression(
 597                exp.IndexColumnConstraint,
 598                this=this,
 599                expressions=expressions,
 600                kind=kind,
 601                index_type=index_type,
 602                options=options,
 603            )
 604
 605        def _parse_show_mysql(
 606            self,
 607            this: str,
 608            target: bool | str = False,
 609            full: t.Optional[bool] = None,
 610            global_: t.Optional[bool] = None,
 611        ) -> exp.Show:
 612            json = self._match_text_seq("JSON")
 613
 614            if target:
 615                if isinstance(target, str):
 616                    self._match_text_seq(*target.split(" "))
 617                target_id = self._parse_id_var()
 618            else:
 619                target_id = None
 620
 621            log = self._parse_string() if self._match_text_seq("IN") else None
 622
 623            if this in ("BINLOG EVENTS", "RELAYLOG EVENTS"):
 624                position = self._parse_number() if self._match_text_seq("FROM") else None
 625                db = None
 626            else:
 627                position = None
 628                db = None
 629
 630                if self._match(TokenType.FROM):
 631                    db = self._parse_id_var()
 632                elif self._match(TokenType.DOT):
 633                    db = target_id
 634                    target_id = self._parse_id_var()
 635
 636            channel = self._parse_id_var() if self._match_text_seq("FOR", "CHANNEL") else None
 637
 638            like = self._parse_string() if self._match_text_seq("LIKE") else None
 639            where = self._parse_where()
 640
 641            if this == "PROFILE":
 642                types = self._parse_csv(lambda: self._parse_var_from_options(self.PROFILE_TYPES))
 643                query = self._parse_number() if self._match_text_seq("FOR", "QUERY") else None
 644                offset = self._parse_number() if self._match_text_seq("OFFSET") else None
 645                limit = self._parse_number() if self._match_text_seq("LIMIT") else None
 646            else:
 647                types, query = None, None
 648                offset, limit = self._parse_oldstyle_limit()
 649
 650            mutex = True if self._match_text_seq("MUTEX") else None
 651            mutex = False if self._match_text_seq("STATUS") else mutex
 652
 653            for_table = self._parse_id_var() if self._match_text_seq("FOR", "TABLE") else None
 654            for_group = self._parse_string() if self._match_text_seq("FOR", "GROUP") else None
 655            for_user = self._parse_string() if self._match_text_seq("FOR", "USER") else None
 656            for_role = self._parse_string() if self._match_text_seq("FOR", "ROLE") else None
 657            into_outfile = self._parse_string() if self._match_text_seq("INTO", "OUTFILE") else None
 658
 659            return self.expression(
 660                exp.Show,
 661                this=this,
 662                target=target_id,
 663                full=full,
 664                log=log,
 665                position=position,
 666                db=db,
 667                channel=channel,
 668                like=like,
 669                where=where,
 670                types=types,
 671                query=query,
 672                offset=offset,
 673                limit=limit,
 674                mutex=mutex,
 675                for_table=for_table,
 676                for_group=for_group,
 677                for_user=for_user,
 678                for_role=for_role,
 679                into_outfile=into_outfile,
 680                json=json,
 681                global_=global_,
 682            )
 683
 684        def _parse_oldstyle_limit(
 685            self,
 686        ) -> t.Tuple[t.Optional[exp.Expression], t.Optional[exp.Expression]]:
 687            limit = None
 688            offset = None
 689            if self._match_text_seq("LIMIT"):
 690                parts = self._parse_csv(self._parse_number)
 691                if len(parts) == 1:
 692                    limit = parts[0]
 693                elif len(parts) == 2:
 694                    limit = parts[1]
 695                    offset = parts[0]
 696
 697            return offset, limit
 698
 699        def _parse_set_item_charset(self, kind: str) -> exp.Expression:
 700            this = self._parse_string() or self._parse_unquoted_field()
 701            return self.expression(exp.SetItem, this=this, kind=kind)
 702
 703        def _parse_set_item_names(self) -> exp.Expression:
 704            charset = self._parse_string() or self._parse_unquoted_field()
 705            if self._match_text_seq("COLLATE"):
 706                collate = self._parse_string() or self._parse_unquoted_field()
 707            else:
 708                collate = None
 709
 710            return self.expression(exp.SetItem, this=charset, collate=collate, kind="NAMES")
 711
 712        def _parse_type(
 713            self, parse_interval: bool = True, fallback_to_identifier: bool = False
 714        ) -> t.Optional[exp.Expression]:
 715            # mysql binary is special and can work anywhere, even in order by operations
 716            # it operates like a no paren func
 717            if self._match(TokenType.BINARY, advance=False):
 718                data_type = self._parse_types(check_func=True, allow_identifiers=False)
 719
 720                if isinstance(data_type, exp.DataType):
 721                    return self.expression(exp.Cast, this=self._parse_column(), to=data_type)
 722
 723            return super()._parse_type(
 724                parse_interval=parse_interval, fallback_to_identifier=fallback_to_identifier
 725            )
 726
 727        def _parse_alter_table_alter_index(self) -> exp.AlterIndex:
 728            index = self._parse_field(any_token=True)
 729
 730            if self._match_text_seq("VISIBLE"):
 731                visible = True
 732            elif self._match_text_seq("INVISIBLE"):
 733                visible = False
 734            else:
 735                visible = None
 736
 737            return self.expression(exp.AlterIndex, this=index, visible=visible)
 738
 739        def _parse_partition_property(
 740            self,
 741        ) -> t.Optional[exp.Expression] | t.List[exp.Expression]:
 742            partition_cls: t.Optional[t.Type[exp.Expression]] = None
 743            value_parser = None
 744
 745            if self._match_text_seq("RANGE"):
 746                partition_cls = exp.PartitionByRangeProperty
 747                value_parser = self._parse_partition_range_value
 748            elif self._match_text_seq("LIST"):
 749                partition_cls = exp.PartitionByListProperty
 750                value_parser = self._parse_partition_list_value
 751
 752            if not partition_cls or not value_parser:
 753                return None
 754
 755            partition_expressions = self._parse_wrapped_csv(self._parse_assignment)
 756
 757            # For Doris and Starrocks
 758            if not self._match_text_seq("(", "PARTITION", advance=False):
 759                return partition_expressions
 760
 761            create_expressions = self._parse_wrapped_csv(value_parser)
 762
 763            return self.expression(
 764                partition_cls,
 765                partition_expressions=partition_expressions,
 766                create_expressions=create_expressions,
 767            )
 768
 769        def _parse_partition_range_value(self) -> t.Optional[exp.Expression]:
 770            self._match_text_seq("PARTITION")
 771            name = self._parse_id_var()
 772
 773            if not self._match_text_seq("VALUES", "LESS", "THAN"):
 774                return name
 775
 776            values = self._parse_wrapped_csv(self._parse_expression)
 777
 778            if (
 779                len(values) == 1
 780                and isinstance(values[0], exp.Column)
 781                and values[0].name.upper() == "MAXVALUE"
 782            ):
 783                values = [exp.var("MAXVALUE")]
 784
 785            part_range = self.expression(exp.PartitionRange, this=name, expressions=values)
 786            return self.expression(exp.Partition, expressions=[part_range])
 787
 788        def _parse_partition_list_value(self) -> exp.Partition:
 789            self._match_text_seq("PARTITION")
 790            name = self._parse_id_var()
 791            self._match_text_seq("VALUES", "IN")
 792            values = self._parse_wrapped_csv(self._parse_expression)
 793            part_list = self.expression(exp.PartitionList, this=name, expressions=values)
 794            return self.expression(exp.Partition, expressions=[part_list])
 795
 796        def _parse_primary_key(
 797            self,
 798            wrapped_optional: bool = False,
 799            in_props: bool = False,
 800            named_primary_key: bool = False,
 801        ) -> exp.PrimaryKeyColumnConstraint | exp.PrimaryKey:
 802            return super()._parse_primary_key(
 803                wrapped_optional=wrapped_optional, in_props=in_props, named_primary_key=True
 804            )
 805
 806    class Generator(generator.Generator):
 807        INTERVAL_ALLOWS_PLURAL_FORM = False
 808        LOCKING_READS_SUPPORTED = True
 809        NULL_ORDERING_SUPPORTED: t.Optional[bool] = None
 810        JOIN_HINTS = False
 811        TABLE_HINTS = True
 812        DUPLICATE_KEY_UPDATE_WITH_SET = False
 813        QUERY_HINT_SEP = " "
 814        VALUES_AS_TABLE = False
 815        NVL2_SUPPORTED = False
 816        LAST_DAY_SUPPORTS_DATE_PART = False
 817        JSON_TYPE_REQUIRED_FOR_EXTRACTION = True
 818        JSON_PATH_BRACKETED_KEY_SUPPORTED = False
 819        JSON_KEY_VALUE_PAIR_SEP = ","
 820        SUPPORTS_TO_NUMBER = False
 821        PARSE_JSON_NAME: t.Optional[str] = None
 822        PAD_FILL_PATTERN_IS_REQUIRED = True
 823        WRAP_DERIVED_VALUES = False
 824        VARCHAR_REQUIRES_SIZE = True
 825        SUPPORTS_MEDIAN = False
 826        UPDATE_STATEMENT_SUPPORTS_FROM = False
 827
 828        TRANSFORMS = {
 829            **generator.Generator.TRANSFORMS,
 830            exp.ArrayAgg: rename_func("GROUP_CONCAT"),
 831            exp.BitwiseAndAgg: rename_func("BIT_AND"),
 832            exp.BitwiseOrAgg: rename_func("BIT_OR"),
 833            exp.BitwiseXorAgg: rename_func("BIT_XOR"),
 834            exp.BitwiseCount: rename_func("BIT_COUNT"),
 835            exp.Chr: lambda self, e: self.chr_sql(e, "CHAR"),
 836            exp.CurrentDate: no_paren_current_date_sql,
 837            exp.CurrentVersion: rename_func("VERSION"),
 838            exp.DateDiff: _remove_ts_or_ds_to_date(
 839                lambda self, e: self.func("DATEDIFF", e.this, e.expression), ("this", "expression")
 840            ),
 841            exp.DateAdd: _remove_ts_or_ds_to_date(date_add_sql("ADD")),
 842            exp.DateStrToDate: datestrtodate_sql,
 843            exp.DateSub: _remove_ts_or_ds_to_date(date_add_sql("SUB")),
 844            exp.DateTrunc: _date_trunc_sql,
 845            exp.Day: _remove_ts_or_ds_to_date(),
 846            exp.DayOfMonth: _remove_ts_or_ds_to_date(rename_func("DAYOFMONTH")),
 847            exp.DayOfWeek: _remove_ts_or_ds_to_date(rename_func("DAYOFWEEK")),
 848            exp.DayOfYear: _remove_ts_or_ds_to_date(rename_func("DAYOFYEAR")),
 849            exp.GroupConcat: lambda self,
 850            e: f"""GROUP_CONCAT({self.sql(e, "this")} SEPARATOR {self.sql(e, "separator") or "','"})""",
 851            exp.ILike: no_ilike_sql,
 852            exp.JSONExtractScalar: arrow_json_extract_sql,
 853            exp.Length: length_or_char_length_sql,
 854            exp.LogicalOr: rename_func("MAX"),
 855            exp.LogicalAnd: rename_func("MIN"),
 856            exp.Max: max_or_greatest,
 857            exp.Min: min_or_least,
 858            exp.Month: _remove_ts_or_ds_to_date(),
 859            exp.NullSafeEQ: lambda self, e: self.binary(e, "<=>"),
 860            exp.NullSafeNEQ: lambda self, e: f"NOT {self.binary(e, '<=>')}",
 861            exp.NumberToStr: rename_func("FORMAT"),
 862            exp.Pivot: no_pivot_sql,
 863            exp.Select: transforms.preprocess(
 864                [
 865                    transforms.eliminate_distinct_on,
 866                    transforms.eliminate_semi_and_anti_joins,
 867                    transforms.eliminate_qualify,
 868                    transforms.eliminate_full_outer_join,
 869                    transforms.unnest_generate_date_array_using_recursive_cte,
 870                ]
 871            ),
 872            exp.StrPosition: lambda self, e: strposition_sql(
 873                self, e, func_name="LOCATE", supports_position=True
 874            ),
 875            exp.StrToDate: _str_to_date_sql,
 876            exp.StrToTime: _str_to_date_sql,
 877            exp.Stuff: rename_func("INSERT"),
 878            exp.SessionUser: lambda *_: "SESSION_USER()",
 879            exp.TableSample: no_tablesample_sql,
 880            exp.TimeFromParts: rename_func("MAKETIME"),
 881            exp.TimestampAdd: date_add_interval_sql("DATE", "ADD"),
 882            exp.TimestampDiff: lambda self, e: self.func(
 883                "TIMESTAMPDIFF", unit_to_var(e), e.expression, e.this
 884            ),
 885            exp.TimestampSub: date_add_interval_sql("DATE", "SUB"),
 886            exp.TimeStrToUnix: rename_func("UNIX_TIMESTAMP"),
 887            exp.TimeStrToTime: lambda self, e: timestrtotime_sql(
 888                self,
 889                e,
 890                include_precision=not e.args.get("zone"),
 891            ),
 892            exp.TimeToStr: _remove_ts_or_ds_to_date(
 893                lambda self, e: self.func("DATE_FORMAT", e.this, self.format_time(e))
 894            ),
 895            exp.Trim: trim_sql,
 896            exp.Trunc: rename_func("TRUNCATE"),
 897            exp.TryCast: no_trycast_sql,
 898            exp.TsOrDsAdd: date_add_sql("ADD"),
 899            exp.TsOrDsDiff: lambda self, e: self.func("DATEDIFF", e.this, e.expression),
 900            exp.TsOrDsToDate: _ts_or_ds_to_date_sql,
 901            exp.Unicode: lambda self, e: f"ORD(CONVERT({self.sql(e.this)} USING utf32))",
 902            exp.UnixToTime: _unix_to_time_sql,
 903            exp.Week: _remove_ts_or_ds_to_date(),
 904            exp.WeekOfYear: _remove_ts_or_ds_to_date(rename_func("WEEKOFYEAR")),
 905            exp.Year: _remove_ts_or_ds_to_date(),
 906            exp.UtcTimestamp: rename_func("UTC_TIMESTAMP"),
 907            exp.UtcTime: rename_func("UTC_TIME"),
 908        }
 909
 910        UNSIGNED_TYPE_MAPPING = {
 911            exp.DataType.Type.UBIGINT: "BIGINT",
 912            exp.DataType.Type.UINT: "INT",
 913            exp.DataType.Type.UMEDIUMINT: "MEDIUMINT",
 914            exp.DataType.Type.USMALLINT: "SMALLINT",
 915            exp.DataType.Type.UTINYINT: "TINYINT",
 916            exp.DataType.Type.UDECIMAL: "DECIMAL",
 917            exp.DataType.Type.UDOUBLE: "DOUBLE",
 918        }
 919
 920        TIMESTAMP_TYPE_MAPPING = {
 921            exp.DataType.Type.DATETIME2: "DATETIME",
 922            exp.DataType.Type.SMALLDATETIME: "DATETIME",
 923            exp.DataType.Type.TIMESTAMP: "DATETIME",
 924            exp.DataType.Type.TIMESTAMPNTZ: "DATETIME",
 925            exp.DataType.Type.TIMESTAMPTZ: "TIMESTAMP",
 926            exp.DataType.Type.TIMESTAMPLTZ: "TIMESTAMP",
 927        }
 928
 929        TYPE_MAPPING = {
 930            **generator.Generator.TYPE_MAPPING,
 931            **UNSIGNED_TYPE_MAPPING,
 932            **TIMESTAMP_TYPE_MAPPING,
 933        }
 934
 935        TYPE_MAPPING.pop(exp.DataType.Type.MEDIUMTEXT)
 936        TYPE_MAPPING.pop(exp.DataType.Type.LONGTEXT)
 937        TYPE_MAPPING.pop(exp.DataType.Type.TINYTEXT)
 938        TYPE_MAPPING.pop(exp.DataType.Type.BLOB)
 939        TYPE_MAPPING.pop(exp.DataType.Type.MEDIUMBLOB)
 940        TYPE_MAPPING.pop(exp.DataType.Type.LONGBLOB)
 941        TYPE_MAPPING.pop(exp.DataType.Type.TINYBLOB)
 942
 943        PROPERTIES_LOCATION = {
 944            **generator.Generator.PROPERTIES_LOCATION,
 945            exp.TransientProperty: exp.Properties.Location.UNSUPPORTED,
 946            exp.VolatileProperty: exp.Properties.Location.UNSUPPORTED,
 947            exp.PartitionedByProperty: exp.Properties.Location.UNSUPPORTED,
 948            exp.PartitionByRangeProperty: exp.Properties.Location.POST_SCHEMA,
 949            exp.PartitionByListProperty: exp.Properties.Location.POST_SCHEMA,
 950        }
 951
 952        LIMIT_FETCH = "LIMIT"
 953
 954        LIMIT_ONLY_LITERALS = True
 955
 956        CHAR_CAST_MAPPING = dict.fromkeys(
 957            (
 958                exp.DataType.Type.LONGTEXT,
 959                exp.DataType.Type.LONGBLOB,
 960                exp.DataType.Type.MEDIUMBLOB,
 961                exp.DataType.Type.MEDIUMTEXT,
 962                exp.DataType.Type.TEXT,
 963                exp.DataType.Type.TINYBLOB,
 964                exp.DataType.Type.TINYTEXT,
 965                exp.DataType.Type.VARCHAR,
 966            ),
 967            "CHAR",
 968        )
 969        SIGNED_CAST_MAPPING = dict.fromkeys(
 970            (
 971                exp.DataType.Type.BIGINT,
 972                exp.DataType.Type.BOOLEAN,
 973                exp.DataType.Type.INT,
 974                exp.DataType.Type.SMALLINT,
 975                exp.DataType.Type.TINYINT,
 976                exp.DataType.Type.MEDIUMINT,
 977            ),
 978            "SIGNED",
 979        )
 980
 981        # MySQL doesn't support many datatypes in cast.
 982        # https://dev.mysql.com/doc/refman/8.0/en/cast-functions.html#function_cast
 983        CAST_MAPPING = {
 984            **CHAR_CAST_MAPPING,
 985            **SIGNED_CAST_MAPPING,
 986            exp.DataType.Type.UBIGINT: "UNSIGNED",
 987        }
 988
 989        TIMESTAMP_FUNC_TYPES = {
 990            exp.DataType.Type.TIMESTAMPTZ,
 991            exp.DataType.Type.TIMESTAMPLTZ,
 992        }
 993
 994        # https://dev.mysql.com/doc/refman/8.0/en/keywords.html
 995        RESERVED_KEYWORDS = {
 996            "accessible",
 997            "add",
 998            "all",
 999            "alter",
1000            "analyze",
1001            "and",
1002            "as",
1003            "asc",
1004            "asensitive",
1005            "before",
1006            "between",
1007            "bigint",
1008            "binary",
1009            "blob",
1010            "both",
1011            "by",
1012            "call",
1013            "cascade",
1014            "case",
1015            "change",
1016            "char",
1017            "character",
1018            "check",
1019            "collate",
1020            "column",
1021            "condition",
1022            "constraint",
1023            "continue",
1024            "convert",
1025            "create",
1026            "cross",
1027            "cube",
1028            "cume_dist",
1029            "current_date",
1030            "current_time",
1031            "current_timestamp",
1032            "current_user",
1033            "cursor",
1034            "database",
1035            "databases",
1036            "day_hour",
1037            "day_microsecond",
1038            "day_minute",
1039            "day_second",
1040            "dec",
1041            "decimal",
1042            "declare",
1043            "default",
1044            "delayed",
1045            "delete",
1046            "dense_rank",
1047            "desc",
1048            "describe",
1049            "deterministic",
1050            "distinct",
1051            "distinctrow",
1052            "div",
1053            "double",
1054            "drop",
1055            "dual",
1056            "each",
1057            "else",
1058            "elseif",
1059            "empty",
1060            "enclosed",
1061            "escaped",
1062            "except",
1063            "exists",
1064            "exit",
1065            "explain",
1066            "false",
1067            "fetch",
1068            "first_value",
1069            "float",
1070            "float4",
1071            "float8",
1072            "for",
1073            "force",
1074            "foreign",
1075            "from",
1076            "fulltext",
1077            "function",
1078            "generated",
1079            "get",
1080            "grant",
1081            "group",
1082            "grouping",
1083            "groups",
1084            "having",
1085            "high_priority",
1086            "hour_microsecond",
1087            "hour_minute",
1088            "hour_second",
1089            "if",
1090            "ignore",
1091            "in",
1092            "index",
1093            "infile",
1094            "inner",
1095            "inout",
1096            "insensitive",
1097            "insert",
1098            "int",
1099            "int1",
1100            "int2",
1101            "int3",
1102            "int4",
1103            "int8",
1104            "integer",
1105            "intersect",
1106            "interval",
1107            "into",
1108            "io_after_gtids",
1109            "io_before_gtids",
1110            "is",
1111            "iterate",
1112            "join",
1113            "json_table",
1114            "key",
1115            "keys",
1116            "kill",
1117            "lag",
1118            "last_value",
1119            "lateral",
1120            "lead",
1121            "leading",
1122            "leave",
1123            "left",
1124            "like",
1125            "limit",
1126            "linear",
1127            "lines",
1128            "load",
1129            "localtime",
1130            "localtimestamp",
1131            "lock",
1132            "long",
1133            "longblob",
1134            "longtext",
1135            "loop",
1136            "low_priority",
1137            "master_bind",
1138            "master_ssl_verify_server_cert",
1139            "match",
1140            "maxvalue",
1141            "mediumblob",
1142            "mediumint",
1143            "mediumtext",
1144            "middleint",
1145            "minute_microsecond",
1146            "minute_second",
1147            "mod",
1148            "modifies",
1149            "natural",
1150            "not",
1151            "no_write_to_binlog",
1152            "nth_value",
1153            "ntile",
1154            "null",
1155            "numeric",
1156            "of",
1157            "on",
1158            "optimize",
1159            "optimizer_costs",
1160            "option",
1161            "optionally",
1162            "or",
1163            "order",
1164            "out",
1165            "outer",
1166            "outfile",
1167            "over",
1168            "partition",
1169            "percent_rank",
1170            "precision",
1171            "primary",
1172            "procedure",
1173            "purge",
1174            "range",
1175            "rank",
1176            "read",
1177            "reads",
1178            "read_write",
1179            "real",
1180            "recursive",
1181            "references",
1182            "regexp",
1183            "release",
1184            "rename",
1185            "repeat",
1186            "replace",
1187            "require",
1188            "resignal",
1189            "restrict",
1190            "return",
1191            "revoke",
1192            "right",
1193            "rlike",
1194            "row",
1195            "rows",
1196            "row_number",
1197            "schema",
1198            "schemas",
1199            "second_microsecond",
1200            "select",
1201            "sensitive",
1202            "separator",
1203            "set",
1204            "show",
1205            "signal",
1206            "smallint",
1207            "spatial",
1208            "specific",
1209            "sql",
1210            "sqlexception",
1211            "sqlstate",
1212            "sqlwarning",
1213            "sql_big_result",
1214            "sql_calc_found_rows",
1215            "sql_small_result",
1216            "ssl",
1217            "starting",
1218            "stored",
1219            "straight_join",
1220            "system",
1221            "table",
1222            "terminated",
1223            "then",
1224            "tinyblob",
1225            "tinyint",
1226            "tinytext",
1227            "to",
1228            "trailing",
1229            "trigger",
1230            "true",
1231            "undo",
1232            "union",
1233            "unique",
1234            "unlock",
1235            "unsigned",
1236            "update",
1237            "usage",
1238            "use",
1239            "using",
1240            "utc_date",
1241            "utc_time",
1242            "utc_timestamp",
1243            "values",
1244            "varbinary",
1245            "varchar",
1246            "varcharacter",
1247            "varying",
1248            "virtual",
1249            "when",
1250            "where",
1251            "while",
1252            "window",
1253            "with",
1254            "write",
1255            "xor",
1256            "year_month",
1257            "zerofill",
1258        }
1259
1260        def computedcolumnconstraint_sql(self, expression: exp.ComputedColumnConstraint) -> str:
1261            persisted = "STORED" if expression.args.get("persisted") else "VIRTUAL"
1262            return f"GENERATED ALWAYS AS ({self.sql(expression.this.unnest())}) {persisted}"
1263
1264        def array_sql(self, expression: exp.Array) -> str:
1265            self.unsupported("Arrays are not supported by MySQL")
1266            return self.function_fallback_sql(expression)
1267
1268        def arraycontainsall_sql(self, expression: exp.ArrayContainsAll) -> str:
1269            self.unsupported("Array operations are not supported by MySQL")
1270            return self.function_fallback_sql(expression)
1271
1272        def dpipe_sql(self, expression: exp.DPipe) -> str:
1273            return self.func("CONCAT", *expression.flatten())
1274
1275        def extract_sql(self, expression: exp.Extract) -> str:
1276            unit = expression.name
1277            if unit and unit.lower() == "epoch":
1278                return self.func("UNIX_TIMESTAMP", expression.expression)
1279
1280            return super().extract_sql(expression)
1281
1282        def datatype_sql(self, expression: exp.DataType) -> str:
1283            if (
1284                self.VARCHAR_REQUIRES_SIZE
1285                and expression.is_type(exp.DataType.Type.VARCHAR)
1286                and not expression.expressions
1287            ):
1288                # `VARCHAR` must always have a size - if it doesn't, we always generate `TEXT`
1289                return "TEXT"
1290
1291            # https://dev.mysql.com/doc/refman/8.0/en/numeric-type-syntax.html
1292            result = super().datatype_sql(expression)
1293            if expression.this in self.UNSIGNED_TYPE_MAPPING:
1294                result = f"{result} UNSIGNED"
1295
1296            return result
1297
1298        def jsonarraycontains_sql(self, expression: exp.JSONArrayContains) -> str:
1299            return f"{self.sql(expression, 'this')} MEMBER OF({self.sql(expression, 'expression')})"
1300
1301        def cast_sql(self, expression: exp.Cast, safe_prefix: t.Optional[str] = None) -> str:
1302            if expression.to.this in self.TIMESTAMP_FUNC_TYPES:
1303                return self.func("TIMESTAMP", expression.this)
1304
1305            to = self.CAST_MAPPING.get(expression.to.this)
1306
1307            if to:
1308                expression.to.set("this", to)
1309            return super().cast_sql(expression)
1310
1311        def show_sql(self, expression: exp.Show) -> str:
1312            this = f" {expression.name}"
1313            full = " FULL" if expression.args.get("full") else ""
1314            global_ = " GLOBAL" if expression.args.get("global_") else ""
1315
1316            target = self.sql(expression, "target")
1317            target = f" {target}" if target else ""
1318            if expression.name in ("COLUMNS", "INDEX"):
1319                target = f" FROM{target}"
1320            elif expression.name == "GRANTS":
1321                target = f" FOR{target}"
1322            elif expression.name in ("LINKS", "PARTITIONS"):
1323                target = f" ON{target}" if target else ""
1324            elif expression.name == "PROJECTIONS":
1325                target = f" ON TABLE{target}" if target else ""
1326
1327            db = self._prefixed_sql("FROM", expression, "db")
1328
1329            like = self._prefixed_sql("LIKE", expression, "like")
1330            where = self.sql(expression, "where")
1331
1332            types = self.expressions(expression, key="types")
1333            types = f" {types}" if types else types
1334            query = self._prefixed_sql("FOR QUERY", expression, "query")
1335
1336            if expression.name == "PROFILE":
1337                offset = self._prefixed_sql("OFFSET", expression, "offset")
1338                limit = self._prefixed_sql("LIMIT", expression, "limit")
1339            else:
1340                offset = ""
1341                limit = self._oldstyle_limit_sql(expression)
1342
1343            log = self._prefixed_sql("IN", expression, "log")
1344            position = self._prefixed_sql("FROM", expression, "position")
1345
1346            channel = self._prefixed_sql("FOR CHANNEL", expression, "channel")
1347
1348            if expression.name == "ENGINE":
1349                mutex_or_status = " MUTEX" if expression.args.get("mutex") else " STATUS"
1350            else:
1351                mutex_or_status = ""
1352
1353            for_table = self._prefixed_sql("FOR TABLE", expression, "for_table")
1354            for_group = self._prefixed_sql("FOR GROUP", expression, "for_group")
1355            for_user = self._prefixed_sql("FOR USER", expression, "for_user")
1356            for_role = self._prefixed_sql("FOR ROLE", expression, "for_role")
1357            into_outfile = self._prefixed_sql("INTO OUTFILE", expression, "into_outfile")
1358            json = " JSON" if expression.args.get("json") else ""
1359
1360            return f"SHOW{full}{global_}{this}{json}{target}{for_table}{types}{db}{query}{log}{position}{channel}{mutex_or_status}{like}{where}{offset}{limit}{for_group}{for_user}{for_role}{into_outfile}"
1361
1362        def alterrename_sql(self, expression: exp.AlterRename, include_to: bool = True) -> str:
1363            """To avoid TO keyword in ALTER ... RENAME statements.
1364            It's moved from Doris, because it's the same for all MySQL, Doris, and StarRocks.
1365            """
1366            return super().alterrename_sql(expression, include_to=False)
1367
1368        def altercolumn_sql(self, expression: exp.AlterColumn) -> str:
1369            dtype = self.sql(expression, "dtype")
1370            if not dtype:
1371                return super().altercolumn_sql(expression)
1372
1373            this = self.sql(expression, "this")
1374            return f"MODIFY COLUMN {this} {dtype}"
1375
1376        def _prefixed_sql(self, prefix: str, expression: exp.Expression, arg: str) -> str:
1377            sql = self.sql(expression, arg)
1378            return f" {prefix} {sql}" if sql else ""
1379
1380        def _oldstyle_limit_sql(self, expression: exp.Show) -> str:
1381            limit = self.sql(expression, "limit")
1382            offset = self.sql(expression, "offset")
1383            if limit:
1384                limit_offset = f"{offset}, {limit}" if offset else limit
1385                return f" LIMIT {limit_offset}"
1386            return ""
1387
1388        def timestamptrunc_sql(self, expression: exp.TimestampTrunc) -> str:
1389            unit = expression.args.get("unit")
1390
1391            # Pick an old-enough date to avoid negative timestamp diffs
1392            start_ts = "'0000-01-01 00:00:00'"
1393
1394            # Source: https://stackoverflow.com/a/32955740
1395            timestamp_diff = build_date_delta(exp.TimestampDiff)([unit, start_ts, expression.this])
1396            interval = exp.Interval(this=timestamp_diff, unit=unit)
1397            dateadd = build_date_delta_with_interval(exp.DateAdd)([start_ts, interval])
1398
1399            return self.sql(dateadd)
1400
1401        def converttimezone_sql(self, expression: exp.ConvertTimezone) -> str:
1402            from_tz = expression.args.get("source_tz")
1403            to_tz = expression.args.get("target_tz")
1404            dt = expression.args.get("timestamp")
1405
1406            return self.func("CONVERT_TZ", dt, from_tz, to_tz)
1407
1408        def attimezone_sql(self, expression: exp.AtTimeZone) -> str:
1409            self.unsupported("AT TIME ZONE is not supported by MySQL")
1410            return self.sql(expression.this)
1411
1412        def isascii_sql(self, expression: exp.IsAscii) -> str:
1413            return f"REGEXP_LIKE({self.sql(expression.this)}, '^[[:ascii:]]*$')"
1414
1415        def ignorenulls_sql(self, expression: exp.IgnoreNulls) -> str:
1416            # https://dev.mysql.com/doc/refman/8.4/en/window-function-descriptions.html
1417            self.unsupported("MySQL does not support IGNORE NULLS.")
1418            return self.sql(expression.this)
1419
1420        @unsupported_args("this")
1421        def currentschema_sql(self, expression: exp.CurrentSchema) -> str:
1422            return self.func("SCHEMA")
1423
1424        def partition_sql(self, expression: exp.Partition) -> str:
1425            parent = expression.parent
1426            if isinstance(parent, (exp.PartitionByRangeProperty, exp.PartitionByListProperty)):
1427                return self.expressions(expression, flat=True)
1428            return super().partition_sql(expression)
1429
1430        def _partition_by_sql(
1431            self, expression: exp.PartitionByRangeProperty | exp.PartitionByListProperty, kind: str
1432        ) -> str:
1433            partitions = self.expressions(expression, key="partition_expressions", flat=True)
1434            create = self.expressions(expression, key="create_expressions", flat=True)
1435            return f"PARTITION BY {kind} ({partitions}) ({create})"
1436
1437        def partitionbyrangeproperty_sql(self, expression: exp.PartitionByRangeProperty) -> str:
1438            return self._partition_by_sql(expression, "RANGE")
1439
1440        def partitionbylistproperty_sql(self, expression: exp.PartitionByListProperty) -> str:
1441            return self._partition_by_sql(expression, "LIST")
1442
1443        def partitionlist_sql(self, expression: exp.PartitionList) -> str:
1444            name = self.sql(expression, "this")
1445            values = self.expressions(expression, flat=True)
1446            return f"PARTITION {name} VALUES IN ({values})"
1447
1448        def partitionrange_sql(self, expression: exp.PartitionRange) -> str:
1449            name = self.sql(expression, "this")
1450            values = self.expressions(expression, flat=True)
1451            return f"PARTITION {name} VALUES LESS THAN ({values})"
PROMOTE_TO_INFERRED_DATETIME_TYPE = True

This flag is used in the optimizer's canonicalize rule and determines whether x will be promoted to the literal's type in x::DATE < '2020-01-01 12:05:03' (i.e., DATETIME). When false, the literal is cast to x's type to match it instead.

IDENTIFIERS_CAN_START_WITH_DIGIT = True

Whether an unquoted identifier can start with a digit.

NORMALIZATION_STRATEGY = <NormalizationStrategy.CASE_SENSITIVE: 'CASE_SENSITIVE'>

Specifies the strategy according to which identifiers should be normalized.

TIME_FORMAT = "'%Y-%m-%d %T'"
DPIPE_IS_STRING_CONCAT = False

Whether the DPIPE token (||) is a string concatenation operator.

SUPPORTS_USER_DEFINED_TYPES = False

Whether user-defined data types are supported.

SUPPORTS_SEMI_ANTI_JOIN = False

Whether SEMI or ANTI joins are supported.

SAFE_DIVISION = True

Whether division by zero throws an error (False) or returns NULL (True).

SAFE_TO_ELIMINATE_DOUBLE_NEGATION = False
LEAST_GREATEST_IGNORES_NULLS = False

Whether LEAST/GREATEST functions ignore NULL values, e.g:

  • BigQuery, Snowflake, MySQL, Presto/Trino: LEAST(1, NULL, 2) -> NULL
  • Spark, Postgres, DuckDB, TSQL: LEAST(1, NULL, 2) -> 1
EXPRESSION_METADATA = {<class 'sqlglot.expressions.Add'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.Adjacent'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.And'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.ArrayContains'>: {'returns': <Type.BOOLEAN: 'BOOLEAN'>}, <class 'sqlglot.expressions.ArrayContainsAll'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.ArrayOverlaps'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.Binary'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.BitwiseAnd'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.BitwiseLeftShift'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.BitwiseOr'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.BitwiseRightShift'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.BitwiseXor'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.Collate'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.Connector'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.Corr'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.DPipe'>: {'returns': <Type.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.Distance'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.Div'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.Dot'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.EQ'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.Escape'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.ExtendsLeft'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.ExtendsRight'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.GT'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.GTE'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.Glob'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.ILike'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.IntDiv'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.Is'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.JSONArrayContains'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.JSONBContains'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.JSONBContainsAllTopKeys'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.JSONBContainsAnyTopKeys'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.JSONBDeleteAtPath'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.JSONBExtract'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.JSONBExtractScalar'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.JSONExtract'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.JSONExtractScalar'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.Kwarg'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.LT'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.LTE'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.Like'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.Match'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.Mod'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.Mul'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.NEQ'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.NullSafeEQ'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.NullSafeNEQ'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.Operator'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.Or'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.Overlaps'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.Pow'>: {'returns': <Type.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.PropertyEQ'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.RegexpFullMatch'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.RegexpILike'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.RegexpLike'>: {'returns': <Type.BOOLEAN: 'BOOLEAN'>}, <class 'sqlglot.expressions.SimilarTo'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.Sub'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.Xor'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.Alias'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.BitwiseNot'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.Neg'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.Not'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.Paren'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.PivotAlias'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.Unary'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.Int64'>: {'returns': <Type.BIGINT: 'BIGINT'>}, <class 'sqlglot.expressions.UnixMillis'>: {'returns': <Type.BIGINT: 'BIGINT'>}, <class 'sqlglot.expressions.UnixMicros'>: {'returns': <Type.BIGINT: 'BIGINT'>}, <class 'sqlglot.expressions.ApproxDistinct'>: {'returns': <Type.BIGINT: 'BIGINT'>}, <class 'sqlglot.expressions.UnixSeconds'>: {'returns': <Type.BIGINT: 'BIGINT'>}, <class 'sqlglot.expressions.CountIf'>: {'returns': <Type.BIGINT: 'BIGINT'>}, <class 'sqlglot.expressions.ArraySize'>: {'returns': <Type.BIGINT: 'BIGINT'>}, <class 'sqlglot.expressions.FromBase32'>: {'returns': <Type.BINARY: 'BINARY'>}, <class 'sqlglot.expressions.FromBase64'>: {'returns': <Type.BINARY: 'BINARY'>}, <class 'sqlglot.expressions.Exists'>: {'returns': <Type.BOOLEAN: 'BOOLEAN'>}, <class 'sqlglot.expressions.In'>: {'returns': <Type.BOOLEAN: 'BOOLEAN'>}, <class 'sqlglot.expressions.IsInf'>: {'returns': <Type.BOOLEAN: 'BOOLEAN'>}, <class 'sqlglot.expressions.LogicalAnd'>: {'returns': <Type.BOOLEAN: 'BOOLEAN'>}, <class 'sqlglot.expressions.Contains'>: {'returns': <Type.BOOLEAN: 'BOOLEAN'>}, <class 'sqlglot.expressions.EndsWith'>: {'returns': <Type.BOOLEAN: 'BOOLEAN'>}, <class 'sqlglot.expressions.IsNan'>: {'returns': <Type.BOOLEAN: 'BOOLEAN'>}, <class 'sqlglot.expressions.LogicalOr'>: {'returns': <Type.BOOLEAN: 'BOOLEAN'>}, <class 'sqlglot.expressions.StartsWith'>: {'returns': <Type.BOOLEAN: 'BOOLEAN'>}, <class 'sqlglot.expressions.Boolean'>: {'returns': <Type.BOOLEAN: 'BOOLEAN'>}, <class 'sqlglot.expressions.Any'>: {'returns': <Type.BOOLEAN: 'BOOLEAN'>}, <class 'sqlglot.expressions.All'>: {'returns': <Type.BOOLEAN: 'BOOLEAN'>}, <class 'sqlglot.expressions.Between'>: {'returns': <Type.BOOLEAN: 'BOOLEAN'>}, <class 'sqlglot.expressions.LastDay'>: {'returns': <Type.DATE: 'DATE'>}, <class 'sqlglot.expressions.DateStrToDate'>: {'returns': <Type.DATE: 'DATE'>}, <class 'sqlglot.expressions.DiToDate'>: {'returns': <Type.DATE: 'DATE'>}, <class 'sqlglot.expressions.TimeStrToDate'>: {'returns': <Type.DATE: 'DATE'>}, <class 'sqlglot.expressions.DateFromParts'>: {'returns': <Type.DATE: 'DATE'>}, <class 'sqlglot.expressions.TsOrDsToDate'>: {'returns': <Type.DATE: 'DATE'>}, <class 'sqlglot.expressions.CurrentDate'>: {'returns': <Type.DATE: 'DATE'>}, <class 'sqlglot.expressions.StrToDate'>: {'returns': <Type.DATE: 'DATE'>}, <class 'sqlglot.expressions.Date'>: {'returns': <Type.DATE: 'DATE'>}, <class 'sqlglot.expressions.CurrentDatetime'>: {'returns': <Type.DATETIME: 'DATETIME'>}, <class 'sqlglot.expressions.DatetimeSub'>: {'returns': <Type.DATETIME: 'DATETIME'>}, <class 'sqlglot.expressions.Datetime'>: {'returns': <Type.DATETIME: 'DATETIME'>}, <class 'sqlglot.expressions.DatetimeAdd'>: {'returns': <Type.DATETIME: 'DATETIME'>}, <class 'sqlglot.expressions.StddevPop'>: {'returns': <Type.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.StddevSamp'>: {'returns': <Type.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.Sqrt'>: {'returns': <Type.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.SafeDivide'>: {'returns': <Type.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.Cot'>: {'returns': <Type.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.Sinh'>: {'returns': <Type.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.Atanh'>: {'returns': <Type.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.Cosh'>: {'returns': <Type.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.Quantile'>: {'returns': <Type.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.Skewness'>: {'returns': <Type.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.Asinh'>: {'returns': <Type.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.Tanh'>: {'returns': <Type.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.VariancePop'>: {'returns': <Type.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.Acosh'>: {'returns': <Type.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.Log'>: {'returns': <Type.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.Cos'>: {'returns': <Type.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.Round'>: {'returns': <Type.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.Cbrt'>: {'returns': <Type.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.Stddev'>: {'returns': <Type.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.ToDouble'>: {'returns': <Type.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.Rand'>: {'returns': <Type.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.ApproxQuantile'>: {'returns': <Type.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.Sin'>: {'returns': <Type.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.Atan'>: {'returns': <Type.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.Degrees'>: {'returns': <Type.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.Kurtosis'>: {'returns': <Type.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.Asin'>: {'returns': <Type.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.Tan'>: {'returns': <Type.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.Variance'>: {'returns': <Type.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.Acos'>: {'returns': <Type.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.Exp'>: {'returns': <Type.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.Ln'>: {'returns': <Type.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.Pi'>: {'returns': <Type.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.Radians'>: {'returns': <Type.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.Avg'>: {'returns': <Type.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.Length'>: {'returns': <Type.INT: 'INT'>}, <class 'sqlglot.expressions.DateToDi'>: {'returns': <Type.INT: 'INT'>}, <class 'sqlglot.expressions.DayOfMonth'>: {'returns': <Type.INT: 'INT'>}, <class 'sqlglot.expressions.Quarter'>: {'returns': <Type.INT: 'INT'>}, <class 'sqlglot.expressions.DayOfWeek'>: {'returns': <Type.INT: 'INT'>}, <class 'sqlglot.expressions.TimeDiff'>: {'returns': <Type.INT: 'INT'>}, <class 'sqlglot.expressions.Ceil'>: {'returns': <Type.INT: 'INT'>}, <class 'sqlglot.expressions.Sign'>: {'returns': <Type.INT: 'INT'>}, <class 'sqlglot.expressions.Levenshtein'>: {'returns': <Type.INT: 'INT'>}, <class 'sqlglot.expressions.UnixDate'>: {'returns': <Type.INT: 'INT'>}, <class 'sqlglot.expressions.Unicode'>: {'returns': <Type.INT: 'INT'>}, <class 'sqlglot.expressions.Getbit'>: {'returns': <Type.INT: 'INT'>}, <class 'sqlglot.expressions.StrPosition'>: {'returns': <Type.INT: 'INT'>}, <class 'sqlglot.expressions.TsOrDiToDi'>: {'returns': <Type.INT: 'INT'>}, <class 'sqlglot.expressions.DayOfYear'>: {'returns': <Type.INT: 'INT'>}, <class 'sqlglot.expressions.TimestampDiff'>: {'returns': <Type.INT: 'INT'>}, <class 'sqlglot.expressions.Hour'>: {'returns': <Type.INT: 'INT'>}, <class 'sqlglot.expressions.DatetimeDiff'>: {'returns': <Type.INT: 'INT'>}, <class 'sqlglot.expressions.Ascii'>: {'returns': <Type.INT: 'INT'>}, <class 'sqlglot.expressions.BitLength'>: {'returns': <Type.INT: 'INT'>}, <class 'sqlglot.expressions.JustifyDays'>: {'returns': <Type.INTERVAL: 'INTERVAL'>}, <class 'sqlglot.expressions.MakeInterval'>: {'returns': <Type.INTERVAL: 'INTERVAL'>}, <class 'sqlglot.expressions.Interval'>: {'returns': <Type.INTERVAL: 'INTERVAL'>}, <class 'sqlglot.expressions.JustifyInterval'>: {'returns': <Type.INTERVAL: 'INTERVAL'>}, <class 'sqlglot.expressions.JustifyHours'>: {'returns': <Type.INTERVAL: 'INTERVAL'>}, <class 'sqlglot.expressions.ParseJSON'>: {'returns': <Type.JSON: 'JSON'>}, <class 'sqlglot.expressions.Time'>: {'returns': <Type.TIME: 'TIME'>}, <class 'sqlglot.expressions.TimeAdd'>: {'returns': <Type.TIME: 'TIME'>}, <class 'sqlglot.expressions.Localtime'>: {'returns': <Type.DATETIME: 'DATETIME'>}, <class 'sqlglot.expressions.CurrentTime'>: {'returns': <Type.TIME: 'TIME'>}, <class 'sqlglot.expressions.TimeSub'>: {'returns': <Type.TIME: 'TIME'>}, <class 'sqlglot.expressions.TimestampLtzFromParts'>: {'returns': <Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>}, <class 'sqlglot.expressions.CurrentTimestampLTZ'>: {'returns': <Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>}, <class 'sqlglot.expressions.TimestampTzFromParts'>: {'returns': <Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>}, <class 'sqlglot.expressions.TimeStrToTime'>: {'returns': <Type.TIMESTAMP: 'TIMESTAMP'>}, <class 'sqlglot.expressions.TimestampSub'>: {'returns': <Type.TIMESTAMP: 'TIMESTAMP'>}, <class 'sqlglot.expressions.StrToTime'>: {'returns': <Type.TIMESTAMP: 'TIMESTAMP'>}, <class 'sqlglot.expressions.TimestampAdd'>: {'returns': <Type.TIMESTAMP: 'TIMESTAMP'>}, <class 'sqlglot.expressions.UnixToTime'>: {'returns': <Type.TIMESTAMP: 'TIMESTAMP'>}, <class 'sqlglot.expressions.CurrentTimestamp'>: {'returns': <Type.DATETIME: 'DATETIME'>}, <class 'sqlglot.expressions.YearOfWeekIso'>: {'returns': <Type.TINYINT: 'TINYINT'>}, <class 'sqlglot.expressions.Week'>: {'returns': <Type.INT: 'INT'>}, <class 'sqlglot.expressions.Year'>: {'returns': <Type.TINYINT: 'TINYINT'>}, <class 'sqlglot.expressions.DayOfWeekIso'>: {'returns': <Type.TINYINT: 'TINYINT'>}, <class 'sqlglot.expressions.YearOfWeek'>: {'returns': <Type.TINYINT: 'TINYINT'>}, <class 'sqlglot.expressions.Day'>: {'returns': <Type.TINYINT: 'TINYINT'>}, <class 'sqlglot.expressions.Month'>: {'returns': <Type.INT: 'INT'>}, <class 'sqlglot.expressions.WeekOfYear'>: {'returns': <Type.TINYINT: 'TINYINT'>}, <class 'sqlglot.expressions.Dayname'>: {'returns': <Type.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.ConcatWs'>: {'returns': <Type.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.ToBase64'>: {'returns': <Type.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.ArrayToString'>: {'returns': <Type.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.SessionUser'>: {'returns': <Type.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.Chr'>: {'returns': <Type.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.Substring'>: {'returns': <Type.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.MD5'>: {'returns': <Type.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.TsOrDsToDateStr'>: {'returns': <Type.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.CurrentUser'>: {'returns': <Type.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.Initcap'>: {'returns': <Type.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.Upper'>: {'returns': <Type.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.TimeToTimeStr'>: {'returns': <Type.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.SHA'>: {'returns': <Type.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.ToBase32'>: {'returns': <Type.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.DateToDateStr'>: {'returns': <Type.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.CurrentVersion'>: {'returns': <Type.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.Concat'>: {'returns': <Type.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.Translate'>: {'returns': <Type.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.RawString'>: {'returns': <Type.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.UnixToTimeStr'>: {'returns': <Type.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.Space'>: {'returns': <Type.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.Lower'>: {'returns': <Type.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.Trim'>: {'returns': <Type.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.CurrentCatalog'>: {'returns': <Type.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.String'>: {'returns': <Type.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.CurrentSchema'>: {'returns': <Type.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.GroupConcat'>: {'returns': <Type.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.UnixToStr'>: {'returns': <Type.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.Monthname'>: {'returns': <Type.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.SHA2'>: {'returns': <Type.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.TimeToStr'>: {'returns': <Type.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.ArrayConcatAgg'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.HavingMax'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.Abs'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.Window'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.SortArray'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.Order'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.ArraySlice'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.Filter'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.AnyValue'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.ArrayReverse'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.Limit'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.LastValue'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.Min'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.ArrayConcat'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.Least'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.Coalesce'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.Greatest'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.Max'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.ArrayFirst'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.ArrayLast'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.Anonymous'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.DateAdd'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.DateTrunc'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.DateSub'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.TryCast'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.Cast'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.VarMap'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.Map'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.Array'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.ArrayAgg'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.Bracket'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.Case'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.Count'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.DateDiff'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.DataType'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.Distinct'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.Explode'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.Extract'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.HexString'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.GenerateSeries'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.GenerateDateArray'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.GenerateTimestampArray'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.If'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.Literal'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.Null'>: {'returns': <Type.NULL: 'NULL'>}, <class 'sqlglot.expressions.Nullif'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.Struct'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.Sum'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.Timestamp'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.ToMap'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.Unnest'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.Subquery'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.Atan2'>: {'returns': <Type.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.Elt'>: {'returns': <Type.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.Second'>: {'returns': <Type.INT: 'INT'>}}
TIME_MAPPING: Dict[str, str] = {'%M': '%B', '%c': '%-m', '%e': '%-d', '%h': '%I', '%i': '%M', '%s': '%S', '%u': '%W', '%k': '%-H', '%l': '%-I', '%T': '%H:%M:%S', '%W': '%A'}

Associates this dialect's time formats with their equivalent Python strftime formats.

VALID_INTERVAL_UNITS: Set[str] = {'WOY', 'DECADE', 'YR', 'QUARTERS', 'MON', 'DAYOFWEEK', 'TZH', 'MS', 'MILLENNIUM', 'NANOSECOND', 'MONTHS', 'EPOCH_MICROSECONDS', 'WEEKOFYEAR_ISO', 'C', 'SECOND_MICROSECOND', 'SECONDS', 'WEEKOFYEAR', 'NS', 'EPOCH_MILLISECOND', 'Y', 'WK', 'WY', 'USECOND', 'EPOCH_MICROSECOND', 'MILLISEC', 'MONTH', 'MINUTE_MICROSECOND', 'YEAR', 'EPOCH_NANOSECONDS', 'MILS', 'DOY', 'NANOSEC', 'DOW_ISO', 'CENT', 'DAYS', 'MINS', 'SEC', 'MILLISECS', 'MI', 'Q', 'MICROSECS', 'DAYOFMONTH', 'WEEKOFYEARISO', 'DECADES', 'HOUR_MINUTE', 'S', 'YRS', 'YYYY', 'WEEK', 'MINUTES', 'WEEKDAY', 'EPOCH', 'HOUR_SECOND', 'HOUR', 'YEAR_MONTH', 'YEARS', 'NSEC', 'MSECOND', 'USEC', 'DAYOFWEEK_ISO', 'CENTURIES', 'QTRS', 'DAY_MINUTE', 'MM', 'D', 'MILLISECONDS', 'DAYOFYEAR', 'WEEKISO', 'NANOSECS', 'CENTS', 'WEEKDAY_ISO', 'DAYOFWEEKISO', 'EPOCH_NANOSECOND', 'MICROSECONDS', 'DAY OF YEAR', 'EPOCH_MILLISECONDS', 'USECONDS', 'TIMEZONE_MINUTE', 'YY', 'HR', 'EPOCH_SECONDS', 'MILLENIA', 'W', 'MICROSECOND', 'HOUR_MICROSECOND', 'DECS', 'MINUTE', 'CENTURY', 'MINUTE_SECOND', 'MIN', 'YYY', 'MSECONDS', 'HH', 'DD', 'QTR', 'DAY_HOUR', 'TIMEZONE_HOUR', 'DAY OF WEEK', 'DW', 'QUARTER', 'SECS', 'DAY_MICROSECOND', 'NSECONDS', 'DW_ISO', 'DAY', 'DY', 'SECOND', 'MILLISECON', 'MICROSEC', 'EPOCH_SECOND', 'HRS', 'HOURS', 'MIL', 'DAY_SECOND', 'TZM', 'MSEC', 'H', 'DOW', 'MSECS', 'MILLISECOND', 'US', 'MONS', 'DEC', 'WEEK_ISO', 'NSECOND', 'USECS', 'M'}
SUPPORTS_COLUMN_JOIN_MARKS = False

Whether the old-style outer join (+) syntax is supported.

UNESCAPED_SEQUENCES: Dict[str, str] = {'\\a': '\x07', '\\b': '\x08', '\\f': '\x0c', '\\n': '\n', '\\r': '\r', '\\t': '\t', '\\v': '\x0b', '\\\\': '\\'}

Mapping of an escaped sequence (\n) to its unescaped version ( ).

INITCAP_SUPPORTS_CUSTOM_DELIMITERS = False
tokenizer_class = <class 'MySQL.Tokenizer'>
jsonpath_tokenizer_class = <class 'sqlglot.dialects.dialect.JSONPathTokenizer'>
parser_class = <class 'MySQL.Parser'>
generator_class = <class 'MySQL.Generator'>
TIME_TRIE: Dict = {'%': {'M': {0: True}, 'c': {0: True}, 'e': {0: True}, 'h': {0: True}, 'i': {0: True}, 's': {0: True}, 'u': {0: True}, 'k': {0: True}, 'l': {0: True}, 'T': {0: True}, 'W': {0: True}}}
FORMAT_TRIE: Dict = {'%': {'M': {0: True}, 'c': {0: True}, 'e': {0: True}, 'h': {0: True}, 'i': {0: True}, 's': {0: True}, 'u': {0: True}, 'k': {0: True}, 'l': {0: True}, 'T': {0: True}, 'W': {0: True}}}
INVERSE_TIME_MAPPING: Dict[str, str] = {'%B': '%M', '%-m': '%c', '%-d': '%e', '%I': '%h', '%M': '%i', '%S': '%s', '%W': '%u', '%-H': '%k', '%-I': '%l', '%H:%M:%S': '%T', '%A': '%W'}
INVERSE_TIME_TRIE: Dict = {'%': {'B': {0: True}, '-': {'m': {0: True}, 'd': {0: True}, 'H': {0: True}, 'I': {0: True}}, 'I': {0: True}, 'M': {0: True}, 'S': {0: True}, 'W': {0: True}, 'H': {':': {'%': {'M': {':': {'%': {'S': {0: True}}}}}}}, 'A': {0: True}}}
INVERSE_FORMAT_MAPPING: Dict[str, str] = {}
INVERSE_FORMAT_TRIE: Dict = {}
INVERSE_CREATABLE_KIND_MAPPING: dict[str, str] = {}
ESCAPED_SEQUENCES: Dict[str, str] = {'\x07': '\\a', '\x08': '\\b', '\x0c': '\\f', '\n': '\\n', '\r': '\\r', '\t': '\\t', '\x0b': '\\v', '\\': '\\\\'}
QUOTE_START = "'"
QUOTE_END = "'"
IDENTIFIER_START = '`'
IDENTIFIER_END = '`'
BIT_START: Optional[str] = "b'"
BIT_END: Optional[str] = "'"
HEX_START: Optional[str] = "x'"
HEX_END: Optional[str] = "'"
BYTE_START: Optional[str] = None
BYTE_END: Optional[str] = None
UNICODE_START: Optional[str] = None
UNICODE_END: Optional[str] = None
STRINGS_SUPPORT_ESCAPED_SEQUENCES = True
BYTE_STRINGS_SUPPORT_ESCAPED_SEQUENCES = True
class MySQL.Tokenizer(sqlglot.tokens.Tokenizer):
203    class Tokenizer(tokens.Tokenizer):
204        QUOTES = ["'", '"']
205        COMMENTS = ["--", "#", ("/*", "*/")]
206        IDENTIFIERS = ["`"]
207        STRING_ESCAPES = ["'", '"', "\\"]
208        BIT_STRINGS = [("b'", "'"), ("B'", "'"), ("0b", "")]
209        HEX_STRINGS = [("x'", "'"), ("X'", "'"), ("0x", "")]
210        # https://dev.mysql.com/doc/refman/8.4/en/string-literals.html
211        ESCAPE_FOLLOW_CHARS = ["0", "b", "n", "r", "t", "Z", "%", "_"]
212
213        NESTED_COMMENTS = False
214
215        KEYWORDS = {
216            **tokens.Tokenizer.KEYWORDS,
217            "BLOB": TokenType.BLOB,
218            "CHARSET": TokenType.CHARACTER_SET,
219            "DISTINCTROW": TokenType.DISTINCT,
220            "EXPLAIN": TokenType.DESCRIBE,
221            "FORCE": TokenType.FORCE,
222            "IGNORE": TokenType.IGNORE,
223            "KEY": TokenType.KEY,
224            "LOCK TABLES": TokenType.COMMAND,
225            "LONGBLOB": TokenType.LONGBLOB,
226            "LONGTEXT": TokenType.LONGTEXT,
227            "MEDIUMBLOB": TokenType.MEDIUMBLOB,
228            "MEDIUMINT": TokenType.MEDIUMINT,
229            "MEDIUMTEXT": TokenType.MEDIUMTEXT,
230            "MEMBER OF": TokenType.MEMBER_OF,
231            "MOD": TokenType.MOD,
232            "SEPARATOR": TokenType.SEPARATOR,
233            "SERIAL": TokenType.SERIAL,
234            "SIGNED": TokenType.BIGINT,
235            "SIGNED INTEGER": TokenType.BIGINT,
236            "SOUNDS LIKE": TokenType.SOUNDS_LIKE,
237            "START": TokenType.BEGIN,
238            "TIMESTAMP": TokenType.TIMESTAMPTZ,
239            "TINYBLOB": TokenType.TINYBLOB,
240            "TINYTEXT": TokenType.TINYTEXT,
241            "UNLOCK TABLES": TokenType.COMMAND,
242            "UNSIGNED": TokenType.UBIGINT,
243            "UNSIGNED INTEGER": TokenType.UBIGINT,
244            "YEAR": TokenType.YEAR,
245            "_ARMSCII8": TokenType.INTRODUCER,
246            "_ASCII": TokenType.INTRODUCER,
247            "_BIG5": TokenType.INTRODUCER,
248            "_BINARY": TokenType.INTRODUCER,
249            "_CP1250": TokenType.INTRODUCER,
250            "_CP1251": TokenType.INTRODUCER,
251            "_CP1256": TokenType.INTRODUCER,
252            "_CP1257": TokenType.INTRODUCER,
253            "_CP850": TokenType.INTRODUCER,
254            "_CP852": TokenType.INTRODUCER,
255            "_CP866": TokenType.INTRODUCER,
256            "_CP932": TokenType.INTRODUCER,
257            "_DEC8": TokenType.INTRODUCER,
258            "_EUCJPMS": TokenType.INTRODUCER,
259            "_EUCKR": TokenType.INTRODUCER,
260            "_GB18030": TokenType.INTRODUCER,
261            "_GB2312": TokenType.INTRODUCER,
262            "_GBK": TokenType.INTRODUCER,
263            "_GEOSTD8": TokenType.INTRODUCER,
264            "_GREEK": TokenType.INTRODUCER,
265            "_HEBREW": TokenType.INTRODUCER,
266            "_HP8": TokenType.INTRODUCER,
267            "_KEYBCS2": TokenType.INTRODUCER,
268            "_KOI8R": TokenType.INTRODUCER,
269            "_KOI8U": TokenType.INTRODUCER,
270            "_LATIN1": TokenType.INTRODUCER,
271            "_LATIN2": TokenType.INTRODUCER,
272            "_LATIN5": TokenType.INTRODUCER,
273            "_LATIN7": TokenType.INTRODUCER,
274            "_MACCE": TokenType.INTRODUCER,
275            "_MACROMAN": TokenType.INTRODUCER,
276            "_SJIS": TokenType.INTRODUCER,
277            "_SWE7": TokenType.INTRODUCER,
278            "_TIS620": TokenType.INTRODUCER,
279            "_UCS2": TokenType.INTRODUCER,
280            "_UJIS": TokenType.INTRODUCER,
281            # https://dev.mysql.com/doc/refman/8.0/en/string-literals.html
282            "_UTF8": TokenType.INTRODUCER,
283            "_UTF16": TokenType.INTRODUCER,
284            "_UTF16LE": TokenType.INTRODUCER,
285            "_UTF32": TokenType.INTRODUCER,
286            "_UTF8MB3": TokenType.INTRODUCER,
287            "_UTF8MB4": TokenType.INTRODUCER,
288            "@@": TokenType.SESSION_PARAMETER,
289        }
290
291        COMMANDS = {*tokens.Tokenizer.COMMANDS, TokenType.REPLACE} - {TokenType.SHOW}
QUOTES = ["'", '"']
COMMENTS = ['--', '#', ('/*', '*/')]
IDENTIFIERS = ['`']
STRING_ESCAPES = ["'", '"', '\\']
BIT_STRINGS = [("b'", "'"), ("B'", "'"), ('0b', '')]
HEX_STRINGS = [("x'", "'"), ("X'", "'"), ('0x', '')]
ESCAPE_FOLLOW_CHARS = ['0', 'b', 'n', 'r', 't', 'Z', '%', '_']
NESTED_COMMENTS = False
KEYWORDS = {'{%': <TokenType.BLOCK_START: 70>, '{%+': <TokenType.BLOCK_START: 70>, '{%-': <TokenType.BLOCK_START: 70>, '%}': <TokenType.BLOCK_END: 71>, '+%}': <TokenType.BLOCK_END: 71>, '-%}': <TokenType.BLOCK_END: 71>, '{{+': <TokenType.BLOCK_START: 70>, '{{-': <TokenType.BLOCK_START: 70>, '+}}': <TokenType.BLOCK_END: 71>, '-}}': <TokenType.BLOCK_END: 71>, '/*+': <TokenType.HINT: 288>, '&<': <TokenType.AMP_LT: 60>, '&>': <TokenType.AMP_GT: 61>, '==': <TokenType.EQ: 27>, '::': <TokenType.DCOLON: 13>, '?::': <TokenType.QDCOLON: 360>, '||': <TokenType.DPIPE: 36>, '|>': <TokenType.PIPE_GT: 37>, '>=': <TokenType.GTE: 25>, '<=': <TokenType.LTE: 23>, '<>': <TokenType.NEQ: 28>, '!=': <TokenType.NEQ: 28>, ':=': <TokenType.COLON_EQ: 30>, '<=>': <TokenType.NULLSAFE_EQ: 29>, '->': <TokenType.ARROW: 44>, '->>': <TokenType.DARROW: 45>, '=>': <TokenType.FARROW: 46>, '#>': <TokenType.HASH_ARROW: 48>, '#>>': <TokenType.DHASH_ARROW: 49>, '<->': <TokenType.LR_ARROW: 50>, '&&': <TokenType.DAMP: 59>, '??': <TokenType.DQMARK: 17>, '~~~': <TokenType.GLOB: 282>, '~~': <TokenType.LIKE: 312>, '~~*': <TokenType.ILIKE: 290>, '~*': <TokenType.IRLIKE: 301>, '-|-': <TokenType.ADJACENT: 62>, 'ALL': <TokenType.ALL: 216>, 'AND': <TokenType.AND: 33>, 'ANTI': <TokenType.ANTI: 217>, 'ANY': <TokenType.ANY: 218>, 'ASC': <TokenType.ASC: 221>, 'AS': <TokenType.ALIAS: 214>, 'ASOF': <TokenType.ASOF: 222>, 'AUTOINCREMENT': <TokenType.AUTO_INCREMENT: 224>, 'AUTO_INCREMENT': <TokenType.AUTO_INCREMENT: 224>, 'BEGIN': <TokenType.BEGIN: 225>, 'BETWEEN': <TokenType.BETWEEN: 226>, 'CACHE': <TokenType.CACHE: 228>, 'UNCACHE': <TokenType.UNCACHE: 400>, 'CASE': <TokenType.CASE: 229>, 'CHARACTER SET': <TokenType.CHARACTER_SET: 230>, 'CLUSTER BY': <TokenType.CLUSTER_BY: 231>, 'COLLATE': <TokenType.COLLATE: 232>, 'COLUMN': <TokenType.COLUMN: 78>, 'COMMIT': <TokenType.COMMIT: 235>, 'CONNECT BY': <TokenType.CONNECT_BY: 236>, 'CONSTRAINT': <TokenType.CONSTRAINT: 237>, 'COPY': <TokenType.COPY: 238>, 'CREATE': <TokenType.CREATE: 239>, 'CROSS': <TokenType.CROSS: 240>, 'CUBE': <TokenType.CUBE: 241>, 'CURRENT_DATE': <TokenType.CURRENT_DATE: 242>, 'CURRENT_SCHEMA': <TokenType.CURRENT_SCHEMA: 244>, 'CURRENT_TIME': <TokenType.CURRENT_TIME: 245>, 'CURRENT_TIMESTAMP': <TokenType.CURRENT_TIMESTAMP: 246>, 'CURRENT_USER': <TokenType.CURRENT_USER: 247>, 'CURRENT_CATALOG': <TokenType.CURRENT_CATALOG: 249>, 'DATABASE': <TokenType.DATABASE: 77>, 'DEFAULT': <TokenType.DEFAULT: 251>, 'DELETE': <TokenType.DELETE: 252>, 'DESC': <TokenType.DESC: 253>, 'DESCRIBE': <TokenType.DESCRIBE: 254>, 'DISTINCT': <TokenType.DISTINCT: 257>, 'DISTRIBUTE BY': <TokenType.DISTRIBUTE_BY: 258>, 'DIV': <TokenType.DIV: 259>, 'DROP': <TokenType.DROP: 260>, 'ELSE': <TokenType.ELSE: 261>, 'END': <TokenType.END: 262>, 'ENUM': <TokenType.ENUM: 201>, 'ESCAPE': <TokenType.ESCAPE: 263>, 'EXCEPT': <TokenType.EXCEPT: 264>, 'EXECUTE': <TokenType.EXECUTE: 265>, 'EXISTS': <TokenType.EXISTS: 266>, 'FALSE': <TokenType.FALSE: 267>, 'FETCH': <TokenType.FETCH: 268>, 'FILTER': <TokenType.FILTER: 271>, 'FILE': <TokenType.FILE: 269>, 'FIRST': <TokenType.FIRST: 273>, 'FULL': <TokenType.FULL: 279>, 'FUNCTION': <TokenType.FUNCTION: 280>, 'FOR': <TokenType.FOR: 274>, 'FOREIGN KEY': <TokenType.FOREIGN_KEY: 276>, 'FORMAT': <TokenType.FORMAT: 277>, 'FROM': <TokenType.FROM: 278>, 'GEOGRAPHY': <TokenType.GEOGRAPHY: 168>, 'GEOMETRY': <TokenType.GEOMETRY: 171>, 'GLOB': <TokenType.GLOB: 282>, 'GROUP BY': <TokenType.GROUP_BY: 285>, 'GROUPING SETS': <TokenType.GROUPING_SETS: 286>, 'HAVING': <TokenType.HAVING: 287>, 'ILIKE': <TokenType.ILIKE: 290>, 'IN': <TokenType.IN: 291>, 'INDEX': <TokenType.INDEX: 292>, 'INET': <TokenType.INET: 196>, 'INNER': <TokenType.INNER: 294>, 'INSERT': <TokenType.INSERT: 295>, 'INTERVAL': <TokenType.INTERVAL: 298>, 'INTERSECT': <TokenType.INTERSECT: 297>, 'INTO': <TokenType.INTO: 299>, 'IS': <TokenType.IS: 302>, 'ISNULL': <TokenType.ISNULL: 303>, 'JOIN': <TokenType.JOIN: 304>, 'KEEP': <TokenType.KEEP: 306>, 'KILL': <TokenType.KILL: 308>, 'LATERAL': <TokenType.LATERAL: 310>, 'LEFT': <TokenType.LEFT: 311>, 'LIKE': <TokenType.LIKE: 312>, 'LIMIT': <TokenType.LIMIT: 313>, 'LOAD': <TokenType.LOAD: 315>, 'LOCALTIME': <TokenType.LOCALTIME: 175>, 'LOCALTIMESTAMP': <TokenType.LOCALTIMESTAMP: 176>, 'LOCK': <TokenType.LOCK: 316>, 'MERGE': <TokenType.MERGE: 322>, 'NAMESPACE': <TokenType.NAMESPACE: 426>, 'NATURAL': <TokenType.NATURAL: 325>, 'NEXT': <TokenType.NEXT: 326>, 'NOT': <TokenType.NOT: 26>, 'NOTNULL': <TokenType.NOTNULL: 328>, 'NULL': <TokenType.NULL: 329>, 'OBJECT': <TokenType.OBJECT: 195>, 'OFFSET': <TokenType.OFFSET: 331>, 'ON': <TokenType.ON: 332>, 'OR': <TokenType.OR: 34>, 'XOR': <TokenType.XOR: 63>, 'ORDER BY': <TokenType.ORDER_BY: 335>, 'ORDINALITY': <TokenType.ORDINALITY: 338>, 'OUT': <TokenType.OUT: 339>, 'OUTER': <TokenType.OUTER: 341>, 'OVER': <TokenType.OVER: 342>, 'OVERLAPS': <TokenType.OVERLAPS: 343>, 'OVERWRITE': <TokenType.OVERWRITE: 344>, 'PARTITION': <TokenType.PARTITION: 345>, 'PARTITION BY': <TokenType.PARTITION_BY: 346>, 'PARTITIONED BY': <TokenType.PARTITION_BY: 346>, 'PARTITIONED_BY': <TokenType.PARTITION_BY: 346>, 'PERCENT': <TokenType.PERCENT: 347>, 'PIVOT': <TokenType.PIVOT: 348>, 'PRAGMA': <TokenType.PRAGMA: 351>, 'PRIMARY KEY': <TokenType.PRIMARY_KEY: 353>, 'PROCEDURE': <TokenType.PROCEDURE: 354>, 'OPERATOR': <TokenType.OPERATOR: 334>, 'QUALIFY': <TokenType.QUALIFY: 358>, 'RANGE': <TokenType.RANGE: 361>, 'RECURSIVE': <TokenType.RECURSIVE: 362>, 'REGEXP': <TokenType.RLIKE: 370>, 'RENAME': <TokenType.RENAME: 364>, 'REPLACE': <TokenType.REPLACE: 365>, 'RETURNING': <TokenType.RETURNING: 366>, 'REFERENCES': <TokenType.REFERENCES: 368>, 'RIGHT': <TokenType.RIGHT: 369>, 'RLIKE': <TokenType.RLIKE: 370>, 'ROLLBACK': <TokenType.ROLLBACK: 371>, 'ROLLUP': <TokenType.ROLLUP: 372>, 'ROW': <TokenType.ROW: 373>, 'ROWS': <TokenType.ROWS: 374>, 'SCHEMA': <TokenType.SCHEMA: 80>, 'SELECT': <TokenType.SELECT: 375>, 'SEMI': <TokenType.SEMI: 376>, 'SESSION': <TokenType.SESSION: 56>, 'SESSION_USER': <TokenType.SESSION_USER: 58>, 'SET': <TokenType.SET: 380>, 'SETTINGS': <TokenType.SETTINGS: 381>, 'SHOW': <TokenType.SHOW: 382>, 'SIMILAR TO': <TokenType.SIMILAR_TO: 383>, 'SOME': <TokenType.SOME: 384>, 'SORT BY': <TokenType.SORT_BY: 385>, 'START WITH': <TokenType.START_WITH: 387>, 'STRAIGHT_JOIN': <TokenType.STRAIGHT_JOIN: 389>, 'TABLE': <TokenType.TABLE: 81>, 'TABLESAMPLE': <TokenType.TABLE_SAMPLE: 392>, 'TEMP': <TokenType.TEMPORARY: 394>, 'TEMPORARY': <TokenType.TEMPORARY: 394>, 'THEN': <TokenType.THEN: 396>, 'TRUE': <TokenType.TRUE: 397>, 'TRUNCATE': <TokenType.TRUNCATE: 398>, 'TRIGGER': <TokenType.TRIGGER: 399>, 'UNION': <TokenType.UNION: 401>, 'UNKNOWN': <TokenType.UNKNOWN: 210>, 'UNNEST': <TokenType.UNNEST: 402>, 'UNPIVOT': <TokenType.UNPIVOT: 403>, 'UPDATE': <TokenType.UPDATE: 404>, 'USE': <TokenType.USE: 405>, 'USING': <TokenType.USING: 406>, 'UUID': <TokenType.UUID: 167>, 'VALUES': <TokenType.VALUES: 407>, 'VIEW': <TokenType.VIEW: 409>, 'VOLATILE': <TokenType.VOLATILE: 411>, 'WHEN': <TokenType.WHEN: 412>, 'WHERE': <TokenType.WHERE: 413>, 'WINDOW': <TokenType.WINDOW: 414>, 'WITH': <TokenType.WITH: 415>, 'APPLY': <TokenType.APPLY: 219>, 'ARRAY': <TokenType.ARRAY: 220>, 'BIT': <TokenType.BIT: 93>, 'BOOL': <TokenType.BOOLEAN: 94>, 'BOOLEAN': <TokenType.BOOLEAN: 94>, 'BYTE': <TokenType.TINYINT: 95>, 'MEDIUMINT': <TokenType.MEDIUMINT: 99>, 'INT1': <TokenType.TINYINT: 95>, 'TINYINT': <TokenType.TINYINT: 95>, 'INT16': <TokenType.SMALLINT: 97>, 'SHORT': <TokenType.SMALLINT: 97>, 'SMALLINT': <TokenType.SMALLINT: 97>, 'HUGEINT': <TokenType.INT128: 106>, 'UHUGEINT': <TokenType.UINT128: 107>, 'INT2': <TokenType.SMALLINT: 97>, 'INTEGER': <TokenType.INT: 101>, 'INT': <TokenType.INT: 101>, 'INT4': <TokenType.INT: 101>, 'INT32': <TokenType.INT: 101>, 'INT64': <TokenType.BIGINT: 103>, 'INT128': <TokenType.INT128: 106>, 'INT256': <TokenType.INT256: 108>, 'LONG': <TokenType.BIGINT: 103>, 'BIGINT': <TokenType.BIGINT: 103>, 'INT8': <TokenType.TINYINT: 95>, 'UINT': <TokenType.UINT: 102>, 'UINT128': <TokenType.UINT128: 107>, 'UINT256': <TokenType.UINT256: 109>, 'DEC': <TokenType.DECIMAL: 113>, 'DECIMAL': <TokenType.DECIMAL: 113>, 'DECIMAL32': <TokenType.DECIMAL32: 114>, 'DECIMAL64': <TokenType.DECIMAL64: 115>, 'DECIMAL128': <TokenType.DECIMAL128: 116>, 'DECIMAL256': <TokenType.DECIMAL256: 117>, 'DECFLOAT': <TokenType.DECFLOAT: 118>, 'BIGDECIMAL': <TokenType.BIGDECIMAL: 120>, 'BIGNUMERIC': <TokenType.BIGDECIMAL: 120>, 'BIGNUM': <TokenType.BIGNUM: 105>, 'LIST': <TokenType.LIST: 314>, 'MAP': <TokenType.MAP: 317>, 'NULLABLE': <TokenType.NULLABLE: 170>, 'NUMBER': <TokenType.DECIMAL: 113>, 'NUMERIC': <TokenType.DECIMAL: 113>, 'FIXED': <TokenType.DECIMAL: 113>, 'REAL': <TokenType.FLOAT: 110>, 'FLOAT': <TokenType.FLOAT: 110>, 'FLOAT4': <TokenType.FLOAT: 110>, 'FLOAT8': <TokenType.DOUBLE: 111>, 'DOUBLE': <TokenType.DOUBLE: 111>, 'DOUBLE PRECISION': <TokenType.DOUBLE: 111>, 'JSON': <TokenType.JSON: 137>, 'JSONB': <TokenType.JSONB: 138>, 'CHAR': <TokenType.CHAR: 121>, 'CHARACTER': <TokenType.CHAR: 121>, 'CHAR VARYING': <TokenType.VARCHAR: 123>, 'CHARACTER VARYING': <TokenType.VARCHAR: 123>, 'NCHAR': <TokenType.NCHAR: 122>, 'VARCHAR': <TokenType.VARCHAR: 123>, 'VARCHAR2': <TokenType.VARCHAR: 123>, 'NVARCHAR': <TokenType.NVARCHAR: 124>, 'NVARCHAR2': <TokenType.NVARCHAR: 124>, 'BPCHAR': <TokenType.BPCHAR: 125>, 'STR': <TokenType.TEXT: 126>, 'STRING': <TokenType.TEXT: 126>, 'TEXT': <TokenType.TEXT: 126>, 'LONGTEXT': <TokenType.LONGTEXT: 128>, 'MEDIUMTEXT': <TokenType.MEDIUMTEXT: 127>, 'TINYTEXT': <TokenType.TINYTEXT: 133>, 'CLOB': <TokenType.TEXT: 126>, 'LONGVARCHAR': <TokenType.TEXT: 126>, 'BINARY': <TokenType.BINARY: 135>, 'BLOB': <TokenType.BLOB: 129>, 'LONGBLOB': <TokenType.LONGBLOB: 131>, 'MEDIUMBLOB': <TokenType.MEDIUMBLOB: 130>, 'TINYBLOB': <TokenType.TINYBLOB: 132>, 'BYTEA': <TokenType.VARBINARY: 136>, 'VARBINARY': <TokenType.VARBINARY: 136>, 'TIME': <TokenType.TIME: 139>, 'TIMETZ': <TokenType.TIMETZ: 140>, 'TIME_NS': <TokenType.TIME_NS: 141>, 'TIMESTAMP': <TokenType.TIMESTAMPTZ: 143>, 'TIMESTAMPTZ': <TokenType.TIMESTAMPTZ: 143>, 'TIMESTAMPLTZ': <TokenType.TIMESTAMPLTZ: 144>, 'TIMESTAMP_LTZ': <TokenType.TIMESTAMPLTZ: 144>, 'TIMESTAMPNTZ': <TokenType.TIMESTAMPNTZ: 145>, 'TIMESTAMP_NTZ': <TokenType.TIMESTAMPNTZ: 145>, 'DATE': <TokenType.DATE: 153>, 'DATETIME': <TokenType.DATETIME: 149>, 'INT4RANGE': <TokenType.INT4RANGE: 155>, 'INT4MULTIRANGE': <TokenType.INT4MULTIRANGE: 156>, 'INT8RANGE': <TokenType.INT8RANGE: 157>, 'INT8MULTIRANGE': <TokenType.INT8MULTIRANGE: 158>, 'NUMRANGE': <TokenType.NUMRANGE: 159>, 'NUMMULTIRANGE': <TokenType.NUMMULTIRANGE: 160>, 'TSRANGE': <TokenType.TSRANGE: 161>, 'TSMULTIRANGE': <TokenType.TSMULTIRANGE: 162>, 'TSTZRANGE': <TokenType.TSTZRANGE: 163>, 'TSTZMULTIRANGE': <TokenType.TSTZMULTIRANGE: 164>, 'DATERANGE': <TokenType.DATERANGE: 165>, 'DATEMULTIRANGE': <TokenType.DATEMULTIRANGE: 166>, 'UNIQUE': <TokenType.UNIQUE: 416>, 'VECTOR': <TokenType.VECTOR: 211>, 'STRUCT': <TokenType.STRUCT: 390>, 'SEQUENCE': <TokenType.SEQUENCE: 378>, 'VARIANT': <TokenType.VARIANT: 194>, 'ALTER': <TokenType.ALTER: 215>, 'ANALYZE': <TokenType.ANALYZE: 425>, 'CALL': <TokenType.COMMAND: 233>, 'COMMENT': <TokenType.COMMENT: 234>, 'EXPLAIN': <TokenType.DESCRIBE: 254>, 'GRANT': <TokenType.GRANT: 284>, 'REVOKE': <TokenType.REVOKE: 367>, 'OPTIMIZE': <TokenType.COMMAND: 233>, 'PREPARE': <TokenType.COMMAND: 233>, 'VACUUM': <TokenType.COMMAND: 233>, 'USER-DEFINED': <TokenType.USERDEFINED: 189>, 'FOR VERSION': <TokenType.VERSION_SNAPSHOT: 420>, 'FOR TIMESTAMP': <TokenType.TIMESTAMP_SNAPSHOT: 421>, 'CHARSET': <TokenType.CHARACTER_SET: 230>, 'DISTINCTROW': <TokenType.DISTINCT: 257>, 'FORCE': <TokenType.FORCE: 275>, 'IGNORE': <TokenType.IGNORE: 289>, 'KEY': <TokenType.KEY: 307>, 'LOCK TABLES': <TokenType.COMMAND: 233>, 'MEMBER OF': <TokenType.MEMBER_OF: 321>, 'MOD': <TokenType.MOD: 323>, 'SEPARATOR': <TokenType.SEPARATOR: 377>, 'SERIAL': <TokenType.SERIAL: 184>, 'SIGNED': <TokenType.BIGINT: 103>, 'SIGNED INTEGER': <TokenType.BIGINT: 103>, 'SOUNDS LIKE': <TokenType.SOUNDS_LIKE: 386>, 'START': <TokenType.BEGIN: 225>, 'UNLOCK TABLES': <TokenType.COMMAND: 233>, 'UNSIGNED': <TokenType.UBIGINT: 104>, 'UNSIGNED INTEGER': <TokenType.UBIGINT: 104>, 'YEAR': <TokenType.YEAR: 188>, '_ARMSCII8': <TokenType.INTRODUCER: 300>, '_ASCII': <TokenType.INTRODUCER: 300>, '_BIG5': <TokenType.INTRODUCER: 300>, '_BINARY': <TokenType.INTRODUCER: 300>, '_CP1250': <TokenType.INTRODUCER: 300>, '_CP1251': <TokenType.INTRODUCER: 300>, '_CP1256': <TokenType.INTRODUCER: 300>, '_CP1257': <TokenType.INTRODUCER: 300>, '_CP850': <TokenType.INTRODUCER: 300>, '_CP852': <TokenType.INTRODUCER: 300>, '_CP866': <TokenType.INTRODUCER: 300>, '_CP932': <TokenType.INTRODUCER: 300>, '_DEC8': <TokenType.INTRODUCER: 300>, '_EUCJPMS': <TokenType.INTRODUCER: 300>, '_EUCKR': <TokenType.INTRODUCER: 300>, '_GB18030': <TokenType.INTRODUCER: 300>, '_GB2312': <TokenType.INTRODUCER: 300>, '_GBK': <TokenType.INTRODUCER: 300>, '_GEOSTD8': <TokenType.INTRODUCER: 300>, '_GREEK': <TokenType.INTRODUCER: 300>, '_HEBREW': <TokenType.INTRODUCER: 300>, '_HP8': <TokenType.INTRODUCER: 300>, '_KEYBCS2': <TokenType.INTRODUCER: 300>, '_KOI8R': <TokenType.INTRODUCER: 300>, '_KOI8U': <TokenType.INTRODUCER: 300>, '_LATIN1': <TokenType.INTRODUCER: 300>, '_LATIN2': <TokenType.INTRODUCER: 300>, '_LATIN5': <TokenType.INTRODUCER: 300>, '_LATIN7': <TokenType.INTRODUCER: 300>, '_MACCE': <TokenType.INTRODUCER: 300>, '_MACROMAN': <TokenType.INTRODUCER: 300>, '_SJIS': <TokenType.INTRODUCER: 300>, '_SWE7': <TokenType.INTRODUCER: 300>, '_TIS620': <TokenType.INTRODUCER: 300>, '_UCS2': <TokenType.INTRODUCER: 300>, '_UJIS': <TokenType.INTRODUCER: 300>, '_UTF8': <TokenType.INTRODUCER: 300>, '_UTF16': <TokenType.INTRODUCER: 300>, '_UTF16LE': <TokenType.INTRODUCER: 300>, '_UTF32': <TokenType.INTRODUCER: 300>, '_UTF8MB3': <TokenType.INTRODUCER: 300>, '_UTF8MB4': <TokenType.INTRODUCER: 300>, '@@': <TokenType.SESSION_PARAMETER: 57>}
COMMANDS = {<TokenType.EXECUTE: 265>, <TokenType.COMMAND: 233>, <TokenType.RENAME: 364>, <TokenType.REPLACE: 365>, <TokenType.FETCH: 268>}
BYTE_STRING_ESCAPES: ClassVar[List[str]] = ["'", '"', '\\']
class MySQL.Parser(sqlglot.parser.Parser):
293    class Parser(parser.Parser):
294        FUNC_TOKENS = {
295            *parser.Parser.FUNC_TOKENS,
296            TokenType.DATABASE,
297            TokenType.MOD,
298            TokenType.SCHEMA,
299            TokenType.VALUES,
300            TokenType.CHARACTER_SET,
301        }
302
303        CONJUNCTION = {
304            **parser.Parser.CONJUNCTION,
305            TokenType.DAMP: exp.And,
306            TokenType.XOR: exp.Xor,
307        }
308
309        DISJUNCTION = {
310            **parser.Parser.DISJUNCTION,
311            TokenType.DPIPE: exp.Or,
312        }
313
314        TABLE_ALIAS_TOKENS = (
315            parser.Parser.TABLE_ALIAS_TOKENS - parser.Parser.TABLE_INDEX_HINT_TOKENS
316        )
317
318        RANGE_PARSERS = {
319            **parser.Parser.RANGE_PARSERS,
320            TokenType.SOUNDS_LIKE: lambda self, this: self.expression(
321                exp.EQ,
322                this=self.expression(exp.Soundex, this=this),
323                expression=self.expression(exp.Soundex, this=self._parse_term()),
324            ),
325            TokenType.MEMBER_OF: lambda self, this: self.expression(
326                exp.JSONArrayContains,
327                this=this,
328                expression=self._parse_wrapped(self._parse_expression),
329            ),
330        }
331
332        FUNCTIONS = {
333            **parser.Parser.FUNCTIONS,
334            "BIT_AND": exp.BitwiseAndAgg.from_arg_list,
335            "BIT_OR": exp.BitwiseOrAgg.from_arg_list,
336            "BIT_XOR": exp.BitwiseXorAgg.from_arg_list,
337            "BIT_COUNT": exp.BitwiseCount.from_arg_list,
338            "CONVERT_TZ": lambda args: exp.ConvertTimezone(
339                source_tz=seq_get(args, 1), target_tz=seq_get(args, 2), timestamp=seq_get(args, 0)
340            ),
341            "CURDATE": exp.CurrentDate.from_arg_list,
342            "CURTIME": exp.CurrentTime.from_arg_list,
343            "DATE": lambda args: exp.TsOrDsToDate(this=seq_get(args, 0)),
344            "DATE_ADD": build_date_delta_with_interval(exp.DateAdd),
345            "DATE_FORMAT": build_formatted_time(exp.TimeToStr, "mysql"),
346            "DATE_SUB": build_date_delta_with_interval(exp.DateSub),
347            "DAY": lambda args: exp.Day(this=exp.TsOrDsToDate(this=seq_get(args, 0))),
348            "DAYOFMONTH": lambda args: exp.DayOfMonth(this=exp.TsOrDsToDate(this=seq_get(args, 0))),
349            "DAYOFWEEK": lambda args: exp.DayOfWeek(this=exp.TsOrDsToDate(this=seq_get(args, 0))),
350            "DAYOFYEAR": lambda args: exp.DayOfYear(this=exp.TsOrDsToDate(this=seq_get(args, 0))),
351            "FORMAT": exp.NumberToStr.from_arg_list,
352            "FROM_UNIXTIME": build_formatted_time(exp.UnixToTime, "mysql"),
353            "ISNULL": isnull_to_is_null,
354            "LENGTH": lambda args: exp.Length(this=seq_get(args, 0), binary=True),
355            "MAKETIME": exp.TimeFromParts.from_arg_list,
356            "MONTH": lambda args: exp.Month(this=exp.TsOrDsToDate(this=seq_get(args, 0))),
357            "MONTHNAME": lambda args: exp.TimeToStr(
358                this=exp.TsOrDsToDate(this=seq_get(args, 0)),
359                format=exp.Literal.string("%B"),
360            ),
361            "SCHEMA": exp.CurrentSchema.from_arg_list,
362            "DATABASE": exp.CurrentSchema.from_arg_list,
363            "STR_TO_DATE": _str_to_date,
364            "TIMESTAMPDIFF": build_date_delta(exp.TimestampDiff),
365            "TO_DAYS": lambda args: exp.paren(
366                exp.DateDiff(
367                    this=exp.TsOrDsToDate(this=seq_get(args, 0)),
368                    expression=exp.TsOrDsToDate(this=exp.Literal.string("0000-01-01")),
369                    unit=exp.var("DAY"),
370                )
371                + 1
372            ),
373            "VERSION": exp.CurrentVersion.from_arg_list,
374            "WEEK": lambda args: exp.Week(
375                this=exp.TsOrDsToDate(this=seq_get(args, 0)), mode=seq_get(args, 1)
376            ),
377            "WEEKOFYEAR": lambda args: exp.WeekOfYear(this=exp.TsOrDsToDate(this=seq_get(args, 0))),
378            "YEAR": lambda args: exp.Year(this=exp.TsOrDsToDate(this=seq_get(args, 0))),
379        }
380
381        FUNCTION_PARSERS = {
382            **parser.Parser.FUNCTION_PARSERS,
383            "GROUP_CONCAT": lambda self: self._parse_group_concat(),
384            # https://dev.mysql.com/doc/refman/5.7/en/miscellaneous-functions.html#function_values
385            "VALUES": lambda self: self.expression(
386                exp.Anonymous, this="VALUES", expressions=[self._parse_id_var()]
387            ),
388            "JSON_VALUE": lambda self: self._parse_json_value(),
389            "SUBSTR": lambda self: self._parse_substring(),
390        }
391
392        STATEMENT_PARSERS = {
393            **parser.Parser.STATEMENT_PARSERS,
394            TokenType.SHOW: lambda self: self._parse_show(),
395        }
396
397        SHOW_PARSERS = {
398            "BINARY LOGS": _show_parser("BINARY LOGS"),
399            "MASTER LOGS": _show_parser("BINARY LOGS"),
400            "BINLOG EVENTS": _show_parser("BINLOG EVENTS"),
401            "CHARACTER SET": _show_parser("CHARACTER SET"),
402            "CHARSET": _show_parser("CHARACTER SET"),
403            "COLLATION": _show_parser("COLLATION"),
404            "FULL COLUMNS": _show_parser("COLUMNS", target="FROM", full=True),
405            "COLUMNS": _show_parser("COLUMNS", target="FROM"),
406            "CREATE DATABASE": _show_parser("CREATE DATABASE", target=True),
407            "CREATE EVENT": _show_parser("CREATE EVENT", target=True),
408            "CREATE FUNCTION": _show_parser("CREATE FUNCTION", target=True),
409            "CREATE PROCEDURE": _show_parser("CREATE PROCEDURE", target=True),
410            "CREATE TABLE": _show_parser("CREATE TABLE", target=True),
411            "CREATE TRIGGER": _show_parser("CREATE TRIGGER", target=True),
412            "CREATE VIEW": _show_parser("CREATE VIEW", target=True),
413            "DATABASES": _show_parser("DATABASES"),
414            "SCHEMAS": _show_parser("DATABASES"),
415            "ENGINE": _show_parser("ENGINE", target=True),
416            "STORAGE ENGINES": _show_parser("ENGINES"),
417            "ENGINES": _show_parser("ENGINES"),
418            "ERRORS": _show_parser("ERRORS"),
419            "EVENTS": _show_parser("EVENTS"),
420            "FUNCTION CODE": _show_parser("FUNCTION CODE", target=True),
421            "FUNCTION STATUS": _show_parser("FUNCTION STATUS"),
422            "GRANTS": _show_parser("GRANTS", target="FOR"),
423            "INDEX": _show_parser("INDEX", target="FROM"),
424            "MASTER STATUS": _show_parser("MASTER STATUS"),
425            "OPEN TABLES": _show_parser("OPEN TABLES"),
426            "PLUGINS": _show_parser("PLUGINS"),
427            "PROCEDURE CODE": _show_parser("PROCEDURE CODE", target=True),
428            "PROCEDURE STATUS": _show_parser("PROCEDURE STATUS"),
429            "PRIVILEGES": _show_parser("PRIVILEGES"),
430            "FULL PROCESSLIST": _show_parser("PROCESSLIST", full=True),
431            "PROCESSLIST": _show_parser("PROCESSLIST"),
432            "PROFILE": _show_parser("PROFILE"),
433            "PROFILES": _show_parser("PROFILES"),
434            "RELAYLOG EVENTS": _show_parser("RELAYLOG EVENTS"),
435            "REPLICAS": _show_parser("REPLICAS"),
436            "SLAVE HOSTS": _show_parser("REPLICAS"),
437            "REPLICA STATUS": _show_parser("REPLICA STATUS"),
438            "SLAVE STATUS": _show_parser("REPLICA STATUS"),
439            "GLOBAL STATUS": _show_parser("STATUS", global_=True),
440            "SESSION STATUS": _show_parser("STATUS"),
441            "STATUS": _show_parser("STATUS"),
442            "TABLE STATUS": _show_parser("TABLE STATUS"),
443            "FULL TABLES": _show_parser("TABLES", full=True),
444            "TABLES": _show_parser("TABLES"),
445            "TRIGGERS": _show_parser("TRIGGERS"),
446            "GLOBAL VARIABLES": _show_parser("VARIABLES", global_=True),
447            "SESSION VARIABLES": _show_parser("VARIABLES"),
448            "VARIABLES": _show_parser("VARIABLES"),
449            "WARNINGS": _show_parser("WARNINGS"),
450        }
451
452        PROPERTY_PARSERS = {
453            **parser.Parser.PROPERTY_PARSERS,
454            "LOCK": lambda self: self._parse_property_assignment(exp.LockProperty),
455            "PARTITION BY": lambda self: self._parse_partition_property(),
456        }
457
458        SET_PARSERS = {
459            **parser.Parser.SET_PARSERS,
460            "PERSIST": lambda self: self._parse_set_item_assignment("PERSIST"),
461            "PERSIST_ONLY": lambda self: self._parse_set_item_assignment("PERSIST_ONLY"),
462            "CHARACTER SET": lambda self: self._parse_set_item_charset("CHARACTER SET"),
463            "CHARSET": lambda self: self._parse_set_item_charset("CHARACTER SET"),
464            "NAMES": lambda self: self._parse_set_item_names(),
465        }
466
467        CONSTRAINT_PARSERS = {
468            **parser.Parser.CONSTRAINT_PARSERS,
469            "FULLTEXT": lambda self: self._parse_index_constraint(kind="FULLTEXT"),
470            "INDEX": lambda self: self._parse_index_constraint(),
471            "KEY": lambda self: self._parse_index_constraint(),
472            "SPATIAL": lambda self: self._parse_index_constraint(kind="SPATIAL"),
473            "ZEROFILL": lambda self: self.expression(exp.ZeroFillColumnConstraint),
474        }
475
476        ALTER_PARSERS = {
477            **parser.Parser.ALTER_PARSERS,
478            "MODIFY": lambda self: self._parse_alter_table_alter(),
479        }
480
481        ALTER_ALTER_PARSERS = {
482            **parser.Parser.ALTER_ALTER_PARSERS,
483            "INDEX": lambda self: self._parse_alter_table_alter_index(),
484        }
485
486        SCHEMA_UNNAMED_CONSTRAINTS = {
487            *parser.Parser.SCHEMA_UNNAMED_CONSTRAINTS,
488            "FULLTEXT",
489            "INDEX",
490            "KEY",
491            "SPATIAL",
492        }
493
494        PROFILE_TYPES: parser.OPTIONS_TYPE = {
495            **dict.fromkeys(("ALL", "CPU", "IPC", "MEMORY", "SOURCE", "SWAPS"), tuple()),
496            "BLOCK": ("IO",),
497            "CONTEXT": ("SWITCHES",),
498            "PAGE": ("FAULTS",),
499        }
500
501        TYPE_TOKENS = {
502            *parser.Parser.TYPE_TOKENS,
503            TokenType.SET,
504        }
505
506        ENUM_TYPE_TOKENS = {
507            *parser.Parser.ENUM_TYPE_TOKENS,
508            TokenType.SET,
509        }
510
511        # SELECT [ ALL | DISTINCT | DISTINCTROW ] [ <OPERATION_MODIFIERS> ]
512        OPERATION_MODIFIERS = {
513            "HIGH_PRIORITY",
514            "STRAIGHT_JOIN",
515            "SQL_SMALL_RESULT",
516            "SQL_BIG_RESULT",
517            "SQL_BUFFER_RESULT",
518            "SQL_NO_CACHE",
519            "SQL_CALC_FOUND_ROWS",
520        }
521
522        LOG_DEFAULTS_TO_LN = True
523        STRING_ALIASES = True
524        VALUES_FOLLOWED_BY_PAREN = False
525        SUPPORTS_PARTITION_SELECTION = True
526
527        def _parse_generated_as_identity(
528            self,
529        ) -> (
530            exp.GeneratedAsIdentityColumnConstraint
531            | exp.ComputedColumnConstraint
532            | exp.GeneratedAsRowColumnConstraint
533        ):
534            this = super()._parse_generated_as_identity()
535
536            if self._match_texts(("STORED", "VIRTUAL")):
537                persisted = self._prev.text.upper() == "STORED"
538
539                if isinstance(this, exp.ComputedColumnConstraint):
540                    this.set("persisted", persisted)
541                elif isinstance(this, exp.GeneratedAsIdentityColumnConstraint):
542                    this = self.expression(
543                        exp.ComputedColumnConstraint, this=this.expression, persisted=persisted
544                    )
545
546            return this
547
548        def _parse_primary_key_part(self) -> t.Optional[exp.Expression]:
549            this = self._parse_id_var()
550            if not self._match(TokenType.L_PAREN):
551                return this
552
553            expression = self._parse_number()
554            self._match_r_paren()
555            return self.expression(exp.ColumnPrefix, this=this, expression=expression)
556
557        def _parse_index_constraint(
558            self, kind: t.Optional[str] = None
559        ) -> exp.IndexColumnConstraint:
560            if kind:
561                self._match_texts(("INDEX", "KEY"))
562
563            this = self._parse_id_var(any_token=False)
564            index_type = self._match(TokenType.USING) and self._advance_any() and self._prev.text
565            expressions = self._parse_wrapped_csv(self._parse_ordered)
566
567            options = []
568            while True:
569                if self._match_text_seq("KEY_BLOCK_SIZE"):
570                    self._match(TokenType.EQ)
571                    opt = exp.IndexConstraintOption(key_block_size=self._parse_number())
572                elif self._match(TokenType.USING):
573                    opt = exp.IndexConstraintOption(using=self._advance_any() and self._prev.text)
574                elif self._match_text_seq("WITH", "PARSER"):
575                    opt = exp.IndexConstraintOption(parser=self._parse_var(any_token=True))
576                elif self._match(TokenType.COMMENT):
577                    opt = exp.IndexConstraintOption(comment=self._parse_string())
578                elif self._match_text_seq("VISIBLE"):
579                    opt = exp.IndexConstraintOption(visible=True)
580                elif self._match_text_seq("INVISIBLE"):
581                    opt = exp.IndexConstraintOption(visible=False)
582                elif self._match_text_seq("ENGINE_ATTRIBUTE"):
583                    self._match(TokenType.EQ)
584                    opt = exp.IndexConstraintOption(engine_attr=self._parse_string())
585                elif self._match_text_seq("SECONDARY_ENGINE_ATTRIBUTE"):
586                    self._match(TokenType.EQ)
587                    opt = exp.IndexConstraintOption(secondary_engine_attr=self._parse_string())
588                else:
589                    opt = None
590
591                if not opt:
592                    break
593
594                options.append(opt)
595
596            return self.expression(
597                exp.IndexColumnConstraint,
598                this=this,
599                expressions=expressions,
600                kind=kind,
601                index_type=index_type,
602                options=options,
603            )
604
605        def _parse_show_mysql(
606            self,
607            this: str,
608            target: bool | str = False,
609            full: t.Optional[bool] = None,
610            global_: t.Optional[bool] = None,
611        ) -> exp.Show:
612            json = self._match_text_seq("JSON")
613
614            if target:
615                if isinstance(target, str):
616                    self._match_text_seq(*target.split(" "))
617                target_id = self._parse_id_var()
618            else:
619                target_id = None
620
621            log = self._parse_string() if self._match_text_seq("IN") else None
622
623            if this in ("BINLOG EVENTS", "RELAYLOG EVENTS"):
624                position = self._parse_number() if self._match_text_seq("FROM") else None
625                db = None
626            else:
627                position = None
628                db = None
629
630                if self._match(TokenType.FROM):
631                    db = self._parse_id_var()
632                elif self._match(TokenType.DOT):
633                    db = target_id
634                    target_id = self._parse_id_var()
635
636            channel = self._parse_id_var() if self._match_text_seq("FOR", "CHANNEL") else None
637
638            like = self._parse_string() if self._match_text_seq("LIKE") else None
639            where = self._parse_where()
640
641            if this == "PROFILE":
642                types = self._parse_csv(lambda: self._parse_var_from_options(self.PROFILE_TYPES))
643                query = self._parse_number() if self._match_text_seq("FOR", "QUERY") else None
644                offset = self._parse_number() if self._match_text_seq("OFFSET") else None
645                limit = self._parse_number() if self._match_text_seq("LIMIT") else None
646            else:
647                types, query = None, None
648                offset, limit = self._parse_oldstyle_limit()
649
650            mutex = True if self._match_text_seq("MUTEX") else None
651            mutex = False if self._match_text_seq("STATUS") else mutex
652
653            for_table = self._parse_id_var() if self._match_text_seq("FOR", "TABLE") else None
654            for_group = self._parse_string() if self._match_text_seq("FOR", "GROUP") else None
655            for_user = self._parse_string() if self._match_text_seq("FOR", "USER") else None
656            for_role = self._parse_string() if self._match_text_seq("FOR", "ROLE") else None
657            into_outfile = self._parse_string() if self._match_text_seq("INTO", "OUTFILE") else None
658
659            return self.expression(
660                exp.Show,
661                this=this,
662                target=target_id,
663                full=full,
664                log=log,
665                position=position,
666                db=db,
667                channel=channel,
668                like=like,
669                where=where,
670                types=types,
671                query=query,
672                offset=offset,
673                limit=limit,
674                mutex=mutex,
675                for_table=for_table,
676                for_group=for_group,
677                for_user=for_user,
678                for_role=for_role,
679                into_outfile=into_outfile,
680                json=json,
681                global_=global_,
682            )
683
684        def _parse_oldstyle_limit(
685            self,
686        ) -> t.Tuple[t.Optional[exp.Expression], t.Optional[exp.Expression]]:
687            limit = None
688            offset = None
689            if self._match_text_seq("LIMIT"):
690                parts = self._parse_csv(self._parse_number)
691                if len(parts) == 1:
692                    limit = parts[0]
693                elif len(parts) == 2:
694                    limit = parts[1]
695                    offset = parts[0]
696
697            return offset, limit
698
699        def _parse_set_item_charset(self, kind: str) -> exp.Expression:
700            this = self._parse_string() or self._parse_unquoted_field()
701            return self.expression(exp.SetItem, this=this, kind=kind)
702
703        def _parse_set_item_names(self) -> exp.Expression:
704            charset = self._parse_string() or self._parse_unquoted_field()
705            if self._match_text_seq("COLLATE"):
706                collate = self._parse_string() or self._parse_unquoted_field()
707            else:
708                collate = None
709
710            return self.expression(exp.SetItem, this=charset, collate=collate, kind="NAMES")
711
712        def _parse_type(
713            self, parse_interval: bool = True, fallback_to_identifier: bool = False
714        ) -> t.Optional[exp.Expression]:
715            # mysql binary is special and can work anywhere, even in order by operations
716            # it operates like a no paren func
717            if self._match(TokenType.BINARY, advance=False):
718                data_type = self._parse_types(check_func=True, allow_identifiers=False)
719
720                if isinstance(data_type, exp.DataType):
721                    return self.expression(exp.Cast, this=self._parse_column(), to=data_type)
722
723            return super()._parse_type(
724                parse_interval=parse_interval, fallback_to_identifier=fallback_to_identifier
725            )
726
727        def _parse_alter_table_alter_index(self) -> exp.AlterIndex:
728            index = self._parse_field(any_token=True)
729
730            if self._match_text_seq("VISIBLE"):
731                visible = True
732            elif self._match_text_seq("INVISIBLE"):
733                visible = False
734            else:
735                visible = None
736
737            return self.expression(exp.AlterIndex, this=index, visible=visible)
738
739        def _parse_partition_property(
740            self,
741        ) -> t.Optional[exp.Expression] | t.List[exp.Expression]:
742            partition_cls: t.Optional[t.Type[exp.Expression]] = None
743            value_parser = None
744
745            if self._match_text_seq("RANGE"):
746                partition_cls = exp.PartitionByRangeProperty
747                value_parser = self._parse_partition_range_value
748            elif self._match_text_seq("LIST"):
749                partition_cls = exp.PartitionByListProperty
750                value_parser = self._parse_partition_list_value
751
752            if not partition_cls or not value_parser:
753                return None
754
755            partition_expressions = self._parse_wrapped_csv(self._parse_assignment)
756
757            # For Doris and Starrocks
758            if not self._match_text_seq("(", "PARTITION", advance=False):
759                return partition_expressions
760
761            create_expressions = self._parse_wrapped_csv(value_parser)
762
763            return self.expression(
764                partition_cls,
765                partition_expressions=partition_expressions,
766                create_expressions=create_expressions,
767            )
768
769        def _parse_partition_range_value(self) -> t.Optional[exp.Expression]:
770            self._match_text_seq("PARTITION")
771            name = self._parse_id_var()
772
773            if not self._match_text_seq("VALUES", "LESS", "THAN"):
774                return name
775
776            values = self._parse_wrapped_csv(self._parse_expression)
777
778            if (
779                len(values) == 1
780                and isinstance(values[0], exp.Column)
781                and values[0].name.upper() == "MAXVALUE"
782            ):
783                values = [exp.var("MAXVALUE")]
784
785            part_range = self.expression(exp.PartitionRange, this=name, expressions=values)
786            return self.expression(exp.Partition, expressions=[part_range])
787
788        def _parse_partition_list_value(self) -> exp.Partition:
789            self._match_text_seq("PARTITION")
790            name = self._parse_id_var()
791            self._match_text_seq("VALUES", "IN")
792            values = self._parse_wrapped_csv(self._parse_expression)
793            part_list = self.expression(exp.PartitionList, this=name, expressions=values)
794            return self.expression(exp.Partition, expressions=[part_list])
795
796        def _parse_primary_key(
797            self,
798            wrapped_optional: bool = False,
799            in_props: bool = False,
800            named_primary_key: bool = False,
801        ) -> exp.PrimaryKeyColumnConstraint | exp.PrimaryKey:
802            return super()._parse_primary_key(
803                wrapped_optional=wrapped_optional, in_props=in_props, named_primary_key=True
804            )

Parser consumes a list of tokens produced by the Tokenizer and produces a parsed syntax tree.

Arguments:
  • error_level: The desired error level. Default: ErrorLevel.IMMEDIATE
  • error_message_context: The amount of context to capture from a query string when displaying the error message (in number of characters). Default: 100
  • max_errors: Maximum number of error messages to include in a raised ParseError. This is only relevant if error_level is ErrorLevel.RAISE. Default: 3
FUNC_TOKENS = {<TokenType.SESSION_USER: 58>, <TokenType.XOR: 63>, <TokenType.IDENTIFIER: 76>, <TokenType.DATABASE: 77>, <TokenType.SCHEMA: 80>, <TokenType.TABLE: 81>, <TokenType.VAR: 85>, <TokenType.BIT: 93>, <TokenType.BOOLEAN: 94>, <TokenType.TINYINT: 95>, <TokenType.UTINYINT: 96>, <TokenType.SMALLINT: 97>, <TokenType.USMALLINT: 98>, <TokenType.MEDIUMINT: 99>, <TokenType.UMEDIUMINT: 100>, <TokenType.INT: 101>, <TokenType.UINT: 102>, <TokenType.BIGINT: 103>, <TokenType.UBIGINT: 104>, <TokenType.BIGNUM: 105>, <TokenType.INT128: 106>, <TokenType.UINT128: 107>, <TokenType.INT256: 108>, <TokenType.UINT256: 109>, <TokenType.FLOAT: 110>, <TokenType.DOUBLE: 111>, <TokenType.UDOUBLE: 112>, <TokenType.DECIMAL: 113>, <TokenType.DECIMAL32: 114>, <TokenType.DECIMAL64: 115>, <TokenType.DECIMAL128: 116>, <TokenType.DECIMAL256: 117>, <TokenType.DECFLOAT: 118>, <TokenType.UDECIMAL: 119>, <TokenType.BIGDECIMAL: 120>, <TokenType.CHAR: 121>, <TokenType.NCHAR: 122>, <TokenType.VARCHAR: 123>, <TokenType.NVARCHAR: 124>, <TokenType.BPCHAR: 125>, <TokenType.TEXT: 126>, <TokenType.MEDIUMTEXT: 127>, <TokenType.LONGTEXT: 128>, <TokenType.BLOB: 129>, <TokenType.MEDIUMBLOB: 130>, <TokenType.LONGBLOB: 131>, <TokenType.TINYBLOB: 132>, <TokenType.TINYTEXT: 133>, <TokenType.NAME: 134>, <TokenType.BINARY: 135>, <TokenType.VARBINARY: 136>, <TokenType.JSON: 137>, <TokenType.JSONB: 138>, <TokenType.TIME: 139>, <TokenType.TIMETZ: 140>, <TokenType.TIME_NS: 141>, <TokenType.TIMESTAMP: 142>, <TokenType.TIMESTAMPTZ: 143>, <TokenType.TIMESTAMPLTZ: 144>, <TokenType.TIMESTAMPNTZ: 145>, <TokenType.TIMESTAMP_S: 146>, <TokenType.TIMESTAMP_MS: 147>, <TokenType.TIMESTAMP_NS: 148>, <TokenType.DATETIME: 149>, <TokenType.DATETIME2: 150>, <TokenType.DATETIME64: 151>, <TokenType.SMALLDATETIME: 152>, <TokenType.DATE: 153>, <TokenType.DATE32: 154>, <TokenType.INT4RANGE: 155>, <TokenType.INT4MULTIRANGE: 156>, <TokenType.INT8RANGE: 157>, <TokenType.INT8MULTIRANGE: 158>, <TokenType.NUMRANGE: 159>, <TokenType.NUMMULTIRANGE: 160>, <TokenType.TSRANGE: 161>, <TokenType.TSMULTIRANGE: 162>, <TokenType.TSTZRANGE: 163>, <TokenType.TSTZMULTIRANGE: 164>, <TokenType.DATERANGE: 165>, <TokenType.DATEMULTIRANGE: 166>, <TokenType.UUID: 167>, <TokenType.GEOGRAPHY: 168>, <TokenType.GEOGRAPHYPOINT: 169>, <TokenType.NULLABLE: 170>, <TokenType.GEOMETRY: 171>, <TokenType.POINT: 172>, <TokenType.RING: 173>, <TokenType.LINESTRING: 174>, <TokenType.LOCALTIME: 175>, <TokenType.LOCALTIMESTAMP: 176>, <TokenType.MULTILINESTRING: 178>, <TokenType.POLYGON: 179>, <TokenType.MULTIPOLYGON: 180>, <TokenType.HLLSKETCH: 181>, <TokenType.HSTORE: 182>, <TokenType.SUPER: 183>, <TokenType.SERIAL: 184>, <TokenType.SMALLSERIAL: 185>, <TokenType.BIGSERIAL: 186>, <TokenType.XML: 187>, <TokenType.YEAR: 188>, <TokenType.USERDEFINED: 189>, <TokenType.MONEY: 190>, <TokenType.SMALLMONEY: 191>, <TokenType.ROWVERSION: 192>, <TokenType.IMAGE: 193>, <TokenType.VARIANT: 194>, <TokenType.OBJECT: 195>, <TokenType.INET: 196>, <TokenType.IPADDRESS: 197>, <TokenType.IPPREFIX: 198>, <TokenType.IPV4: 199>, <TokenType.IPV6: 200>, <TokenType.ENUM: 201>, <TokenType.ENUM8: 202>, <TokenType.ENUM16: 203>, <TokenType.FIXEDSTRING: 204>, <TokenType.LOWCARDINALITY: 205>, <TokenType.NESTED: 206>, <TokenType.AGGREGATEFUNCTION: 207>, <TokenType.SIMPLEAGGREGATEFUNCTION: 208>, <TokenType.TDIGEST: 209>, <TokenType.UNKNOWN: 210>, <TokenType.VECTOR: 211>, <TokenType.DYNAMIC: 212>, <TokenType.VOID: 213>, <TokenType.ALL: 216>, <TokenType.ANY: 218>, <TokenType.ARRAY: 220>, <TokenType.CHARACTER_SET: 230>, <TokenType.COLLATE: 232>, <TokenType.COMMAND: 233>, <TokenType.CURRENT_DATE: 242>, <TokenType.CURRENT_DATETIME: 243>, <TokenType.CURRENT_SCHEMA: 244>, <TokenType.CURRENT_TIME: 245>, <TokenType.CURRENT_TIMESTAMP: 246>, <TokenType.CURRENT_USER: 247>, <TokenType.CURRENT_CATALOG: 249>, <TokenType.EXISTS: 266>, <TokenType.FILE: 269>, <TokenType.FILTER: 271>, <TokenType.FIRST: 273>, <TokenType.FORMAT: 277>, <TokenType.GET: 281>, <TokenType.GLOB: 282>, <TokenType.ILIKE: 290>, <TokenType.INDEX: 292>, <TokenType.INSERT: 295>, <TokenType.INTERVAL: 298>, <TokenType.ISNULL: 303>, <TokenType.LEFT: 311>, <TokenType.LIKE: 312>, <TokenType.LIST: 314>, <TokenType.MAP: 317>, <TokenType.MERGE: 322>, <TokenType.MOD: 323>, <TokenType.NEXT: 326>, <TokenType.NOTHING: 327>, <TokenType.NULL: 329>, <TokenType.OBJECT_IDENTIFIER: 330>, <TokenType.OFFSET: 331>, <TokenType.PRIMARY_KEY: 353>, <TokenType.PSEUDO_TYPE: 356>, <TokenType.RANGE: 361>, <TokenType.REPLACE: 365>, <TokenType.RIGHT: 369>, <TokenType.RLIKE: 370>, <TokenType.ROW: 373>, <TokenType.SEQUENCE: 378>, <TokenType.SOME: 384>, <TokenType.STRUCT: 390>, <TokenType.TRUNCATE: 398>, <TokenType.UNION: 401>, <TokenType.UNNEST: 402>, <TokenType.VALUES: 407>, <TokenType.WINDOW: 414>, <TokenType.UTC_DATE: 417>, <TokenType.UTC_TIME: 418>, <TokenType.UTC_TIMESTAMP: 419>}
CONJUNCTION = {<TokenType.AND: 33>: <class 'sqlglot.expressions.And'>, <TokenType.DAMP: 59>: <class 'sqlglot.expressions.And'>, <TokenType.XOR: 63>: <class 'sqlglot.expressions.Xor'>}
DISJUNCTION = {<TokenType.OR: 34>: <class 'sqlglot.expressions.Or'>, <TokenType.DPIPE: 36>: <class 'sqlglot.expressions.Or'>}
TABLE_ALIAS_TOKENS = {<TokenType.SESSION: 56>, <TokenType.IDENTIFIER: 76>, <TokenType.DATABASE: 77>, <TokenType.COLUMN: 78>, <TokenType.SCHEMA: 80>, <TokenType.TABLE: 81>, <TokenType.WAREHOUSE: 82>, <TokenType.STAGE: 83>, <TokenType.STREAMLIT: 84>, <TokenType.VAR: 85>, <TokenType.BIT: 93>, <TokenType.BOOLEAN: 94>, <TokenType.TINYINT: 95>, <TokenType.UTINYINT: 96>, <TokenType.SMALLINT: 97>, <TokenType.USMALLINT: 98>, <TokenType.MEDIUMINT: 99>, <TokenType.UMEDIUMINT: 100>, <TokenType.INT: 101>, <TokenType.UINT: 102>, <TokenType.BIGINT: 103>, <TokenType.UBIGINT: 104>, <TokenType.BIGNUM: 105>, <TokenType.INT128: 106>, <TokenType.UINT128: 107>, <TokenType.INT256: 108>, <TokenType.UINT256: 109>, <TokenType.FLOAT: 110>, <TokenType.DOUBLE: 111>, <TokenType.UDOUBLE: 112>, <TokenType.DECIMAL: 113>, <TokenType.DECIMAL32: 114>, <TokenType.DECIMAL64: 115>, <TokenType.DECIMAL128: 116>, <TokenType.DECIMAL256: 117>, <TokenType.DECFLOAT: 118>, <TokenType.UDECIMAL: 119>, <TokenType.BIGDECIMAL: 120>, <TokenType.CHAR: 121>, <TokenType.NCHAR: 122>, <TokenType.VARCHAR: 123>, <TokenType.NVARCHAR: 124>, <TokenType.BPCHAR: 125>, <TokenType.TEXT: 126>, <TokenType.MEDIUMTEXT: 127>, <TokenType.LONGTEXT: 128>, <TokenType.BLOB: 129>, <TokenType.MEDIUMBLOB: 130>, <TokenType.LONGBLOB: 131>, <TokenType.TINYBLOB: 132>, <TokenType.TINYTEXT: 133>, <TokenType.NAME: 134>, <TokenType.BINARY: 135>, <TokenType.VARBINARY: 136>, <TokenType.JSON: 137>, <TokenType.JSONB: 138>, <TokenType.TIME: 139>, <TokenType.TIMETZ: 140>, <TokenType.TIME_NS: 141>, <TokenType.TIMESTAMP: 142>, <TokenType.TIMESTAMPTZ: 143>, <TokenType.TIMESTAMPLTZ: 144>, <TokenType.TIMESTAMPNTZ: 145>, <TokenType.TIMESTAMP_S: 146>, <TokenType.TIMESTAMP_MS: 147>, <TokenType.TIMESTAMP_NS: 148>, <TokenType.DATETIME: 149>, <TokenType.DATETIME2: 150>, <TokenType.DATETIME64: 151>, <TokenType.SMALLDATETIME: 152>, <TokenType.DATE: 153>, <TokenType.DATE32: 154>, <TokenType.INT4RANGE: 155>, <TokenType.INT4MULTIRANGE: 156>, <TokenType.INT8RANGE: 157>, <TokenType.INT8MULTIRANGE: 158>, <TokenType.NUMRANGE: 159>, <TokenType.NUMMULTIRANGE: 160>, <TokenType.TSRANGE: 161>, <TokenType.TSMULTIRANGE: 162>, <TokenType.TSTZRANGE: 163>, <TokenType.TSTZMULTIRANGE: 164>, <TokenType.DATERANGE: 165>, <TokenType.DATEMULTIRANGE: 166>, <TokenType.UUID: 167>, <TokenType.GEOGRAPHY: 168>, <TokenType.GEOGRAPHYPOINT: 169>, <TokenType.NULLABLE: 170>, <TokenType.GEOMETRY: 171>, <TokenType.POINT: 172>, <TokenType.RING: 173>, <TokenType.LINESTRING: 174>, <TokenType.LOCALTIME: 175>, <TokenType.LOCALTIMESTAMP: 176>, <TokenType.MULTILINESTRING: 178>, <TokenType.POLYGON: 179>, <TokenType.MULTIPOLYGON: 180>, <TokenType.HLLSKETCH: 181>, <TokenType.HSTORE: 182>, <TokenType.SUPER: 183>, <TokenType.SERIAL: 184>, <TokenType.SMALLSERIAL: 185>, <TokenType.BIGSERIAL: 186>, <TokenType.XML: 187>, <TokenType.YEAR: 188>, <TokenType.USERDEFINED: 189>, <TokenType.MONEY: 190>, <TokenType.SMALLMONEY: 191>, <TokenType.ROWVERSION: 192>, <TokenType.IMAGE: 193>, <TokenType.VARIANT: 194>, <TokenType.OBJECT: 195>, <TokenType.INET: 196>, <TokenType.IPADDRESS: 197>, <TokenType.IPPREFIX: 198>, <TokenType.IPV4: 199>, <TokenType.IPV6: 200>, <TokenType.ENUM: 201>, <TokenType.ENUM8: 202>, <TokenType.ENUM16: 203>, <TokenType.FIXEDSTRING: 204>, <TokenType.LOWCARDINALITY: 205>, <TokenType.NESTED: 206>, <TokenType.AGGREGATEFUNCTION: 207>, <TokenType.SIMPLEAGGREGATEFUNCTION: 208>, <TokenType.TDIGEST: 209>, <TokenType.UNKNOWN: 210>, <TokenType.VECTOR: 211>, <TokenType.DYNAMIC: 212>, <TokenType.VOID: 213>, <TokenType.ALL: 216>, <TokenType.ANTI: 217>, <TokenType.ANY: 218>, <TokenType.APPLY: 219>, <TokenType.ARRAY: 220>, <TokenType.ASC: 221>, <TokenType.ATTACH: 223>, <TokenType.AUTO_INCREMENT: 224>, <TokenType.BEGIN: 225>, <TokenType.CACHE: 228>, <TokenType.CASE: 229>, <TokenType.COLLATE: 232>, <TokenType.COMMAND: 233>, <TokenType.COMMENT: 234>, <TokenType.COMMIT: 235>, <TokenType.CONSTRAINT: 237>, <TokenType.COPY: 238>, <TokenType.CUBE: 241>, <TokenType.CURRENT_DATE: 242>, <TokenType.CURRENT_DATETIME: 243>, <TokenType.CURRENT_SCHEMA: 244>, <TokenType.CURRENT_TIME: 245>, <TokenType.CURRENT_TIMESTAMP: 246>, <TokenType.CURRENT_USER: 247>, <TokenType.CURRENT_ROLE: 248>, <TokenType.DEFAULT: 251>, <TokenType.DELETE: 252>, <TokenType.DESC: 253>, <TokenType.DESCRIBE: 254>, <TokenType.DETACH: 255>, <TokenType.DICTIONARY: 256>, <TokenType.DIV: 259>, <TokenType.END: 262>, <TokenType.ESCAPE: 263>, <TokenType.EXECUTE: 265>, <TokenType.EXISTS: 266>, <TokenType.FALSE: 267>, <TokenType.FILE: 269>, <TokenType.FILE_FORMAT: 270>, <TokenType.FILTER: 271>, <TokenType.FINAL: 272>, <TokenType.FIRST: 273>, <TokenType.FOREIGN_KEY: 276>, <TokenType.FORMAT: 277>, <TokenType.FUNCTION: 280>, <TokenType.GET: 281>, <TokenType.INDEX: 292>, <TokenType.INTERVAL: 298>, <TokenType.IS: 302>, <TokenType.ISNULL: 303>, <TokenType.KEEP: 306>, <TokenType.KILL: 308>, <TokenType.LIMIT: 313>, <TokenType.LIST: 314>, <TokenType.LOAD: 315>, <TokenType.MAP: 317>, <TokenType.MATCH: 318>, <TokenType.MERGE: 322>, <TokenType.MODEL: 324>, <TokenType.NEXT: 326>, <TokenType.NOTHING: 327>, <TokenType.NULL: 329>, <TokenType.OBJECT_IDENTIFIER: 330>, <TokenType.OFFSET: 331>, <TokenType.OPERATOR: 334>, <TokenType.ORDINALITY: 338>, <TokenType.INOUT: 340>, <TokenType.OVER: 342>, <TokenType.OVERLAPS: 343>, <TokenType.OVERWRITE: 344>, <TokenType.PARTITION: 345>, <TokenType.PERCENT: 347>, <TokenType.PIVOT: 348>, <TokenType.PRAGMA: 351>, <TokenType.PROCEDURE: 354>, <TokenType.PSEUDO_TYPE: 356>, <TokenType.PUT: 357>, <TokenType.RANGE: 361>, <TokenType.RECURSIVE: 362>, <TokenType.REFRESH: 363>, <TokenType.RENAME: 364>, <TokenType.REPLACE: 365>, <TokenType.REFERENCES: 368>, <TokenType.ROLLUP: 372>, <TokenType.ROW: 373>, <TokenType.ROWS: 374>, <TokenType.SEMI: 376>, <TokenType.SEQUENCE: 378>, <TokenType.SET: 380>, <TokenType.SETTINGS: 381>, <TokenType.SHOW: 382>, <TokenType.SOME: 384>, <TokenType.STORAGE_INTEGRATION: 388>, <TokenType.STRUCT: 390>, <TokenType.TAG: 393>, <TokenType.TEMPORARY: 394>, <TokenType.TOP: 395>, <TokenType.TRUE: 397>, <TokenType.TRUNCATE: 398>, <TokenType.TRIGGER: 399>, <TokenType.UNNEST: 402>, <TokenType.UNPIVOT: 403>, <TokenType.UPDATE: 404>, <TokenType.VIEW: 409>, <TokenType.SEMANTIC_VIEW: 410>, <TokenType.VOLATILE: 411>, <TokenType.UNIQUE: 416>, <TokenType.SINK: 423>, <TokenType.SOURCE: 424>, <TokenType.ANALYZE: 425>, <TokenType.NAMESPACE: 426>, <TokenType.EXPORT: 427>}
RANGE_PARSERS = {<TokenType.AT_GT: 53>: <function binary_range_parser.<locals>._parse_binary_range>, <TokenType.BETWEEN: 226>: <function Parser.<lambda>>, <TokenType.GLOB: 282>: <function binary_range_parser.<locals>._parse_binary_range>, <TokenType.ILIKE: 290>: <function binary_range_parser.<locals>._parse_binary_range>, <TokenType.IN: 291>: <function Parser.<lambda>>, <TokenType.IRLIKE: 301>: <function binary_range_parser.<locals>._parse_binary_range>, <TokenType.IS: 302>: <function Parser.<lambda>>, <TokenType.LIKE: 312>: <function binary_range_parser.<locals>._parse_binary_range>, <TokenType.LT_AT: 52>: <function binary_range_parser.<locals>._parse_binary_range>, <TokenType.OVERLAPS: 343>: <function binary_range_parser.<locals>._parse_binary_range>, <TokenType.RLIKE: 370>: <function binary_range_parser.<locals>._parse_binary_range>, <TokenType.SIMILAR_TO: 383>: <function binary_range_parser.<locals>._parse_binary_range>, <TokenType.FOR: 274>: <function Parser.<lambda>>, <TokenType.QMARK_AMP: 65>: <function binary_range_parser.<locals>._parse_binary_range>, <TokenType.QMARK_PIPE: 66>: <function binary_range_parser.<locals>._parse_binary_range>, <TokenType.HASH_DASH: 67>: <function binary_range_parser.<locals>._parse_binary_range>, <TokenType.ADJACENT: 62>: <function binary_range_parser.<locals>._parse_binary_range>, <TokenType.OPERATOR: 334>: <function Parser.<lambda>>, <TokenType.AMP_LT: 60>: <function binary_range_parser.<locals>._parse_binary_range>, <TokenType.AMP_GT: 61>: <function binary_range_parser.<locals>._parse_binary_range>, <TokenType.SOUNDS_LIKE: 386>: <function MySQL.Parser.<lambda>>, <TokenType.MEMBER_OF: 321>: <function MySQL.Parser.<lambda>>}
FUNCTIONS = {'AI_AGG': <bound method Func.from_arg_list of <class 'sqlglot.expressions.AIAgg'>>, 'AI_CLASSIFY': <bound method Func.from_arg_list of <class 'sqlglot.expressions.AIClassify'>>, 'AI_SUMMARIZE_AGG': <bound method Func.from_arg_list of <class 'sqlglot.expressions.AISummarizeAgg'>>, 'ABS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Abs'>>, 'ACOS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Acos'>>, 'ACOSH': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Acosh'>>, 'ADD_MONTHS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.AddMonths'>>, 'AND': <bound method Func.from_arg_list of <class 'sqlglot.expressions.And'>>, 'ANONYMOUS_AGG_FUNC': <bound method Func.from_arg_list of <class 'sqlglot.expressions.AnonymousAggFunc'>>, 'ANY_VALUE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.AnyValue'>>, 'APPLY': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Apply'>>, 'APPROX_DISTINCT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ApproxDistinct'>>, 'APPROX_COUNT_DISTINCT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ApproxDistinct'>>, 'APPROX_PERCENTILE_ACCUMULATE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ApproxPercentileAccumulate'>>, 'APPROX_PERCENTILE_COMBINE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ApproxPercentileCombine'>>, 'APPROX_PERCENTILE_ESTIMATE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ApproxPercentileEstimate'>>, 'APPROX_QUANTILE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ApproxQuantile'>>, 'APPROX_QUANTILES': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ApproxQuantiles'>>, 'APPROX_TOP_K': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ApproxTopK'>>, 'APPROX_TOP_K_ACCUMULATE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ApproxTopKAccumulate'>>, 'APPROX_TOP_K_COMBINE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ApproxTopKCombine'>>, 'APPROX_TOP_K_ESTIMATE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ApproxTopKEstimate'>>, 'APPROX_TOP_SUM': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ApproxTopSum'>>, 'APPROXIMATE_SIMILARITY': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ApproximateSimilarity'>>, 'APPROXIMATE_JACCARD_INDEX': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ApproximateSimilarity'>>, 'ARG_MAX': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArgMax'>>, 'ARGMAX': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArgMax'>>, 'MAX_BY': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArgMax'>>, 'ARG_MIN': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArgMin'>>, 'ARGMIN': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArgMin'>>, 'MIN_BY': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArgMin'>>, 'ARRAY': <function Parser.<lambda>>, 'ARRAY_AGG': <function Parser.<lambda>>, 'ARRAY_ALL': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArrayAll'>>, 'ARRAY_ANY': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArrayAny'>>, 'ARRAY_APPEND': <function build_array_append>, 'ARRAY_COMPACT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArrayCompact'>>, 'ARRAY_CONCAT': <function build_array_concat>, 'ARRAY_CAT': <function build_array_concat>, 'ARRAY_CONCAT_AGG': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArrayConcatAgg'>>, 'ARRAY_CONSTRUCT_COMPACT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArrayConstructCompact'>>, 'ARRAY_CONTAINS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArrayContains'>>, 'ARRAY_HAS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArrayContains'>>, 'ARRAY_CONTAINS_ALL': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArrayContainsAll'>>, 'ARRAY_HAS_ALL': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArrayContainsAll'>>, 'ARRAY_DISTINCT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArrayDistinct'>>, 'ARRAY_EXCEPT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArrayExcept'>>, 'FILTER': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArrayFilter'>>, 'ARRAY_FILTER': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArrayFilter'>>, 'ARRAY_FIRST': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArrayFirst'>>, 'ARRAY_INSERT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArrayInsert'>>, 'ARRAY_INTERSECT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArrayIntersect'>>, 'ARRAY_INTERSECTION': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArrayIntersect'>>, 'ARRAY_LAST': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArrayLast'>>, 'ARRAY_MAX': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArrayMax'>>, 'ARRAY_MIN': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArrayMin'>>, 'ARRAY_OVERLAPS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArrayOverlaps'>>, 'ARRAY_PREPEND': <function build_array_prepend>, 'ARRAY_REMOVE': <function build_array_remove>, 'ARRAY_REMOVE_AT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArrayRemoveAt'>>, 'ARRAY_REVERSE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArrayReverse'>>, 'ARRAY_SIZE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArraySize'>>, 'ARRAY_LENGTH': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArraySize'>>, 'ARRAY_SLICE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArraySlice'>>, 'ARRAY_SORT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArraySort'>>, 'ARRAY_SUM': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArraySum'>>, 'ARRAY_TO_STRING': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArrayToString'>>, 'ARRAY_JOIN': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArrayToString'>>, 'ARRAY_UNION_AGG': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArrayUnionAgg'>>, 'ARRAY_UNIQUE_AGG': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArrayUniqueAgg'>>, 'ARRAYS_ZIP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArraysZip'>>, 'ASCII': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Ascii'>>, 'ASIN': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Asin'>>, 'ASINH': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Asinh'>>, 'ATAN': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Atan'>>, 'ATAN2': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Atan2'>>, 'ATANH': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Atanh'>>, 'AVG': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Avg'>>, 'BASE64_DECODE_BINARY': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Base64DecodeBinary'>>, 'BASE64_DECODE_STRING': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Base64DecodeString'>>, 'BASE64_ENCODE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Base64Encode'>>, 'BIT_LENGTH': <bound method Func.from_arg_list of <class 'sqlglot.expressions.BitLength'>>, 'BITMAP_BIT_POSITION': <bound method Func.from_arg_list of <class 'sqlglot.expressions.BitmapBitPosition'>>, 'BITMAP_BUCKET_NUMBER': <bound method Func.from_arg_list of <class 'sqlglot.expressions.BitmapBucketNumber'>>, 'BITMAP_CONSTRUCT_AGG': <bound method Func.from_arg_list of <class 'sqlglot.expressions.BitmapConstructAgg'>>, 'BITMAP_COUNT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.BitmapCount'>>, 'BITMAP_OR_AGG': <bound method Func.from_arg_list of <class 'sqlglot.expressions.BitmapOrAgg'>>, 'BITWISE_AND_AGG': <bound method Func.from_arg_list of <class 'sqlglot.expressions.BitwiseAndAgg'>>, 'BITWISE_COUNT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.BitwiseCount'>>, 'BITWISE_OR_AGG': <bound method Func.from_arg_list of <class 'sqlglot.expressions.BitwiseOrAgg'>>, 'BITWISE_XOR_AGG': <bound method Func.from_arg_list of <class 'sqlglot.expressions.BitwiseXorAgg'>>, 'BOOLAND': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Booland'>>, 'BOOLNOT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Boolnot'>>, 'BOOLOR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Boolor'>>, 'BOOLXOR_AGG': <bound method Func.from_arg_list of <class 'sqlglot.expressions.BoolxorAgg'>>, 'BYTE_LENGTH': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ByteLength'>>, 'CASE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Case'>>, 'CAST': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Cast'>>, 'CAST_TO_STR_TYPE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CastToStrType'>>, 'CBRT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Cbrt'>>, 'CEIL': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Ceil'>>, 'CEILING': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Ceil'>>, 'CHECK_JSON': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CheckJson'>>, 'CHECK_XML': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CheckXml'>>, 'CHR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Chr'>>, 'CHAR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Chr'>>, 'COALESCE': <function build_coalesce>, 'IFNULL': <function build_coalesce>, 'NVL': <function build_coalesce>, 'CODE_POINTS_TO_BYTES': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CodePointsToBytes'>>, 'CODE_POINTS_TO_STRING': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CodePointsToString'>>, 'COLLATE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Collate'>>, 'COLLATION': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Collation'>>, 'COLUMNS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Columns'>>, 'COMBINED_AGG_FUNC': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CombinedAggFunc'>>, 'COMBINED_PARAMETERIZED_AGG': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CombinedParameterizedAgg'>>, 'COMPRESS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Compress'>>, 'CONCAT': <function Parser.<lambda>>, 'CONCAT_WS': <function Parser.<lambda>>, 'CONNECT_BY_ROOT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ConnectByRoot'>>, 'CONTAINS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Contains'>>, 'CONVERT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Convert'>>, 'CONVERT_TIMEZONE': <function build_convert_timezone>, 'CONVERT_TO_CHARSET': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ConvertToCharset'>>, 'CORR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Corr'>>, 'COS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Cos'>>, 'COSH': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Cosh'>>, 'COSINE_DISTANCE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CosineDistance'>>, 'COT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Cot'>>, 'COTH': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Coth'>>, 'COUNT': <function Parser.<lambda>>, 'COUNT_IF': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CountIf'>>, 'COUNTIF': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CountIf'>>, 'COVAR_POP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CovarPop'>>, 'COVAR_SAMP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CovarSamp'>>, 'CSC': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Csc'>>, 'CSCH': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Csch'>>, 'CUME_DIST': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CumeDist'>>, 'CURRENT_ACCOUNT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CurrentAccount'>>, 'CURRENT_ACCOUNT_NAME': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CurrentAccountName'>>, 'CURRENT_AVAILABLE_ROLES': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CurrentAvailableRoles'>>, 'CURRENT_CATALOG': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CurrentCatalog'>>, 'CURRENT_CLIENT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CurrentClient'>>, 'CURRENT_DATABASE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CurrentDatabase'>>, 'CURRENT_DATE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CurrentDate'>>, 'CURRENT_DATETIME': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CurrentDatetime'>>, 'CURRENT_IP_ADDRESS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CurrentIpAddress'>>, 'CURRENT_ORGANIZATION_NAME': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CurrentOrganizationName'>>, 'CURRENT_ORGANIZATION_USER': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CurrentOrganizationUser'>>, 'CURRENT_REGION': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CurrentRegion'>>, 'CURRENT_ROLE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CurrentRole'>>, 'CURRENT_ROLE_TYPE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CurrentRoleType'>>, 'CURRENT_SCHEMA': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CurrentSchema'>>, 'CURRENT_SCHEMAS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CurrentSchemas'>>, 'CURRENT_SECONDARY_ROLES': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CurrentSecondaryRoles'>>, 'CURRENT_SESSION': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CurrentSession'>>, 'CURRENT_STATEMENT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CurrentStatement'>>, 'CURRENT_TIME': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CurrentTime'>>, 'CURRENT_TIMESTAMP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CurrentTimestamp'>>, 'CURRENT_TIMESTAMP_L_T_Z': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CurrentTimestampLTZ'>>, 'CURRENT_TIMEZONE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CurrentTimezone'>>, 'CURRENT_TRANSACTION': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CurrentTransaction'>>, 'CURRENT_USER': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CurrentUser'>>, 'CURRENT_VERSION': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CurrentVersion'>>, 'CURRENT_WAREHOUSE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CurrentWarehouse'>>, 'DATE': <function MySQL.Parser.<lambda>>, 'DATE_ADD': <function build_date_delta_with_interval.<locals>._builder>, 'DATE_BIN': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DateBin'>>, 'DATEDIFF': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DateDiff'>>, 'DATE_DIFF': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DateDiff'>>, 'DATE_FROM_PARTS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DateFromParts'>>, 'DATEFROMPARTS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DateFromParts'>>, 'DATE_FROM_UNIX_DATE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DateFromUnixDate'>>, 'DATE_STR_TO_DATE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DateStrToDate'>>, 'DATE_SUB': <function build_date_delta_with_interval.<locals>._builder>, 'DATE_TO_DATE_STR': <function Parser.<lambda>>, 'DATE_TO_DI': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DateToDi'>>, 'DATE_TRUNC': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DateTrunc'>>, 'DATETIME': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Datetime'>>, 'DATETIME_ADD': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DatetimeAdd'>>, 'DATETIME_DIFF': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DatetimeDiff'>>, 'DATETIME_SUB': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DatetimeSub'>>, 'DATETIME_TRUNC': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DatetimeTrunc'>>, 'DAY': <function MySQL.Parser.<lambda>>, 'DAY_OF_MONTH': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DayOfMonth'>>, 'DAYOFMONTH': <function MySQL.Parser.<lambda>>, 'DAY_OF_WEEK': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DayOfWeek'>>, 'DAYOFWEEK': <function MySQL.Parser.<lambda>>, 'DAYOFWEEK_ISO': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DayOfWeekIso'>>, 'ISODOW': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DayOfWeekIso'>>, 'DAY_OF_YEAR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DayOfYear'>>, 'DAYOFYEAR': <function MySQL.Parser.<lambda>>, 'DAYNAME': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Dayname'>>, 'DECODE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Decode'>>, 'DECODE_CASE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DecodeCase'>>, 'DECOMPRESS_BINARY': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DecompressBinary'>>, 'DECOMPRESS_STRING': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DecompressString'>>, 'DECRYPT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Decrypt'>>, 'DECRYPT_RAW': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DecryptRaw'>>, 'DEGREES': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Degrees'>>, 'DENSE_RANK': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DenseRank'>>, 'DI_TO_DATE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DiToDate'>>, 'DOT_PRODUCT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DotProduct'>>, 'ELT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Elt'>>, 'ENCODE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Encode'>>, 'ENCRYPT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Encrypt'>>, 'ENCRYPT_RAW': <bound method Func.from_arg_list of <class 'sqlglot.expressions.EncryptRaw'>>, 'ENDS_WITH': <bound method Func.from_arg_list of <class 'sqlglot.expressions.EndsWith'>>, 'ENDSWITH': <bound method Func.from_arg_list of <class 'sqlglot.expressions.EndsWith'>>, 'EQUAL_NULL': <bound method Func.from_arg_list of <class 'sqlglot.expressions.EqualNull'>>, 'EUCLIDEAN_DISTANCE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.EuclideanDistance'>>, 'EXISTS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Exists'>>, 'EXP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Exp'>>, 'EXPLODE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Explode'>>, 'EXPLODE_OUTER': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ExplodeOuter'>>, 'EXPLODING_GENERATE_SERIES': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ExplodingGenerateSeries'>>, 'EXTRACT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Extract'>>, 'FACTORIAL': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Factorial'>>, 'FARM_FINGERPRINT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.FarmFingerprint'>>, 'FARMFINGERPRINT64': <bound method Func.from_arg_list of <class 'sqlglot.expressions.FarmFingerprint'>>, 'FEATURES_AT_TIME': <bound method Func.from_arg_list of <class 'sqlglot.expressions.FeaturesAtTime'>>, 'FIRST': <bound method Func.from_arg_list of <class 'sqlglot.expressions.First'>>, 'FIRST_VALUE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.FirstValue'>>, 'FLATTEN': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Flatten'>>, 'FLOAT64': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Float64'>>, 'FLOOR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Floor'>>, 'FORMAT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.NumberToStr'>>, 'FROM_BASE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.FromBase'>>, 'FROM_BASE32': <bound method Func.from_arg_list of <class 'sqlglot.expressions.FromBase32'>>, 'FROM_BASE64': <bound method Func.from_arg_list of <class 'sqlglot.expressions.FromBase64'>>, 'FROM_ISO8601_TIMESTAMP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.FromISO8601Timestamp'>>, 'GAP_FILL': <bound method Func.from_arg_list of <class 'sqlglot.expressions.GapFill'>>, 'GENERATE_DATE_ARRAY': <function Parser.<lambda>>, 'GENERATE_EMBEDDING': <bound method Func.from_arg_list of <class 'sqlglot.expressions.GenerateEmbedding'>>, 'GENERATE_SERIES': <bound method Func.from_arg_list of <class 'sqlglot.expressions.GenerateSeries'>>, 'GENERATE_TIMESTAMP_ARRAY': <bound method Func.from_arg_list of <class 'sqlglot.expressions.GenerateTimestampArray'>>, 'GENERATOR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Generator'>>, 'GET_EXTRACT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.GetExtract'>>, 'GETBIT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Getbit'>>, 'GET_BIT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Getbit'>>, 'GREATEST': <function Parser.<lambda>>, 'GROUP_CONCAT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.GroupConcat'>>, 'GROUPING': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Grouping'>>, 'GROUPING_ID': <bound method Func.from_arg_list of <class 'sqlglot.expressions.GroupingId'>>, 'HASH_AGG': <bound method Func.from_arg_list of <class 'sqlglot.expressions.HashAgg'>>, 'HEX': <function build_hex>, 'HEX_DECODE_STRING': <bound method Func.from_arg_list of <class 'sqlglot.expressions.HexDecodeString'>>, 'HEX_ENCODE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.HexEncode'>>, 'HLL': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Hll'>>, 'HOST': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Host'>>, 'HOUR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Hour'>>, 'IF': <bound method Func.from_arg_list of <class 'sqlglot.expressions.If'>>, 'IIF': <bound method Func.from_arg_list of <class 'sqlglot.expressions.If'>>, 'INITCAP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Initcap'>>, 'INLINE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Inline'>>, 'INT64': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Int64'>>, 'IS_ARRAY': <bound method Func.from_arg_list of <class 'sqlglot.expressions.IsArray'>>, 'IS_ASCII': <bound method Func.from_arg_list of <class 'sqlglot.expressions.IsAscii'>>, 'IS_INF': <bound method Func.from_arg_list of <class 'sqlglot.expressions.IsInf'>>, 'ISINF': <bound method Func.from_arg_list of <class 'sqlglot.expressions.IsInf'>>, 'IS_NAN': <bound method Func.from_arg_list of <class 'sqlglot.expressions.IsNan'>>, 'ISNAN': <bound method Func.from_arg_list of <class 'sqlglot.expressions.IsNan'>>, 'IS_NULL_VALUE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.IsNullValue'>>, 'J_S_O_N_ARRAY': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONArray'>>, 'J_S_O_N_ARRAY_AGG': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONArrayAgg'>>, 'JSON_ARRAY_APPEND': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONArrayAppend'>>, 'JSON_ARRAY_CONTAINS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONArrayContains'>>, 'JSON_ARRAY_INSERT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONArrayInsert'>>, 'JSONB_CONTAINS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONBContains'>>, 'J_S_O_N_B_CONTAINS_ALL_TOP_KEYS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONBContainsAllTopKeys'>>, 'J_S_O_N_B_CONTAINS_ANY_TOP_KEYS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONBContainsAnyTopKeys'>>, 'J_S_O_N_B_DELETE_AT_PATH': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONBDeleteAtPath'>>, 'JSONB_EXISTS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONBExists'>>, 'JSONB_EXTRACT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONBExtract'>>, 'JSONB_EXTRACT_SCALAR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONBExtractScalar'>>, 'J_S_O_N_B_OBJECT_AGG': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONBObjectAgg'>>, 'J_S_O_N_BOOL': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONBool'>>, 'J_S_O_N_CAST': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONCast'>>, 'J_S_O_N_EXISTS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONExists'>>, 'JSON_EXTRACT': <function build_extract_json_with_path.<locals>._builder>, 'JSON_EXTRACT_ARRAY': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONExtractArray'>>, 'JSON_EXTRACT_SCALAR': <function build_extract_json_with_path.<locals>._builder>, 'JSON_FORMAT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONFormat'>>, 'JSON_KEYS': <function Parser.<lambda>>, 'J_S_O_N_KEYS_AT_DEPTH': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONKeysAtDepth'>>, 'J_S_O_N_OBJECT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONObject'>>, 'J_S_O_N_OBJECT_AGG': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONObjectAgg'>>, 'JSON_REMOVE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONRemove'>>, 'JSON_SET': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONSet'>>, 'JSON_STRIP_NULLS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONStripNulls'>>, 'J_S_O_N_TABLE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONTable'>>, 'JSON_TYPE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONType'>>, 'J_S_O_N_VALUE_ARRAY': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONValueArray'>>, 'JAROWINKLER_SIMILARITY': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JarowinklerSimilarity'>>, 'JUSTIFY_DAYS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JustifyDays'>>, 'JUSTIFY_HOURS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JustifyHours'>>, 'JUSTIFY_INTERVAL': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JustifyInterval'>>, 'KURTOSIS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Kurtosis'>>, 'LAG': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Lag'>>, 'LAST': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Last'>>, 'LAST_DAY': <bound method Func.from_arg_list of <class 'sqlglot.expressions.LastDay'>>, 'LAST_DAY_OF_MONTH': <bound method Func.from_arg_list of <class 'sqlglot.expressions.LastDay'>>, 'LAST_VALUE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.LastValue'>>, 'LAX_BOOL': <bound method Func.from_arg_list of <class 'sqlglot.expressions.LaxBool'>>, 'LAX_FLOAT64': <bound method Func.from_arg_list of <class 'sqlglot.expressions.LaxFloat64'>>, 'LAX_INT64': <bound method Func.from_arg_list of <class 'sqlglot.expressions.LaxInt64'>>, 'LAX_STRING': <bound method Func.from_arg_list of <class 'sqlglot.expressions.LaxString'>>, 'LEAD': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Lead'>>, 'LEAST': <function Parser.<lambda>>, 'LEFT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Left'>>, 'LENGTH': <function MySQL.Parser.<lambda>>, 'LEN': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Length'>>, 'CHAR_LENGTH': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Length'>>, 'CHARACTER_LENGTH': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Length'>>, 'LEVENSHTEIN': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Levenshtein'>>, 'LIST': <bound method Func.from_arg_list of <class 'sqlglot.expressions.List'>>, 'LN': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Ln'>>, 'LOCALTIME': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Localtime'>>, 'LOCALTIMESTAMP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Localtimestamp'>>, 'LOG': <function build_logarithm>, 'LOGICAL_AND': <bound method Func.from_arg_list of <class 'sqlglot.expressions.LogicalAnd'>>, 'BOOL_AND': <bound method Func.from_arg_list of <class 'sqlglot.expressions.LogicalAnd'>>, 'BOOLAND_AGG': <bound method Func.from_arg_list of <class 'sqlglot.expressions.LogicalAnd'>>, 'LOGICAL_OR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.LogicalOr'>>, 'BOOL_OR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.LogicalOr'>>, 'BOOLOR_AGG': <bound method Func.from_arg_list of <class 'sqlglot.expressions.LogicalOr'>>, 'LOWER': <function build_lower>, 'LCASE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Lower'>>, 'LOWER_HEX': <bound method Func.from_arg_list of <class 'sqlglot.expressions.LowerHex'>>, 'MD5': <bound method Func.from_arg_list of <class 'sqlglot.expressions.MD5'>>, 'MD5_DIGEST': <bound method Func.from_arg_list of <class 'sqlglot.expressions.MD5Digest'>>, 'M_D5_NUMBER_LOWER64': <bound method Func.from_arg_list of <class 'sqlglot.expressions.MD5NumberLower64'>>, 'M_D5_NUMBER_UPPER64': <bound method Func.from_arg_list of <class 'sqlglot.expressions.MD5NumberUpper64'>>, 'M_L_FORECAST': <bound method Func.from_arg_list of <class 'sqlglot.expressions.MLForecast'>>, 'M_L_TRANSLATE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.MLTranslate'>>, 'MAKE_INTERVAL': <bound method Func.from_arg_list of <class 'sqlglot.expressions.MakeInterval'>>, 'MANHATTAN_DISTANCE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ManhattanDistance'>>, 'MAP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Map'>>, 'MAP_CAT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.MapCat'>>, 'MAP_CONTAINS_KEY': <bound method Func.from_arg_list of <class 'sqlglot.expressions.MapContainsKey'>>, 'MAP_DELETE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.MapDelete'>>, 'MAP_FROM_ENTRIES': <bound method Func.from_arg_list of <class 'sqlglot.expressions.MapFromEntries'>>, 'MAP_INSERT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.MapInsert'>>, 'MAP_KEYS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.MapKeys'>>, 'MAP_PICK': <bound method Func.from_arg_list of <class 'sqlglot.expressions.MapPick'>>, 'MAP_SIZE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.MapSize'>>, 'MATCH_AGAINST': <bound method Func.from_arg_list of <class 'sqlglot.expressions.MatchAgainst'>>, 'MAX': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Max'>>, 'MEDIAN': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Median'>>, 'MIN': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Min'>>, 'MINHASH': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Minhash'>>, 'MINHASH_COMBINE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.MinhashCombine'>>, 'MINUTE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Minute'>>, 'MODE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Mode'>>, 'MONTH': <function MySQL.Parser.<lambda>>, 'MONTHNAME': <function MySQL.Parser.<lambda>>, 'MONTHS_BETWEEN': <bound method Func.from_arg_list of <class 'sqlglot.expressions.MonthsBetween'>>, 'NET_FUNC': <bound method Func.from_arg_list of <class 'sqlglot.expressions.NetFunc'>>, 'NEXT_DAY': <bound method Func.from_arg_list of <class 'sqlglot.expressions.NextDay'>>, 'NEXT_VALUE_FOR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.NextValueFor'>>, 'NORMAL': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Normal'>>, 'NORMALIZE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Normalize'>>, 'NTH_VALUE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.NthValue'>>, 'NTILE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Ntile'>>, 'NULLIF': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Nullif'>>, 'NUMBER_TO_STR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.NumberToStr'>>, 'NVL2': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Nvl2'>>, 'OBJECT_AGG': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ObjectAgg'>>, 'OBJECT_ID': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ObjectId'>>, 'OBJECT_INSERT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ObjectInsert'>>, 'OPEN_J_S_O_N': <bound method Func.from_arg_list of <class 'sqlglot.expressions.OpenJSON'>>, 'OR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Or'>>, 'OVERLAY': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Overlay'>>, 'PAD': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Pad'>>, 'PARAMETERIZED_AGG': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ParameterizedAgg'>>, 'PARSE_BIGNUMERIC': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ParseBignumeric'>>, 'PARSE_DATETIME': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ParseDatetime'>>, 'PARSE_IP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ParseIp'>>, 'PARSE_JSON': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ParseJSON'>>, 'JSON_PARSE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ParseJSON'>>, 'PARSE_NUMERIC': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ParseNumeric'>>, 'PARSE_TIME': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ParseTime'>>, 'PARSE_URL': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ParseUrl'>>, 'PERCENT_RANK': <bound method Func.from_arg_list of <class 'sqlglot.expressions.PercentRank'>>, 'PERCENTILE_CONT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.PercentileCont'>>, 'PERCENTILE_DISC': <bound method Func.from_arg_list of <class 'sqlglot.expressions.PercentileDisc'>>, 'PI': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Pi'>>, 'POSEXPLODE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Posexplode'>>, 'POSEXPLODE_OUTER': <bound method Func.from_arg_list of <class 'sqlglot.expressions.PosexplodeOuter'>>, 'POWER': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Pow'>>, 'POW': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Pow'>>, 'PREDICT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Predict'>>, 'PREVIOUS_DAY': <bound method Func.from_arg_list of <class 'sqlglot.expressions.PreviousDay'>>, 'QUANTILE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Quantile'>>, 'QUARTER': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Quarter'>>, 'RADIANS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Radians'>>, 'RAND': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Rand'>>, 'RANDOM': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Rand'>>, 'RANDN': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Randn'>>, 'RANDSTR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Randstr'>>, 'RANGE_BUCKET': <bound method Func.from_arg_list of <class 'sqlglot.expressions.RangeBucket'>>, 'RANGE_N': <bound method Func.from_arg_list of <class 'sqlglot.expressions.RangeN'>>, 'RANK': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Rank'>>, 'READ_CSV': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ReadCSV'>>, 'READ_PARQUET': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ReadParquet'>>, 'REDUCE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Reduce'>>, 'REG_DOMAIN': <bound method Func.from_arg_list of <class 'sqlglot.expressions.RegDomain'>>, 'REGEXP_COUNT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.RegexpCount'>>, 'REGEXP_EXTRACT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.RegexpExtract'>>, 'REGEXP_EXTRACT_ALL': <bound method Func.from_arg_list of <class 'sqlglot.expressions.RegexpExtractAll'>>, 'REGEXP_FULL_MATCH': <bound method Func.from_arg_list of <class 'sqlglot.expressions.RegexpFullMatch'>>, 'REGEXP_I_LIKE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.RegexpILike'>>, 'REGEXP_INSTR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.RegexpInstr'>>, 'REGEXP_LIKE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.RegexpLike'>>, 'REGEXP_REPLACE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.RegexpReplace'>>, 'REGEXP_SPLIT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.RegexpSplit'>>, 'REGR_AVGX': <bound method Func.from_arg_list of <class 'sqlglot.expressions.RegrAvgx'>>, 'REGR_AVGY': <bound method Func.from_arg_list of <class 'sqlglot.expressions.RegrAvgy'>>, 'REGR_COUNT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.RegrCount'>>, 'REGR_INTERCEPT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.RegrIntercept'>>, 'REGR_R2': <bound method Func.from_arg_list of <class 'sqlglot.expressions.RegrR2'>>, 'REGR_SLOPE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.RegrSlope'>>, 'REGR_SXX': <bound method Func.from_arg_list of <class 'sqlglot.expressions.RegrSxx'>>, 'REGR_SXY': <bound method Func.from_arg_list of <class 'sqlglot.expressions.RegrSxy'>>, 'REGR_SYY': <bound method Func.from_arg_list of <class 'sqlglot.expressions.RegrSyy'>>, 'REGR_VALX': <bound method Func.from_arg_list of <class 'sqlglot.expressions.RegrValx'>>, 'REGR_VALY': <bound method Func.from_arg_list of <class 'sqlglot.expressions.RegrValy'>>, 'REPEAT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Repeat'>>, 'REPLACE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Replace'>>, 'REVERSE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Reverse'>>, 'RIGHT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Right'>>, 'ROUND': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Round'>>, 'ROW_NUMBER': <bound method Func.from_arg_list of <class 'sqlglot.expressions.RowNumber'>>, 'RTRIMMED_LENGTH': <bound method Func.from_arg_list of <class 'sqlglot.expressions.RtrimmedLength'>>, 'SHA': <bound method Func.from_arg_list of <class 'sqlglot.expressions.SHA'>>, 'SHA1': <bound method Func.from_arg_list of <class 'sqlglot.expressions.SHA'>>, 'S_H_A1_DIGEST': <bound method Func.from_arg_list of <class 'sqlglot.expressions.SHA1Digest'>>, 'SHA2': <bound method Func.from_arg_list of <class 'sqlglot.expressions.SHA2'>>, 'S_H_A2_DIGEST': <bound method Func.from_arg_list of <class 'sqlglot.expressions.SHA2Digest'>>, 'SAFE_ADD': <bound method Func.from_arg_list of <class 'sqlglot.expressions.SafeAdd'>>, 'SAFE_CONVERT_BYTES_TO_STRING': <bound method Func.from_arg_list of <class 'sqlglot.expressions.SafeConvertBytesToString'>>, 'SAFE_DIVIDE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.SafeDivide'>>, 'SAFE_FUNC': <bound method Func.from_arg_list of <class 'sqlglot.expressions.SafeFunc'>>, 'SAFE_MULTIPLY': <bound method Func.from_arg_list of <class 'sqlglot.expressions.SafeMultiply'>>, 'SAFE_NEGATE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.SafeNegate'>>, 'SAFE_SUBTRACT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.SafeSubtract'>>, 'SEARCH': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Search'>>, 'SEARCH_IP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.SearchIp'>>, 'SEC': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Sec'>>, 'SECH': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Sech'>>, 'SECOND': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Second'>>, 'SEQ1': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Seq1'>>, 'SEQ2': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Seq2'>>, 'SEQ4': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Seq4'>>, 'SEQ8': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Seq8'>>, 'SESSION_USER': <bound method Func.from_arg_list of <class 'sqlglot.expressions.SessionUser'>>, 'SIGN': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Sign'>>, 'SIGNUM': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Sign'>>, 'SIN': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Sin'>>, 'SINH': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Sinh'>>, 'SKEWNESS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Skewness'>>, 'SORT_ARRAY': <bound method Func.from_arg_list of <class 'sqlglot.expressions.SortArray'>>, 'SOUNDEX': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Soundex'>>, 'SOUNDEX_P123': <bound method Func.from_arg_list of <class 'sqlglot.expressions.SoundexP123'>>, 'SPACE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Space'>>, 'SPLIT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Split'>>, 'SPLIT_PART': <bound method Func.from_arg_list of <class 'sqlglot.expressions.SplitPart'>>, 'SQRT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Sqrt'>>, 'ST_DISTANCE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StDistance'>>, 'ST_POINT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StPoint'>>, 'ST_MAKEPOINT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StPoint'>>, 'STANDARD_HASH': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StandardHash'>>, 'STAR_MAP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StarMap'>>, 'STARTS_WITH': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StartsWith'>>, 'STARTSWITH': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StartsWith'>>, 'STDDEV': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Stddev'>>, 'STDEV': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Stddev'>>, 'STDDEV_POP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StddevPop'>>, 'STDDEV_SAMP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StddevSamp'>>, 'STR_POSITION': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StrPosition'>>, 'STR_TO_DATE': <function _str_to_date>, 'STR_TO_MAP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StrToMap'>>, 'STR_TO_TIME': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StrToTime'>>, 'STR_TO_UNIX': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StrToUnix'>>, 'STRING': <bound method Func.from_arg_list of <class 'sqlglot.expressions.String'>>, 'STRING_TO_ARRAY': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StringToArray'>>, 'SPLIT_BY_STRING': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StringToArray'>>, 'STRTOK_TO_ARRAY': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StringToArray'>>, 'STRUCT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Struct'>>, 'STRUCT_EXTRACT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StructExtract'>>, 'STUFF': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Stuff'>>, 'INSERT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Stuff'>>, 'SUBSTRING': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Substring'>>, 'SUBSTR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Substring'>>, 'SUBSTRING_INDEX': <bound method Func.from_arg_list of <class 'sqlglot.expressions.SubstringIndex'>>, 'SUM': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Sum'>>, 'SYSTIMESTAMP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Systimestamp'>>, 'TAN': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Tan'>>, 'TANH': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Tanh'>>, 'TIME': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Time'>>, 'TIME_ADD': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimeAdd'>>, 'TIME_DIFF': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimeDiff'>>, 'TIME_FROM_PARTS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimeFromParts'>>, 'TIMEFROMPARTS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimeFromParts'>>, 'TIME_SLICE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimeSlice'>>, 'TIME_STR_TO_DATE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimeStrToDate'>>, 'TIME_STR_TO_TIME': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimeStrToTime'>>, 'TIME_STR_TO_UNIX': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimeStrToUnix'>>, 'TIME_SUB': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimeSub'>>, 'TIME_TO_STR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimeToStr'>>, 'TIME_TO_TIME_STR': <function Parser.<lambda>>, 'TIME_TO_UNIX': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimeToUnix'>>, 'TIME_TRUNC': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimeTrunc'>>, 'TIMESTAMP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Timestamp'>>, 'TIMESTAMP_ADD': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimestampAdd'>>, 'TIMESTAMPDIFF': <function build_date_delta.<locals>._builder>, 'TIMESTAMP_DIFF': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimestampDiff'>>, 'TIMESTAMP_FROM_PARTS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimestampFromParts'>>, 'TIMESTAMPFROMPARTS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimestampFromParts'>>, 'TIMESTAMP_LTZ_FROM_PARTS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimestampLtzFromParts'>>, 'TIMESTAMPLTZFROMPARTS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimestampLtzFromParts'>>, 'TIMESTAMP_SUB': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimestampSub'>>, 'TIMESTAMP_TRUNC': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimestampTrunc'>>, 'TIMESTAMP_TZ_FROM_PARTS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimestampTzFromParts'>>, 'TIMESTAMPTZFROMPARTS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimestampTzFromParts'>>, 'TO_ARRAY': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ToArray'>>, 'TO_BASE32': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ToBase32'>>, 'TO_BASE64': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ToBase64'>>, 'TO_BINARY': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ToBinary'>>, 'TO_BOOLEAN': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ToBoolean'>>, 'TO_CHAR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ToChar'>>, 'TO_CODE_POINTS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ToCodePoints'>>, 'TO_DAYS': <function MySQL.Parser.<lambda>>, 'TO_DECFLOAT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ToDecfloat'>>, 'TO_DOUBLE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ToDouble'>>, 'TO_FILE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ToFile'>>, 'TO_MAP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ToMap'>>, 'TO_NUMBER': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ToNumber'>>, 'TRANSFORM': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Transform'>>, 'TRANSLATE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Translate'>>, 'TRIM': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Trim'>>, 'TRUNC': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Trunc'>>, 'TRUNCATE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Trunc'>>, 'TRY': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Try'>>, 'TRY_BASE64_DECODE_BINARY': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TryBase64DecodeBinary'>>, 'TRY_BASE64_DECODE_STRING': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TryBase64DecodeString'>>, 'TRY_CAST': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TryCast'>>, 'TRY_HEX_DECODE_BINARY': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TryHexDecodeBinary'>>, 'TRY_HEX_DECODE_STRING': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TryHexDecodeString'>>, 'TRY_TO_DECFLOAT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TryToDecfloat'>>, 'TS_OR_DI_TO_DI': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TsOrDiToDi'>>, 'TS_OR_DS_ADD': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TsOrDsAdd'>>, 'TS_OR_DS_DIFF': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TsOrDsDiff'>>, 'TS_OR_DS_TO_DATE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TsOrDsToDate'>>, 'TS_OR_DS_TO_DATE_STR': <function Parser.<lambda>>, 'TS_OR_DS_TO_DATETIME': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TsOrDsToDatetime'>>, 'TS_OR_DS_TO_TIME': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TsOrDsToTime'>>, 'TS_OR_DS_TO_TIMESTAMP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TsOrDsToTimestamp'>>, 'TYPEOF': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Typeof'>>, 'UNHEX': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Unhex'>>, 'UNICODE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Unicode'>>, 'UNIFORM': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Uniform'>>, 'UNIX_DATE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.UnixDate'>>, 'UNIX_MICROS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.UnixMicros'>>, 'UNIX_MILLIS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.UnixMillis'>>, 'UNIX_SECONDS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.UnixSeconds'>>, 'UNIX_TO_STR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.UnixToStr'>>, 'UNIX_TO_TIME': <bound method Func.from_arg_list of <class 'sqlglot.expressions.UnixToTime'>>, 'UNIX_TO_TIME_STR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.UnixToTimeStr'>>, 'UNNEST': <function Parser.<lambda>>, 'UPPER': <function build_upper>, 'UCASE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Upper'>>, 'UTC_DATE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.UtcDate'>>, 'UTC_TIME': <bound method Func.from_arg_list of <class 'sqlglot.expressions.UtcTime'>>, 'UTC_TIMESTAMP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.UtcTimestamp'>>, 'UUID': <function Parser.<lambda>>, 'GEN_RANDOM_UUID': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Uuid'>>, 'GENERATE_UUID': <function Parser.<lambda>>, 'UUID_STRING': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Uuid'>>, 'VAR_MAP': <function build_var_map>, 'VARIANCE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Variance'>>, 'VARIANCE_SAMP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Variance'>>, 'VAR_SAMP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Variance'>>, 'VARIANCE_POP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.VariancePop'>>, 'VAR_POP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.VariancePop'>>, 'VECTOR_SEARCH': <bound method Func.from_arg_list of <class 'sqlglot.expressions.VectorSearch'>>, 'WEEK': <function MySQL.Parser.<lambda>>, 'WEEK_OF_YEAR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.WeekOfYear'>>, 'WEEKOFYEAR': <function MySQL.Parser.<lambda>>, 'WIDTH_BUCKET': <bound method Func.from_arg_list of <class 'sqlglot.expressions.WidthBucket'>>, 'XMLELEMENT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.XMLElement'>>, 'XMLGET': <bound method Func.from_arg_list of <class 'sqlglot.expressions.XMLGet'>>, 'X_M_L_TABLE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.XMLTable'>>, 'XOR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Xor'>>, 'YEAR': <function MySQL.Parser.<lambda>>, 'YEAR_OF_WEEK': <bound method Func.from_arg_list of <class 'sqlglot.expressions.YearOfWeek'>>, 'YEAROFWEEK': <bound method Func.from_arg_list of <class 'sqlglot.expressions.YearOfWeek'>>, 'YEAR_OF_WEEK_ISO': <bound method Func.from_arg_list of <class 'sqlglot.expressions.YearOfWeekIso'>>, 'YEAROFWEEKISO': <bound method Func.from_arg_list of <class 'sqlglot.expressions.YearOfWeekIso'>>, 'ZIPF': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Zipf'>>, 'ARRAYAGG': <function Parser.<lambda>>, 'GLOB': <function Parser.<lambda>>, 'JSON_EXTRACT_PATH_TEXT': <function build_extract_json_with_path.<locals>._builder>, 'LIKE': <function build_like>, 'LOG2': <function Parser.<lambda>>, 'LOG10': <function Parser.<lambda>>, 'LPAD': <function Parser.<lambda>>, 'LEFTPAD': <function Parser.<lambda>>, 'LTRIM': <function Parser.<lambda>>, 'MOD': <function build_mod>, 'RIGHTPAD': <function Parser.<lambda>>, 'RPAD': <function Parser.<lambda>>, 'RTRIM': <function Parser.<lambda>>, 'SCOPE_RESOLUTION': <function Parser.<lambda>>, 'STRPOS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StrPosition'>>, 'CHARINDEX': <function Parser.<lambda>>, 'INSTR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StrPosition'>>, 'LOCATE': <function Parser.<lambda>>, 'TO_HEX': <function build_hex>, 'BIT_AND': <bound method Func.from_arg_list of <class 'sqlglot.expressions.BitwiseAndAgg'>>, 'BIT_OR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.BitwiseOrAgg'>>, 'BIT_XOR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.BitwiseXorAgg'>>, 'BIT_COUNT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.BitwiseCount'>>, 'CONVERT_TZ': <function MySQL.Parser.<lambda>>, 'CURDATE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CurrentDate'>>, 'CURTIME': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CurrentTime'>>, 'DATE_FORMAT': <function build_formatted_time.<locals>._builder>, 'FROM_UNIXTIME': <function build_formatted_time.<locals>._builder>, 'ISNULL': <function isnull_to_is_null>, 'MAKETIME': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimeFromParts'>>, 'SCHEMA': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CurrentSchema'>>, 'DATABASE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CurrentSchema'>>, 'VERSION': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CurrentVersion'>>}
FUNCTION_PARSERS = {'ARG_MAX': <function Parser.<dictcomp>.<lambda>>, 'ARGMAX': <function Parser.<dictcomp>.<lambda>>, 'MAX_BY': <function Parser.<dictcomp>.<lambda>>, 'ARG_MIN': <function Parser.<dictcomp>.<lambda>>, 'ARGMIN': <function Parser.<dictcomp>.<lambda>>, 'MIN_BY': <function Parser.<dictcomp>.<lambda>>, 'CAST': <function Parser.<lambda>>, 'CEIL': <function Parser.<lambda>>, 'CONVERT': <function Parser.<lambda>>, 'CHAR': <function Parser.<lambda>>, 'CHR': <function Parser.<lambda>>, 'DECODE': <function Parser.<lambda>>, 'EXTRACT': <function Parser.<lambda>>, 'FLOOR': <function Parser.<lambda>>, 'GAP_FILL': <function Parser.<lambda>>, 'INITCAP': <function Parser.<lambda>>, 'JSON_OBJECT': <function Parser.<lambda>>, 'JSON_OBJECTAGG': <function Parser.<lambda>>, 'JSON_TABLE': <function Parser.<lambda>>, 'MATCH': <function Parser.<lambda>>, 'NORMALIZE': <function Parser.<lambda>>, 'OPENJSON': <function Parser.<lambda>>, 'OVERLAY': <function Parser.<lambda>>, 'POSITION': <function Parser.<lambda>>, 'SAFE_CAST': <function Parser.<lambda>>, 'STRING_AGG': <function Parser.<lambda>>, 'SUBSTRING': <function Parser.<lambda>>, 'TRIM': <function Parser.<lambda>>, 'TRY_CAST': <function Parser.<lambda>>, 'TRY_CONVERT': <function Parser.<lambda>>, 'XMLELEMENT': <function Parser.<lambda>>, 'XMLTABLE': <function Parser.<lambda>>, 'GROUP_CONCAT': <function MySQL.Parser.<lambda>>, 'VALUES': <function MySQL.Parser.<lambda>>, 'JSON_VALUE': <function MySQL.Parser.<lambda>>, 'SUBSTR': <function MySQL.Parser.<lambda>>}
STATEMENT_PARSERS = {<TokenType.ALTER: 215>: <function Parser.<lambda>>, <TokenType.ANALYZE: 425>: <function Parser.<lambda>>, <TokenType.BEGIN: 225>: <function Parser.<lambda>>, <TokenType.CACHE: 228>: <function Parser.<lambda>>, <TokenType.COMMENT: 234>: <function Parser.<lambda>>, <TokenType.COMMIT: 235>: <function Parser.<lambda>>, <TokenType.COPY: 238>: <function Parser.<lambda>>, <TokenType.CREATE: 239>: <function Parser.<lambda>>, <TokenType.DELETE: 252>: <function Parser.<lambda>>, <TokenType.DESC: 253>: <function Parser.<lambda>>, <TokenType.DESCRIBE: 254>: <function Parser.<lambda>>, <TokenType.DROP: 260>: <function Parser.<lambda>>, <TokenType.GRANT: 284>: <function Parser.<lambda>>, <TokenType.REVOKE: 367>: <function Parser.<lambda>>, <TokenType.INSERT: 295>: <function Parser.<lambda>>, <TokenType.KILL: 308>: <function Parser.<lambda>>, <TokenType.LOAD: 315>: <function Parser.<lambda>>, <TokenType.MERGE: 322>: <function Parser.<lambda>>, <TokenType.PIVOT: 348>: <function Parser.<lambda>>, <TokenType.PRAGMA: 351>: <function Parser.<lambda>>, <TokenType.REFRESH: 363>: <function Parser.<lambda>>, <TokenType.ROLLBACK: 371>: <function Parser.<lambda>>, <TokenType.SET: 380>: <function Parser.<lambda>>, <TokenType.TRUNCATE: 398>: <function Parser.<lambda>>, <TokenType.UNCACHE: 400>: <function Parser.<lambda>>, <TokenType.UNPIVOT: 403>: <function Parser.<lambda>>, <TokenType.UPDATE: 404>: <function Parser.<lambda>>, <TokenType.USE: 405>: <function Parser.<lambda>>, <TokenType.SEMICOLON: 18>: <function Parser.<lambda>>, <TokenType.SHOW: 382>: <function MySQL.Parser.<lambda>>}
SHOW_PARSERS = {'BINARY LOGS': <function _show_parser.<locals>._parse>, 'MASTER LOGS': <function _show_parser.<locals>._parse>, 'BINLOG EVENTS': <function _show_parser.<locals>._parse>, 'CHARACTER SET': <function _show_parser.<locals>._parse>, 'CHARSET': <function _show_parser.<locals>._parse>, 'COLLATION': <function _show_parser.<locals>._parse>, 'FULL COLUMNS': <function _show_parser.<locals>._parse>, 'COLUMNS': <function _show_parser.<locals>._parse>, 'CREATE DATABASE': <function _show_parser.<locals>._parse>, 'CREATE EVENT': <function _show_parser.<locals>._parse>, 'CREATE FUNCTION': <function _show_parser.<locals>._parse>, 'CREATE PROCEDURE': <function _show_parser.<locals>._parse>, 'CREATE TABLE': <function _show_parser.<locals>._parse>, 'CREATE TRIGGER': <function _show_parser.<locals>._parse>, 'CREATE VIEW': <function _show_parser.<locals>._parse>, 'DATABASES': <function _show_parser.<locals>._parse>, 'SCHEMAS': <function _show_parser.<locals>._parse>, 'ENGINE': <function _show_parser.<locals>._parse>, 'STORAGE ENGINES': <function _show_parser.<locals>._parse>, 'ENGINES': <function _show_parser.<locals>._parse>, 'ERRORS': <function _show_parser.<locals>._parse>, 'EVENTS': <function _show_parser.<locals>._parse>, 'FUNCTION CODE': <function _show_parser.<locals>._parse>, 'FUNCTION STATUS': <function _show_parser.<locals>._parse>, 'GRANTS': <function _show_parser.<locals>._parse>, 'INDEX': <function _show_parser.<locals>._parse>, 'MASTER STATUS': <function _show_parser.<locals>._parse>, 'OPEN TABLES': <function _show_parser.<locals>._parse>, 'PLUGINS': <function _show_parser.<locals>._parse>, 'PROCEDURE CODE': <function _show_parser.<locals>._parse>, 'PROCEDURE STATUS': <function _show_parser.<locals>._parse>, 'PRIVILEGES': <function _show_parser.<locals>._parse>, 'FULL PROCESSLIST': <function _show_parser.<locals>._parse>, 'PROCESSLIST': <function _show_parser.<locals>._parse>, 'PROFILE': <function _show_parser.<locals>._parse>, 'PROFILES': <function _show_parser.<locals>._parse>, 'RELAYLOG EVENTS': <function _show_parser.<locals>._parse>, 'REPLICAS': <function _show_parser.<locals>._parse>, 'SLAVE HOSTS': <function _show_parser.<locals>._parse>, 'REPLICA STATUS': <function _show_parser.<locals>._parse>, 'SLAVE STATUS': <function _show_parser.<locals>._parse>, 'GLOBAL STATUS': <function _show_parser.<locals>._parse>, 'SESSION STATUS': <function _show_parser.<locals>._parse>, 'STATUS': <function _show_parser.<locals>._parse>, 'TABLE STATUS': <function _show_parser.<locals>._parse>, 'FULL TABLES': <function _show_parser.<locals>._parse>, 'TABLES': <function _show_parser.<locals>._parse>, 'TRIGGERS': <function _show_parser.<locals>._parse>, 'GLOBAL VARIABLES': <function _show_parser.<locals>._parse>, 'SESSION VARIABLES': <function _show_parser.<locals>._parse>, 'VARIABLES': <function _show_parser.<locals>._parse>, 'WARNINGS': <function _show_parser.<locals>._parse>}
PROPERTY_PARSERS = {'ALLOWED_VALUES': <function Parser.<lambda>>, 'ALGORITHM': <function Parser.<lambda>>, 'AUTO': <function Parser.<lambda>>, 'AUTO_INCREMENT': <function Parser.<lambda>>, 'BACKUP': <function Parser.<lambda>>, 'BLOCKCOMPRESSION': <function Parser.<lambda>>, 'CHARSET': <function Parser.<lambda>>, 'CHARACTER SET': <function Parser.<lambda>>, 'CHECKSUM': <function Parser.<lambda>>, 'CLUSTER BY': <function Parser.<lambda>>, 'CLUSTERED': <function Parser.<lambda>>, 'COLLATE': <function Parser.<lambda>>, 'COMMENT': <function Parser.<lambda>>, 'CONTAINS': <function Parser.<lambda>>, 'COPY': <function Parser.<lambda>>, 'DATABLOCKSIZE': <function Parser.<lambda>>, 'DATA_DELETION': <function Parser.<lambda>>, 'DEFINER': <function Parser.<lambda>>, 'DETERMINISTIC': <function Parser.<lambda>>, 'DISTRIBUTED': <function Parser.<lambda>>, 'DUPLICATE': <function Parser.<lambda>>, 'DYNAMIC': <function Parser.<lambda>>, 'DISTKEY': <function Parser.<lambda>>, 'DISTSTYLE': <function Parser.<lambda>>, 'EMPTY': <function Parser.<lambda>>, 'ENGINE': <function Parser.<lambda>>, 'ENVIRONMENT': <function Parser.<lambda>>, 'EXECUTE': <function Parser.<lambda>>, 'EXTERNAL': <function Parser.<lambda>>, 'FALLBACK': <function Parser.<lambda>>, 'FORMAT': <function Parser.<lambda>>, 'FREESPACE': <function Parser.<lambda>>, 'GLOBAL': <function Parser.<lambda>>, 'HEAP': <function Parser.<lambda>>, 'ICEBERG': <function Parser.<lambda>>, 'IMMUTABLE': <function Parser.<lambda>>, 'INHERITS': <function Parser.<lambda>>, 'INPUT': <function Parser.<lambda>>, 'JOURNAL': <function Parser.<lambda>>, 'LANGUAGE': <function Parser.<lambda>>, 'LAYOUT': <function Parser.<lambda>>, 'LIFETIME': <function Parser.<lambda>>, 'LIKE': <function Parser.<lambda>>, 'LOCATION': <function Parser.<lambda>>, 'LOCK': <function MySQL.Parser.<lambda>>, 'LOCKING': <function Parser.<lambda>>, 'LOG': <function Parser.<lambda>>, 'MATERIALIZED': <function Parser.<lambda>>, 'MERGEBLOCKRATIO': <function Parser.<lambda>>, 'MODIFIES': <function Parser.<lambda>>, 'MULTISET': <function Parser.<lambda>>, 'NO': <function Parser.<lambda>>, 'ON': <function Parser.<lambda>>, 'ORDER BY': <function Parser.<lambda>>, 'OUTPUT': <function Parser.<lambda>>, 'PARTITION': <function Parser.<lambda>>, 'PARTITION BY': <function MySQL.Parser.<lambda>>, 'PARTITIONED BY': <function Parser.<lambda>>, 'PARTITIONED_BY': <function Parser.<lambda>>, 'PRIMARY KEY': <function Parser.<lambda>>, 'RANGE': <function Parser.<lambda>>, 'READS': <function Parser.<lambda>>, 'REMOTE': <function Parser.<lambda>>, 'RETURNS': <function Parser.<lambda>>, 'STRICT': <function Parser.<lambda>>, 'STREAMING': <function Parser.<lambda>>, 'ROW': <function Parser.<lambda>>, 'ROW_FORMAT': <function Parser.<lambda>>, 'SAMPLE': <function Parser.<lambda>>, 'SECURE': <function Parser.<lambda>>, 'SECURITY': <function Parser.<lambda>>, 'SET': <function Parser.<lambda>>, 'SETTINGS': <function Parser.<lambda>>, 'SHARING': <function Parser.<lambda>>, 'SORTKEY': <function Parser.<lambda>>, 'SOURCE': <function Parser.<lambda>>, 'STABLE': <function Parser.<lambda>>, 'STORED': <function Parser.<lambda>>, 'SYSTEM_VERSIONING': <function Parser.<lambda>>, 'TBLPROPERTIES': <function Parser.<lambda>>, 'TEMP': <function Parser.<lambda>>, 'TEMPORARY': <function Parser.<lambda>>, 'TO': <function Parser.<lambda>>, 'TRANSIENT': <function Parser.<lambda>>, 'TRANSFORM': <function Parser.<lambda>>, 'TTL': <function Parser.<lambda>>, 'USING': <function Parser.<lambda>>, 'UNLOGGED': <function Parser.<lambda>>, 'VOLATILE': <function Parser.<lambda>>, 'WITH': <function Parser.<lambda>>}
SET_PARSERS = {'GLOBAL': <function Parser.<lambda>>, 'LOCAL': <function Parser.<lambda>>, 'SESSION': <function Parser.<lambda>>, 'TRANSACTION': <function Parser.<lambda>>, 'PERSIST': <function MySQL.Parser.<lambda>>, 'PERSIST_ONLY': <function MySQL.Parser.<lambda>>, 'CHARACTER SET': <function MySQL.Parser.<lambda>>, 'CHARSET': <function MySQL.Parser.<lambda>>, 'NAMES': <function MySQL.Parser.<lambda>>}
CONSTRAINT_PARSERS = {'AUTOINCREMENT': <function Parser.<lambda>>, 'AUTO_INCREMENT': <function Parser.<lambda>>, 'CASESPECIFIC': <function Parser.<lambda>>, 'CHARACTER SET': <function Parser.<lambda>>, 'CHECK': <function Parser.<lambda>>, 'COLLATE': <function Parser.<lambda>>, 'COMMENT': <function Parser.<lambda>>, 'COMPRESS': <function Parser.<lambda>>, 'CLUSTERED': <function Parser.<lambda>>, 'NONCLUSTERED': <function Parser.<lambda>>, 'DEFAULT': <function Parser.<lambda>>, 'ENCODE': <function Parser.<lambda>>, 'EPHEMERAL': <function Parser.<lambda>>, 'EXCLUDE': <function Parser.<lambda>>, 'FOREIGN KEY': <function Parser.<lambda>>, 'FORMAT': <function Parser.<lambda>>, 'GENERATED': <function Parser.<lambda>>, 'IDENTITY': <function Parser.<lambda>>, 'INLINE': <function Parser.<lambda>>, 'LIKE': <function Parser.<lambda>>, 'NOT': <function Parser.<lambda>>, 'NULL': <function Parser.<lambda>>, 'ON': <function Parser.<lambda>>, 'PATH': <function Parser.<lambda>>, 'PERIOD': <function Parser.<lambda>>, 'PRIMARY KEY': <function Parser.<lambda>>, 'REFERENCES': <function Parser.<lambda>>, 'TITLE': <function Parser.<lambda>>, 'TTL': <function Parser.<lambda>>, 'UNIQUE': <function Parser.<lambda>>, 'UPPERCASE': <function Parser.<lambda>>, 'WITH': <function Parser.<lambda>>, 'BUCKET': <function Parser.<lambda>>, 'TRUNCATE': <function Parser.<lambda>>, 'FULLTEXT': <function MySQL.Parser.<lambda>>, 'INDEX': <function MySQL.Parser.<lambda>>, 'KEY': <function MySQL.Parser.<lambda>>, 'SPATIAL': <function MySQL.Parser.<lambda>>, 'ZEROFILL': <function MySQL.Parser.<lambda>>}
ALTER_PARSERS = {'ADD': <function Parser.<lambda>>, 'AS': <function Parser.<lambda>>, 'ALTER': <function Parser.<lambda>>, 'CLUSTER BY': <function Parser.<lambda>>, 'DELETE': <function Parser.<lambda>>, 'DROP': <function Parser.<lambda>>, 'RENAME': <function Parser.<lambda>>, 'SET': <function Parser.<lambda>>, 'SWAP': <function Parser.<lambda>>, 'MODIFY': <function MySQL.Parser.<lambda>>}
ALTER_ALTER_PARSERS = {'DISTKEY': <function Parser.<lambda>>, 'DISTSTYLE': <function Parser.<lambda>>, 'SORTKEY': <function Parser.<lambda>>, 'COMPOUND': <function Parser.<lambda>>, 'INDEX': <function MySQL.Parser.<lambda>>}
SCHEMA_UNNAMED_CONSTRAINTS = {'UNIQUE', 'CHECK', 'PRIMARY KEY', 'FULLTEXT', 'BUCKET', 'TRUNCATE', 'INDEX', 'FOREIGN KEY', 'EXCLUDE', 'KEY', 'PERIOD', 'SPATIAL', 'LIKE'}
PROFILE_TYPES: Dict[str, Sequence[Union[Sequence[str], str]]] = {'ALL': (), 'CPU': (), 'IPC': (), 'MEMORY': (), 'SOURCE': (), 'SWAPS': (), 'BLOCK': ('IO',), 'CONTEXT': ('SWITCHES',), 'PAGE': ('FAULTS',)}
TYPE_TOKENS = {<TokenType.BIT: 93>, <TokenType.BOOLEAN: 94>, <TokenType.TINYINT: 95>, <TokenType.UTINYINT: 96>, <TokenType.SMALLINT: 97>, <TokenType.USMALLINT: 98>, <TokenType.MEDIUMINT: 99>, <TokenType.UMEDIUMINT: 100>, <TokenType.INT: 101>, <TokenType.UINT: 102>, <TokenType.BIGINT: 103>, <TokenType.UBIGINT: 104>, <TokenType.BIGNUM: 105>, <TokenType.INT128: 106>, <TokenType.UINT128: 107>, <TokenType.INT256: 108>, <TokenType.UINT256: 109>, <TokenType.FLOAT: 110>, <TokenType.DOUBLE: 111>, <TokenType.UDOUBLE: 112>, <TokenType.DECIMAL: 113>, <TokenType.DECIMAL32: 114>, <TokenType.DECIMAL64: 115>, <TokenType.DECIMAL128: 116>, <TokenType.DECIMAL256: 117>, <TokenType.DECFLOAT: 118>, <TokenType.UDECIMAL: 119>, <TokenType.BIGDECIMAL: 120>, <TokenType.CHAR: 121>, <TokenType.NCHAR: 122>, <TokenType.VARCHAR: 123>, <TokenType.NVARCHAR: 124>, <TokenType.BPCHAR: 125>, <TokenType.TEXT: 126>, <TokenType.MEDIUMTEXT: 127>, <TokenType.LONGTEXT: 128>, <TokenType.BLOB: 129>, <TokenType.MEDIUMBLOB: 130>, <TokenType.LONGBLOB: 131>, <TokenType.TINYBLOB: 132>, <TokenType.TINYTEXT: 133>, <TokenType.NAME: 134>, <TokenType.BINARY: 135>, <TokenType.VARBINARY: 136>, <TokenType.JSON: 137>, <TokenType.JSONB: 138>, <TokenType.TIME: 139>, <TokenType.TIMETZ: 140>, <TokenType.TIME_NS: 141>, <TokenType.TIMESTAMP: 142>, <TokenType.TIMESTAMPTZ: 143>, <TokenType.TIMESTAMPLTZ: 144>, <TokenType.TIMESTAMPNTZ: 145>, <TokenType.TIMESTAMP_S: 146>, <TokenType.TIMESTAMP_MS: 147>, <TokenType.TIMESTAMP_NS: 148>, <TokenType.DATETIME: 149>, <TokenType.DATETIME2: 150>, <TokenType.DATETIME64: 151>, <TokenType.SMALLDATETIME: 152>, <TokenType.DATE: 153>, <TokenType.DATE32: 154>, <TokenType.INT4RANGE: 155>, <TokenType.INT4MULTIRANGE: 156>, <TokenType.INT8RANGE: 157>, <TokenType.INT8MULTIRANGE: 158>, <TokenType.NUMRANGE: 159>, <TokenType.NUMMULTIRANGE: 160>, <TokenType.TSRANGE: 161>, <TokenType.TSMULTIRANGE: 162>, <TokenType.TSTZRANGE: 163>, <TokenType.TSTZMULTIRANGE: 164>, <TokenType.DATERANGE: 165>, <TokenType.DATEMULTIRANGE: 166>, <TokenType.UUID: 167>, <TokenType.GEOGRAPHY: 168>, <TokenType.GEOGRAPHYPOINT: 169>, <TokenType.NULLABLE: 170>, <TokenType.GEOMETRY: 171>, <TokenType.POINT: 172>, <TokenType.RING: 173>, <TokenType.LINESTRING: 174>, <TokenType.MULTILINESTRING: 178>, <TokenType.POLYGON: 179>, <TokenType.MULTIPOLYGON: 180>, <TokenType.HLLSKETCH: 181>, <TokenType.HSTORE: 182>, <TokenType.SUPER: 183>, <TokenType.SERIAL: 184>, <TokenType.SMALLSERIAL: 185>, <TokenType.BIGSERIAL: 186>, <TokenType.XML: 187>, <TokenType.YEAR: 188>, <TokenType.USERDEFINED: 189>, <TokenType.MONEY: 190>, <TokenType.SMALLMONEY: 191>, <TokenType.ROWVERSION: 192>, <TokenType.IMAGE: 193>, <TokenType.VARIANT: 194>, <TokenType.OBJECT: 195>, <TokenType.INET: 196>, <TokenType.IPADDRESS: 197>, <TokenType.IPPREFIX: 198>, <TokenType.IPV4: 199>, <TokenType.IPV6: 200>, <TokenType.ENUM: 201>, <TokenType.ENUM8: 202>, <TokenType.ENUM16: 203>, <TokenType.FIXEDSTRING: 204>, <TokenType.LOWCARDINALITY: 205>, <TokenType.NESTED: 206>, <TokenType.AGGREGATEFUNCTION: 207>, <TokenType.SIMPLEAGGREGATEFUNCTION: 208>, <TokenType.TDIGEST: 209>, <TokenType.UNKNOWN: 210>, <TokenType.VECTOR: 211>, <TokenType.DYNAMIC: 212>, <TokenType.VOID: 213>, <TokenType.ARRAY: 220>, <TokenType.FILE: 269>, <TokenType.INTERVAL: 298>, <TokenType.LIST: 314>, <TokenType.MAP: 317>, <TokenType.NOTHING: 327>, <TokenType.NULL: 329>, <TokenType.OBJECT_IDENTIFIER: 330>, <TokenType.PSEUDO_TYPE: 356>, <TokenType.RANGE: 361>, <TokenType.SET: 380>, <TokenType.STRUCT: 390>, <TokenType.UNION: 401>}
ENUM_TYPE_TOKENS = {<TokenType.ENUM: 201>, <TokenType.ENUM8: 202>, <TokenType.ENUM16: 203>, <TokenType.DYNAMIC: 212>, <TokenType.SET: 380>}
OPERATION_MODIFIERS = {'SQL_SMALL_RESULT', 'SQL_BUFFER_RESULT', 'SQL_BIG_RESULT', 'SQL_CALC_FOUND_ROWS', 'STRAIGHT_JOIN', 'SQL_NO_CACHE', 'HIGH_PRIORITY'}
LOG_DEFAULTS_TO_LN = True
STRING_ALIASES = True
VALUES_FOLLOWED_BY_PAREN = False
SUPPORTS_PARTITION_SELECTION = True
ID_VAR_TOKENS = {<TokenType.SESSION: 56>, <TokenType.SESSION_USER: 58>, <TokenType.IDENTIFIER: 76>, <TokenType.DATABASE: 77>, <TokenType.COLUMN: 78>, <TokenType.SCHEMA: 80>, <TokenType.TABLE: 81>, <TokenType.WAREHOUSE: 82>, <TokenType.STAGE: 83>, <TokenType.STREAMLIT: 84>, <TokenType.VAR: 85>, <TokenType.BIT: 93>, <TokenType.BOOLEAN: 94>, <TokenType.TINYINT: 95>, <TokenType.UTINYINT: 96>, <TokenType.SMALLINT: 97>, <TokenType.USMALLINT: 98>, <TokenType.MEDIUMINT: 99>, <TokenType.UMEDIUMINT: 100>, <TokenType.INT: 101>, <TokenType.UINT: 102>, <TokenType.BIGINT: 103>, <TokenType.UBIGINT: 104>, <TokenType.BIGNUM: 105>, <TokenType.INT128: 106>, <TokenType.UINT128: 107>, <TokenType.INT256: 108>, <TokenType.UINT256: 109>, <TokenType.FLOAT: 110>, <TokenType.DOUBLE: 111>, <TokenType.UDOUBLE: 112>, <TokenType.DECIMAL: 113>, <TokenType.DECIMAL32: 114>, <TokenType.DECIMAL64: 115>, <TokenType.DECIMAL128: 116>, <TokenType.DECIMAL256: 117>, <TokenType.DECFLOAT: 118>, <TokenType.UDECIMAL: 119>, <TokenType.BIGDECIMAL: 120>, <TokenType.CHAR: 121>, <TokenType.NCHAR: 122>, <TokenType.VARCHAR: 123>, <TokenType.NVARCHAR: 124>, <TokenType.BPCHAR: 125>, <TokenType.TEXT: 126>, <TokenType.MEDIUMTEXT: 127>, <TokenType.LONGTEXT: 128>, <TokenType.BLOB: 129>, <TokenType.MEDIUMBLOB: 130>, <TokenType.LONGBLOB: 131>, <TokenType.TINYBLOB: 132>, <TokenType.TINYTEXT: 133>, <TokenType.NAME: 134>, <TokenType.BINARY: 135>, <TokenType.VARBINARY: 136>, <TokenType.JSON: 137>, <TokenType.JSONB: 138>, <TokenType.TIME: 139>, <TokenType.TIMETZ: 140>, <TokenType.TIME_NS: 141>, <TokenType.TIMESTAMP: 142>, <TokenType.TIMESTAMPTZ: 143>, <TokenType.TIMESTAMPLTZ: 144>, <TokenType.TIMESTAMPNTZ: 145>, <TokenType.TIMESTAMP_S: 146>, <TokenType.TIMESTAMP_MS: 147>, <TokenType.TIMESTAMP_NS: 148>, <TokenType.DATETIME: 149>, <TokenType.DATETIME2: 150>, <TokenType.DATETIME64: 151>, <TokenType.SMALLDATETIME: 152>, <TokenType.DATE: 153>, <TokenType.DATE32: 154>, <TokenType.INT4RANGE: 155>, <TokenType.INT4MULTIRANGE: 156>, <TokenType.INT8RANGE: 157>, <TokenType.INT8MULTIRANGE: 158>, <TokenType.NUMRANGE: 159>, <TokenType.NUMMULTIRANGE: 160>, <TokenType.TSRANGE: 161>, <TokenType.TSMULTIRANGE: 162>, <TokenType.TSTZRANGE: 163>, <TokenType.TSTZMULTIRANGE: 164>, <TokenType.DATERANGE: 165>, <TokenType.DATEMULTIRANGE: 166>, <TokenType.UUID: 167>, <TokenType.GEOGRAPHY: 168>, <TokenType.GEOGRAPHYPOINT: 169>, <TokenType.NULLABLE: 170>, <TokenType.GEOMETRY: 171>, <TokenType.POINT: 172>, <TokenType.RING: 173>, <TokenType.LINESTRING: 174>, <TokenType.LOCALTIME: 175>, <TokenType.LOCALTIMESTAMP: 176>, <TokenType.MULTILINESTRING: 178>, <TokenType.POLYGON: 179>, <TokenType.MULTIPOLYGON: 180>, <TokenType.HLLSKETCH: 181>, <TokenType.HSTORE: 182>, <TokenType.SUPER: 183>, <TokenType.SERIAL: 184>, <TokenType.SMALLSERIAL: 185>, <TokenType.BIGSERIAL: 186>, <TokenType.XML: 187>, <TokenType.YEAR: 188>, <TokenType.USERDEFINED: 189>, <TokenType.MONEY: 190>, <TokenType.SMALLMONEY: 191>, <TokenType.ROWVERSION: 192>, <TokenType.IMAGE: 193>, <TokenType.VARIANT: 194>, <TokenType.OBJECT: 195>, <TokenType.INET: 196>, <TokenType.IPADDRESS: 197>, <TokenType.IPPREFIX: 198>, <TokenType.IPV4: 199>, <TokenType.IPV6: 200>, <TokenType.ENUM: 201>, <TokenType.ENUM8: 202>, <TokenType.ENUM16: 203>, <TokenType.FIXEDSTRING: 204>, <TokenType.LOWCARDINALITY: 205>, <TokenType.NESTED: 206>, <TokenType.AGGREGATEFUNCTION: 207>, <TokenType.SIMPLEAGGREGATEFUNCTION: 208>, <TokenType.TDIGEST: 209>, <TokenType.UNKNOWN: 210>, <TokenType.VECTOR: 211>, <TokenType.DYNAMIC: 212>, <TokenType.VOID: 213>, <TokenType.ALL: 216>, <TokenType.ANTI: 217>, <TokenType.ANY: 218>, <TokenType.APPLY: 219>, <TokenType.ARRAY: 220>, <TokenType.ASC: 221>, <TokenType.ASOF: 222>, <TokenType.ATTACH: 223>, <TokenType.AUTO_INCREMENT: 224>, <TokenType.BEGIN: 225>, <TokenType.CACHE: 228>, <TokenType.CASE: 229>, <TokenType.COLLATE: 232>, <TokenType.COMMAND: 233>, <TokenType.COMMENT: 234>, <TokenType.COMMIT: 235>, <TokenType.CONSTRAINT: 237>, <TokenType.COPY: 238>, <TokenType.CUBE: 241>, <TokenType.CURRENT_DATE: 242>, <TokenType.CURRENT_DATETIME: 243>, <TokenType.CURRENT_SCHEMA: 244>, <TokenType.CURRENT_TIME: 245>, <TokenType.CURRENT_TIMESTAMP: 246>, <TokenType.CURRENT_USER: 247>, <TokenType.CURRENT_ROLE: 248>, <TokenType.CURRENT_CATALOG: 249>, <TokenType.DEFAULT: 251>, <TokenType.DELETE: 252>, <TokenType.DESC: 253>, <TokenType.DESCRIBE: 254>, <TokenType.DETACH: 255>, <TokenType.DICTIONARY: 256>, <TokenType.DIV: 259>, <TokenType.END: 262>, <TokenType.ESCAPE: 263>, <TokenType.EXECUTE: 265>, <TokenType.EXISTS: 266>, <TokenType.FALSE: 267>, <TokenType.FILE: 269>, <TokenType.FILE_FORMAT: 270>, <TokenType.FILTER: 271>, <TokenType.FINAL: 272>, <TokenType.FIRST: 273>, <TokenType.FOREIGN_KEY: 276>, <TokenType.FORMAT: 277>, <TokenType.FULL: 279>, <TokenType.FUNCTION: 280>, <TokenType.GET: 281>, <TokenType.INDEX: 292>, <TokenType.INTERVAL: 298>, <TokenType.IS: 302>, <TokenType.ISNULL: 303>, <TokenType.KEEP: 306>, <TokenType.KILL: 308>, <TokenType.LEFT: 311>, <TokenType.LIMIT: 313>, <TokenType.LIST: 314>, <TokenType.LOAD: 315>, <TokenType.LOCK: 316>, <TokenType.MAP: 317>, <TokenType.MATCH: 318>, <TokenType.MERGE: 322>, <TokenType.MODEL: 324>, <TokenType.NATURAL: 325>, <TokenType.NEXT: 326>, <TokenType.NOTHING: 327>, <TokenType.NULL: 329>, <TokenType.OBJECT_IDENTIFIER: 330>, <TokenType.OFFSET: 331>, <TokenType.OPERATOR: 334>, <TokenType.ORDINALITY: 338>, <TokenType.INOUT: 340>, <TokenType.OVER: 342>, <TokenType.OVERLAPS: 343>, <TokenType.OVERWRITE: 344>, <TokenType.PARTITION: 345>, <TokenType.PERCENT: 347>, <TokenType.PIVOT: 348>, <TokenType.PRAGMA: 351>, <TokenType.PROCEDURE: 354>, <TokenType.PSEUDO_TYPE: 356>, <TokenType.PUT: 357>, <TokenType.RANGE: 361>, <TokenType.RECURSIVE: 362>, <TokenType.REFRESH: 363>, <TokenType.RENAME: 364>, <TokenType.REPLACE: 365>, <TokenType.REFERENCES: 368>, <TokenType.RIGHT: 369>, <TokenType.ROLLUP: 372>, <TokenType.ROW: 373>, <TokenType.ROWS: 374>, <TokenType.SEMI: 376>, <TokenType.SEQUENCE: 378>, <TokenType.SET: 380>, <TokenType.SETTINGS: 381>, <TokenType.SHOW: 382>, <TokenType.SOME: 384>, <TokenType.STORAGE_INTEGRATION: 388>, <TokenType.STRUCT: 390>, <TokenType.TAG: 393>, <TokenType.TEMPORARY: 394>, <TokenType.TOP: 395>, <TokenType.TRUE: 397>, <TokenType.TRUNCATE: 398>, <TokenType.TRIGGER: 399>, <TokenType.UNNEST: 402>, <TokenType.UNPIVOT: 403>, <TokenType.UPDATE: 404>, <TokenType.USE: 405>, <TokenType.VIEW: 409>, <TokenType.SEMANTIC_VIEW: 410>, <TokenType.VOLATILE: 411>, <TokenType.WINDOW: 414>, <TokenType.UNIQUE: 416>, <TokenType.SINK: 423>, <TokenType.SOURCE: 424>, <TokenType.ANALYZE: 425>, <TokenType.NAMESPACE: 426>, <TokenType.EXPORT: 427>}
SHOW_TRIE: Dict = {'BINARY': {'LOGS': {0: True}}, 'MASTER': {'LOGS': {0: True}, 'STATUS': {0: True}}, 'BINLOG': {'EVENTS': {0: True}}, 'CHARACTER': {'SET': {0: True}}, 'CHARSET': {0: True}, 'COLLATION': {0: True}, 'FULL': {'COLUMNS': {0: True}, 'PROCESSLIST': {0: True}, 'TABLES': {0: True}}, 'COLUMNS': {0: True}, 'CREATE': {'DATABASE': {0: True}, 'EVENT': {0: True}, 'FUNCTION': {0: True}, 'PROCEDURE': {0: True}, 'TABLE': {0: True}, 'TRIGGER': {0: True}, 'VIEW': {0: True}}, 'DATABASES': {0: True}, 'SCHEMAS': {0: True}, 'ENGINE': {0: True}, 'STORAGE': {'ENGINES': {0: True}}, 'ENGINES': {0: True}, 'ERRORS': {0: True}, 'EVENTS': {0: True}, 'FUNCTION': {'CODE': {0: True}, 'STATUS': {0: True}}, 'GRANTS': {0: True}, 'INDEX': {0: True}, 'OPEN': {'TABLES': {0: True}}, 'PLUGINS': {0: True}, 'PROCEDURE': {'CODE': {0: True}, 'STATUS': {0: True}}, 'PRIVILEGES': {0: True}, 'PROCESSLIST': {0: True}, 'PROFILE': {0: True}, 'PROFILES': {0: True}, 'RELAYLOG': {'EVENTS': {0: True}}, 'REPLICAS': {0: True}, 'SLAVE': {'HOSTS': {0: True}, 'STATUS': {0: True}}, 'REPLICA': {'STATUS': {0: True}}, 'GLOBAL': {'STATUS': {0: True}, 'VARIABLES': {0: True}}, 'SESSION': {'STATUS': {0: True}, 'VARIABLES': {0: True}}, 'STATUS': {0: True}, 'TABLE': {'STATUS': {0: True}}, 'TABLES': {0: True}, 'TRIGGERS': {0: True}, 'VARIABLES': {0: True}, 'WARNINGS': {0: True}}
SET_TRIE: Dict = {'GLOBAL': {0: True}, 'LOCAL': {0: True}, 'SESSION': {0: True}, 'TRANSACTION': {0: True}, 'PERSIST': {0: True}, 'PERSIST_ONLY': {0: True}, 'CHARACTER': {'SET': {0: True}}, 'CHARSET': {0: True}, 'NAMES': {0: True}}
Inherited Members
sqlglot.parser.Parser
Parser
NO_PAREN_FUNCTIONS
STRUCT_TYPE_TOKENS
NESTED_TYPE_TOKENS
AGGREGATE_TYPE_TOKENS
SIGNED_TO_UNSIGNED_TYPE_TOKEN
SUBQUERY_PREDICATES
RESERVED_TOKENS
DB_CREATABLES
CREATABLES
TRIGGER_EVENTS
ALTERABLES
ALIAS_TOKENS
COLON_PLACEHOLDER_TOKENS
ARRAY_CONSTRUCTORS
COMMENT_TABLE_ALIAS_TOKENS
UPDATE_ALIAS_TOKENS
TRIM_TYPES
ASSIGNMENT
EQUALITY
COMPARISON
BITWISE
TERM
FACTOR
EXPONENT
TIMES
TIMESTAMPS
SET_OPERATIONS
JOIN_METHODS
JOIN_SIDES
JOIN_KINDS
JOIN_HINTS
LAMBDAS
COLUMN_OPERATORS
CAST_COLUMN_OPERATORS
EXPRESSION_PARSERS
UNARY_PARSERS
STRING_PARSERS
NUMERIC_PARSERS
PRIMARY_PARSERS
PLACEHOLDER_PARSERS
PIPE_SYNTAX_TRANSFORM_PARSERS
NO_PAREN_FUNCTION_PARSERS
INVALID_FUNC_NAME_TOKENS
FUNCTIONS_WITH_ALIASED_ARGS
KEY_VALUE_DEFINITIONS
QUERY_MODIFIER_PARSERS
QUERY_MODIFIER_TOKENS
TYPE_LITERAL_PARSERS
TYPE_CONVERTERS
DDL_SELECT_TOKENS
PRE_VOLATILE_TOKENS
TRANSACTION_KIND
TRANSACTION_CHARACTERISTICS
CONFLICT_ACTIONS
TRIGGER_TIMING
TRIGGER_DEFERRABLE
CREATE_SEQUENCE
ISOLATED_LOADING_OPTIONS
USABLES
CAST_ACTIONS
SCHEMA_BINDING_OPTIONS
PROCEDURE_OPTIONS
EXECUTE_AS_OPTIONS
KEY_CONSTRAINT_OPTIONS
WINDOW_EXCLUDE_OPTIONS
INSERT_ALTERNATIVES
CLONE_KEYWORDS
HISTORICAL_DATA_PREFIX
HISTORICAL_DATA_KIND
OPCLASS_FOLLOW_KEYWORDS
OPTYPE_FOLLOW_TOKENS
TABLE_INDEX_HINT_TOKENS
VIEW_ATTRIBUTES
WINDOW_ALIAS_TOKENS
WINDOW_BEFORE_PAREN_TOKENS
WINDOW_SIDES
JSON_KEY_VALUE_SEPARATOR_TOKENS
FETCH_TOKENS
ADD_CONSTRAINT_TOKENS
DISTINCT_TOKENS
UNNEST_OFFSET_ALIAS_TOKENS
SELECT_START_TOKENS
COPY_INTO_VARLEN_OPTIONS
IS_JSON_PREDICATE_KIND
ODBC_DATETIME_LITERALS
ON_CONDITION_TOKENS
PRIVILEGE_FOLLOW_TOKENS
DESCRIBE_STYLES
SET_ASSIGNMENT_DELIMITERS
ANALYZE_STYLES
ANALYZE_EXPRESSION_PARSERS
PARTITION_KEYWORDS
AMBIGUOUS_ALIAS_TOKENS
RECURSIVE_CTE_SEARCH_KIND
MODIFIABLES
STRICT_CAST
PREFIXED_PIVOT_COLUMNS
IDENTIFY_PIVOT_STRINGS
TABLESAMPLE_CSV
DEFAULT_SAMPLING_METHOD
SET_REQUIRES_ASSIGNMENT_DELIMITER
TRIM_PATTERN_FIRST
MODIFIERS_ATTACHED_TO_SET_OP
SET_OP_MODIFIERS
NO_PAREN_IF_COMMANDS
JSON_ARROWS_REQUIRE_JSON_TYPE
COLON_IS_VARIANT_EXTRACT
SUPPORTS_IMPLICIT_UNNEST
INTERVAL_SPANS
WRAPPED_TRANSFORM_COLUMN_CONSTRAINT
OPTIONAL_ALIAS_TOKEN_CTE
ALTER_RENAME_REQUIRES_COLUMN
ALTER_TABLE_PARTITIONS
JOINS_HAVE_EQUAL_PRECEDENCE
ZONE_AWARE_TIMESTAMP_CONSTRUCTOR
MAP_KEYS_ARE_ARBITRARY_EXPRESSIONS
JSON_EXTRACT_REQUIRES_JSON_EXPRESSION
ADD_JOIN_ON_TRUE
SUPPORTS_OMITTED_INTERVAL_SPAN_UNIT
raise_error
validate_expression
reset
errors
error_level
error_message_context
max_errors
dialect
sql
parse
parse_into
check_errors
expression
parse_set_operation
build_cast
class MySQL.Generator(sqlglot.generator.Generator):
 806    class Generator(generator.Generator):
 807        INTERVAL_ALLOWS_PLURAL_FORM = False
 808        LOCKING_READS_SUPPORTED = True
 809        NULL_ORDERING_SUPPORTED: t.Optional[bool] = None
 810        JOIN_HINTS = False
 811        TABLE_HINTS = True
 812        DUPLICATE_KEY_UPDATE_WITH_SET = False
 813        QUERY_HINT_SEP = " "
 814        VALUES_AS_TABLE = False
 815        NVL2_SUPPORTED = False
 816        LAST_DAY_SUPPORTS_DATE_PART = False
 817        JSON_TYPE_REQUIRED_FOR_EXTRACTION = True
 818        JSON_PATH_BRACKETED_KEY_SUPPORTED = False
 819        JSON_KEY_VALUE_PAIR_SEP = ","
 820        SUPPORTS_TO_NUMBER = False
 821        PARSE_JSON_NAME: t.Optional[str] = None
 822        PAD_FILL_PATTERN_IS_REQUIRED = True
 823        WRAP_DERIVED_VALUES = False
 824        VARCHAR_REQUIRES_SIZE = True
 825        SUPPORTS_MEDIAN = False
 826        UPDATE_STATEMENT_SUPPORTS_FROM = False
 827
 828        TRANSFORMS = {
 829            **generator.Generator.TRANSFORMS,
 830            exp.ArrayAgg: rename_func("GROUP_CONCAT"),
 831            exp.BitwiseAndAgg: rename_func("BIT_AND"),
 832            exp.BitwiseOrAgg: rename_func("BIT_OR"),
 833            exp.BitwiseXorAgg: rename_func("BIT_XOR"),
 834            exp.BitwiseCount: rename_func("BIT_COUNT"),
 835            exp.Chr: lambda self, e: self.chr_sql(e, "CHAR"),
 836            exp.CurrentDate: no_paren_current_date_sql,
 837            exp.CurrentVersion: rename_func("VERSION"),
 838            exp.DateDiff: _remove_ts_or_ds_to_date(
 839                lambda self, e: self.func("DATEDIFF", e.this, e.expression), ("this", "expression")
 840            ),
 841            exp.DateAdd: _remove_ts_or_ds_to_date(date_add_sql("ADD")),
 842            exp.DateStrToDate: datestrtodate_sql,
 843            exp.DateSub: _remove_ts_or_ds_to_date(date_add_sql("SUB")),
 844            exp.DateTrunc: _date_trunc_sql,
 845            exp.Day: _remove_ts_or_ds_to_date(),
 846            exp.DayOfMonth: _remove_ts_or_ds_to_date(rename_func("DAYOFMONTH")),
 847            exp.DayOfWeek: _remove_ts_or_ds_to_date(rename_func("DAYOFWEEK")),
 848            exp.DayOfYear: _remove_ts_or_ds_to_date(rename_func("DAYOFYEAR")),
 849            exp.GroupConcat: lambda self,
 850            e: f"""GROUP_CONCAT({self.sql(e, "this")} SEPARATOR {self.sql(e, "separator") or "','"})""",
 851            exp.ILike: no_ilike_sql,
 852            exp.JSONExtractScalar: arrow_json_extract_sql,
 853            exp.Length: length_or_char_length_sql,
 854            exp.LogicalOr: rename_func("MAX"),
 855            exp.LogicalAnd: rename_func("MIN"),
 856            exp.Max: max_or_greatest,
 857            exp.Min: min_or_least,
 858            exp.Month: _remove_ts_or_ds_to_date(),
 859            exp.NullSafeEQ: lambda self, e: self.binary(e, "<=>"),
 860            exp.NullSafeNEQ: lambda self, e: f"NOT {self.binary(e, '<=>')}",
 861            exp.NumberToStr: rename_func("FORMAT"),
 862            exp.Pivot: no_pivot_sql,
 863            exp.Select: transforms.preprocess(
 864                [
 865                    transforms.eliminate_distinct_on,
 866                    transforms.eliminate_semi_and_anti_joins,
 867                    transforms.eliminate_qualify,
 868                    transforms.eliminate_full_outer_join,
 869                    transforms.unnest_generate_date_array_using_recursive_cte,
 870                ]
 871            ),
 872            exp.StrPosition: lambda self, e: strposition_sql(
 873                self, e, func_name="LOCATE", supports_position=True
 874            ),
 875            exp.StrToDate: _str_to_date_sql,
 876            exp.StrToTime: _str_to_date_sql,
 877            exp.Stuff: rename_func("INSERT"),
 878            exp.SessionUser: lambda *_: "SESSION_USER()",
 879            exp.TableSample: no_tablesample_sql,
 880            exp.TimeFromParts: rename_func("MAKETIME"),
 881            exp.TimestampAdd: date_add_interval_sql("DATE", "ADD"),
 882            exp.TimestampDiff: lambda self, e: self.func(
 883                "TIMESTAMPDIFF", unit_to_var(e), e.expression, e.this
 884            ),
 885            exp.TimestampSub: date_add_interval_sql("DATE", "SUB"),
 886            exp.TimeStrToUnix: rename_func("UNIX_TIMESTAMP"),
 887            exp.TimeStrToTime: lambda self, e: timestrtotime_sql(
 888                self,
 889                e,
 890                include_precision=not e.args.get("zone"),
 891            ),
 892            exp.TimeToStr: _remove_ts_or_ds_to_date(
 893                lambda self, e: self.func("DATE_FORMAT", e.this, self.format_time(e))
 894            ),
 895            exp.Trim: trim_sql,
 896            exp.Trunc: rename_func("TRUNCATE"),
 897            exp.TryCast: no_trycast_sql,
 898            exp.TsOrDsAdd: date_add_sql("ADD"),
 899            exp.TsOrDsDiff: lambda self, e: self.func("DATEDIFF", e.this, e.expression),
 900            exp.TsOrDsToDate: _ts_or_ds_to_date_sql,
 901            exp.Unicode: lambda self, e: f"ORD(CONVERT({self.sql(e.this)} USING utf32))",
 902            exp.UnixToTime: _unix_to_time_sql,
 903            exp.Week: _remove_ts_or_ds_to_date(),
 904            exp.WeekOfYear: _remove_ts_or_ds_to_date(rename_func("WEEKOFYEAR")),
 905            exp.Year: _remove_ts_or_ds_to_date(),
 906            exp.UtcTimestamp: rename_func("UTC_TIMESTAMP"),
 907            exp.UtcTime: rename_func("UTC_TIME"),
 908        }
 909
 910        UNSIGNED_TYPE_MAPPING = {
 911            exp.DataType.Type.UBIGINT: "BIGINT",
 912            exp.DataType.Type.UINT: "INT",
 913            exp.DataType.Type.UMEDIUMINT: "MEDIUMINT",
 914            exp.DataType.Type.USMALLINT: "SMALLINT",
 915            exp.DataType.Type.UTINYINT: "TINYINT",
 916            exp.DataType.Type.UDECIMAL: "DECIMAL",
 917            exp.DataType.Type.UDOUBLE: "DOUBLE",
 918        }
 919
 920        TIMESTAMP_TYPE_MAPPING = {
 921            exp.DataType.Type.DATETIME2: "DATETIME",
 922            exp.DataType.Type.SMALLDATETIME: "DATETIME",
 923            exp.DataType.Type.TIMESTAMP: "DATETIME",
 924            exp.DataType.Type.TIMESTAMPNTZ: "DATETIME",
 925            exp.DataType.Type.TIMESTAMPTZ: "TIMESTAMP",
 926            exp.DataType.Type.TIMESTAMPLTZ: "TIMESTAMP",
 927        }
 928
 929        TYPE_MAPPING = {
 930            **generator.Generator.TYPE_MAPPING,
 931            **UNSIGNED_TYPE_MAPPING,
 932            **TIMESTAMP_TYPE_MAPPING,
 933        }
 934
 935        TYPE_MAPPING.pop(exp.DataType.Type.MEDIUMTEXT)
 936        TYPE_MAPPING.pop(exp.DataType.Type.LONGTEXT)
 937        TYPE_MAPPING.pop(exp.DataType.Type.TINYTEXT)
 938        TYPE_MAPPING.pop(exp.DataType.Type.BLOB)
 939        TYPE_MAPPING.pop(exp.DataType.Type.MEDIUMBLOB)
 940        TYPE_MAPPING.pop(exp.DataType.Type.LONGBLOB)
 941        TYPE_MAPPING.pop(exp.DataType.Type.TINYBLOB)
 942
 943        PROPERTIES_LOCATION = {
 944            **generator.Generator.PROPERTIES_LOCATION,
 945            exp.TransientProperty: exp.Properties.Location.UNSUPPORTED,
 946            exp.VolatileProperty: exp.Properties.Location.UNSUPPORTED,
 947            exp.PartitionedByProperty: exp.Properties.Location.UNSUPPORTED,
 948            exp.PartitionByRangeProperty: exp.Properties.Location.POST_SCHEMA,
 949            exp.PartitionByListProperty: exp.Properties.Location.POST_SCHEMA,
 950        }
 951
 952        LIMIT_FETCH = "LIMIT"
 953
 954        LIMIT_ONLY_LITERALS = True
 955
 956        CHAR_CAST_MAPPING = dict.fromkeys(
 957            (
 958                exp.DataType.Type.LONGTEXT,
 959                exp.DataType.Type.LONGBLOB,
 960                exp.DataType.Type.MEDIUMBLOB,
 961                exp.DataType.Type.MEDIUMTEXT,
 962                exp.DataType.Type.TEXT,
 963                exp.DataType.Type.TINYBLOB,
 964                exp.DataType.Type.TINYTEXT,
 965                exp.DataType.Type.VARCHAR,
 966            ),
 967            "CHAR",
 968        )
 969        SIGNED_CAST_MAPPING = dict.fromkeys(
 970            (
 971                exp.DataType.Type.BIGINT,
 972                exp.DataType.Type.BOOLEAN,
 973                exp.DataType.Type.INT,
 974                exp.DataType.Type.SMALLINT,
 975                exp.DataType.Type.TINYINT,
 976                exp.DataType.Type.MEDIUMINT,
 977            ),
 978            "SIGNED",
 979        )
 980
 981        # MySQL doesn't support many datatypes in cast.
 982        # https://dev.mysql.com/doc/refman/8.0/en/cast-functions.html#function_cast
 983        CAST_MAPPING = {
 984            **CHAR_CAST_MAPPING,
 985            **SIGNED_CAST_MAPPING,
 986            exp.DataType.Type.UBIGINT: "UNSIGNED",
 987        }
 988
 989        TIMESTAMP_FUNC_TYPES = {
 990            exp.DataType.Type.TIMESTAMPTZ,
 991            exp.DataType.Type.TIMESTAMPLTZ,
 992        }
 993
 994        # https://dev.mysql.com/doc/refman/8.0/en/keywords.html
 995        RESERVED_KEYWORDS = {
 996            "accessible",
 997            "add",
 998            "all",
 999            "alter",
1000            "analyze",
1001            "and",
1002            "as",
1003            "asc",
1004            "asensitive",
1005            "before",
1006            "between",
1007            "bigint",
1008            "binary",
1009            "blob",
1010            "both",
1011            "by",
1012            "call",
1013            "cascade",
1014            "case",
1015            "change",
1016            "char",
1017            "character",
1018            "check",
1019            "collate",
1020            "column",
1021            "condition",
1022            "constraint",
1023            "continue",
1024            "convert",
1025            "create",
1026            "cross",
1027            "cube",
1028            "cume_dist",
1029            "current_date",
1030            "current_time",
1031            "current_timestamp",
1032            "current_user",
1033            "cursor",
1034            "database",
1035            "databases",
1036            "day_hour",
1037            "day_microsecond",
1038            "day_minute",
1039            "day_second",
1040            "dec",
1041            "decimal",
1042            "declare",
1043            "default",
1044            "delayed",
1045            "delete",
1046            "dense_rank",
1047            "desc",
1048            "describe",
1049            "deterministic",
1050            "distinct",
1051            "distinctrow",
1052            "div",
1053            "double",
1054            "drop",
1055            "dual",
1056            "each",
1057            "else",
1058            "elseif",
1059            "empty",
1060            "enclosed",
1061            "escaped",
1062            "except",
1063            "exists",
1064            "exit",
1065            "explain",
1066            "false",
1067            "fetch",
1068            "first_value",
1069            "float",
1070            "float4",
1071            "float8",
1072            "for",
1073            "force",
1074            "foreign",
1075            "from",
1076            "fulltext",
1077            "function",
1078            "generated",
1079            "get",
1080            "grant",
1081            "group",
1082            "grouping",
1083            "groups",
1084            "having",
1085            "high_priority",
1086            "hour_microsecond",
1087            "hour_minute",
1088            "hour_second",
1089            "if",
1090            "ignore",
1091            "in",
1092            "index",
1093            "infile",
1094            "inner",
1095            "inout",
1096            "insensitive",
1097            "insert",
1098            "int",
1099            "int1",
1100            "int2",
1101            "int3",
1102            "int4",
1103            "int8",
1104            "integer",
1105            "intersect",
1106            "interval",
1107            "into",
1108            "io_after_gtids",
1109            "io_before_gtids",
1110            "is",
1111            "iterate",
1112            "join",
1113            "json_table",
1114            "key",
1115            "keys",
1116            "kill",
1117            "lag",
1118            "last_value",
1119            "lateral",
1120            "lead",
1121            "leading",
1122            "leave",
1123            "left",
1124            "like",
1125            "limit",
1126            "linear",
1127            "lines",
1128            "load",
1129            "localtime",
1130            "localtimestamp",
1131            "lock",
1132            "long",
1133            "longblob",
1134            "longtext",
1135            "loop",
1136            "low_priority",
1137            "master_bind",
1138            "master_ssl_verify_server_cert",
1139            "match",
1140            "maxvalue",
1141            "mediumblob",
1142            "mediumint",
1143            "mediumtext",
1144            "middleint",
1145            "minute_microsecond",
1146            "minute_second",
1147            "mod",
1148            "modifies",
1149            "natural",
1150            "not",
1151            "no_write_to_binlog",
1152            "nth_value",
1153            "ntile",
1154            "null",
1155            "numeric",
1156            "of",
1157            "on",
1158            "optimize",
1159            "optimizer_costs",
1160            "option",
1161            "optionally",
1162            "or",
1163            "order",
1164            "out",
1165            "outer",
1166            "outfile",
1167            "over",
1168            "partition",
1169            "percent_rank",
1170            "precision",
1171            "primary",
1172            "procedure",
1173            "purge",
1174            "range",
1175            "rank",
1176            "read",
1177            "reads",
1178            "read_write",
1179            "real",
1180            "recursive",
1181            "references",
1182            "regexp",
1183            "release",
1184            "rename",
1185            "repeat",
1186            "replace",
1187            "require",
1188            "resignal",
1189            "restrict",
1190            "return",
1191            "revoke",
1192            "right",
1193            "rlike",
1194            "row",
1195            "rows",
1196            "row_number",
1197            "schema",
1198            "schemas",
1199            "second_microsecond",
1200            "select",
1201            "sensitive",
1202            "separator",
1203            "set",
1204            "show",
1205            "signal",
1206            "smallint",
1207            "spatial",
1208            "specific",
1209            "sql",
1210            "sqlexception",
1211            "sqlstate",
1212            "sqlwarning",
1213            "sql_big_result",
1214            "sql_calc_found_rows",
1215            "sql_small_result",
1216            "ssl",
1217            "starting",
1218            "stored",
1219            "straight_join",
1220            "system",
1221            "table",
1222            "terminated",
1223            "then",
1224            "tinyblob",
1225            "tinyint",
1226            "tinytext",
1227            "to",
1228            "trailing",
1229            "trigger",
1230            "true",
1231            "undo",
1232            "union",
1233            "unique",
1234            "unlock",
1235            "unsigned",
1236            "update",
1237            "usage",
1238            "use",
1239            "using",
1240            "utc_date",
1241            "utc_time",
1242            "utc_timestamp",
1243            "values",
1244            "varbinary",
1245            "varchar",
1246            "varcharacter",
1247            "varying",
1248            "virtual",
1249            "when",
1250            "where",
1251            "while",
1252            "window",
1253            "with",
1254            "write",
1255            "xor",
1256            "year_month",
1257            "zerofill",
1258        }
1259
1260        def computedcolumnconstraint_sql(self, expression: exp.ComputedColumnConstraint) -> str:
1261            persisted = "STORED" if expression.args.get("persisted") else "VIRTUAL"
1262            return f"GENERATED ALWAYS AS ({self.sql(expression.this.unnest())}) {persisted}"
1263
1264        def array_sql(self, expression: exp.Array) -> str:
1265            self.unsupported("Arrays are not supported by MySQL")
1266            return self.function_fallback_sql(expression)
1267
1268        def arraycontainsall_sql(self, expression: exp.ArrayContainsAll) -> str:
1269            self.unsupported("Array operations are not supported by MySQL")
1270            return self.function_fallback_sql(expression)
1271
1272        def dpipe_sql(self, expression: exp.DPipe) -> str:
1273            return self.func("CONCAT", *expression.flatten())
1274
1275        def extract_sql(self, expression: exp.Extract) -> str:
1276            unit = expression.name
1277            if unit and unit.lower() == "epoch":
1278                return self.func("UNIX_TIMESTAMP", expression.expression)
1279
1280            return super().extract_sql(expression)
1281
1282        def datatype_sql(self, expression: exp.DataType) -> str:
1283            if (
1284                self.VARCHAR_REQUIRES_SIZE
1285                and expression.is_type(exp.DataType.Type.VARCHAR)
1286                and not expression.expressions
1287            ):
1288                # `VARCHAR` must always have a size - if it doesn't, we always generate `TEXT`
1289                return "TEXT"
1290
1291            # https://dev.mysql.com/doc/refman/8.0/en/numeric-type-syntax.html
1292            result = super().datatype_sql(expression)
1293            if expression.this in self.UNSIGNED_TYPE_MAPPING:
1294                result = f"{result} UNSIGNED"
1295
1296            return result
1297
1298        def jsonarraycontains_sql(self, expression: exp.JSONArrayContains) -> str:
1299            return f"{self.sql(expression, 'this')} MEMBER OF({self.sql(expression, 'expression')})"
1300
1301        def cast_sql(self, expression: exp.Cast, safe_prefix: t.Optional[str] = None) -> str:
1302            if expression.to.this in self.TIMESTAMP_FUNC_TYPES:
1303                return self.func("TIMESTAMP", expression.this)
1304
1305            to = self.CAST_MAPPING.get(expression.to.this)
1306
1307            if to:
1308                expression.to.set("this", to)
1309            return super().cast_sql(expression)
1310
1311        def show_sql(self, expression: exp.Show) -> str:
1312            this = f" {expression.name}"
1313            full = " FULL" if expression.args.get("full") else ""
1314            global_ = " GLOBAL" if expression.args.get("global_") else ""
1315
1316            target = self.sql(expression, "target")
1317            target = f" {target}" if target else ""
1318            if expression.name in ("COLUMNS", "INDEX"):
1319                target = f" FROM{target}"
1320            elif expression.name == "GRANTS":
1321                target = f" FOR{target}"
1322            elif expression.name in ("LINKS", "PARTITIONS"):
1323                target = f" ON{target}" if target else ""
1324            elif expression.name == "PROJECTIONS":
1325                target = f" ON TABLE{target}" if target else ""
1326
1327            db = self._prefixed_sql("FROM", expression, "db")
1328
1329            like = self._prefixed_sql("LIKE", expression, "like")
1330            where = self.sql(expression, "where")
1331
1332            types = self.expressions(expression, key="types")
1333            types = f" {types}" if types else types
1334            query = self._prefixed_sql("FOR QUERY", expression, "query")
1335
1336            if expression.name == "PROFILE":
1337                offset = self._prefixed_sql("OFFSET", expression, "offset")
1338                limit = self._prefixed_sql("LIMIT", expression, "limit")
1339            else:
1340                offset = ""
1341                limit = self._oldstyle_limit_sql(expression)
1342
1343            log = self._prefixed_sql("IN", expression, "log")
1344            position = self._prefixed_sql("FROM", expression, "position")
1345
1346            channel = self._prefixed_sql("FOR CHANNEL", expression, "channel")
1347
1348            if expression.name == "ENGINE":
1349                mutex_or_status = " MUTEX" if expression.args.get("mutex") else " STATUS"
1350            else:
1351                mutex_or_status = ""
1352
1353            for_table = self._prefixed_sql("FOR TABLE", expression, "for_table")
1354            for_group = self._prefixed_sql("FOR GROUP", expression, "for_group")
1355            for_user = self._prefixed_sql("FOR USER", expression, "for_user")
1356            for_role = self._prefixed_sql("FOR ROLE", expression, "for_role")
1357            into_outfile = self._prefixed_sql("INTO OUTFILE", expression, "into_outfile")
1358            json = " JSON" if expression.args.get("json") else ""
1359
1360            return f"SHOW{full}{global_}{this}{json}{target}{for_table}{types}{db}{query}{log}{position}{channel}{mutex_or_status}{like}{where}{offset}{limit}{for_group}{for_user}{for_role}{into_outfile}"
1361
1362        def alterrename_sql(self, expression: exp.AlterRename, include_to: bool = True) -> str:
1363            """To avoid TO keyword in ALTER ... RENAME statements.
1364            It's moved from Doris, because it's the same for all MySQL, Doris, and StarRocks.
1365            """
1366            return super().alterrename_sql(expression, include_to=False)
1367
1368        def altercolumn_sql(self, expression: exp.AlterColumn) -> str:
1369            dtype = self.sql(expression, "dtype")
1370            if not dtype:
1371                return super().altercolumn_sql(expression)
1372
1373            this = self.sql(expression, "this")
1374            return f"MODIFY COLUMN {this} {dtype}"
1375
1376        def _prefixed_sql(self, prefix: str, expression: exp.Expression, arg: str) -> str:
1377            sql = self.sql(expression, arg)
1378            return f" {prefix} {sql}" if sql else ""
1379
1380        def _oldstyle_limit_sql(self, expression: exp.Show) -> str:
1381            limit = self.sql(expression, "limit")
1382            offset = self.sql(expression, "offset")
1383            if limit:
1384                limit_offset = f"{offset}, {limit}" if offset else limit
1385                return f" LIMIT {limit_offset}"
1386            return ""
1387
1388        def timestamptrunc_sql(self, expression: exp.TimestampTrunc) -> str:
1389            unit = expression.args.get("unit")
1390
1391            # Pick an old-enough date to avoid negative timestamp diffs
1392            start_ts = "'0000-01-01 00:00:00'"
1393
1394            # Source: https://stackoverflow.com/a/32955740
1395            timestamp_diff = build_date_delta(exp.TimestampDiff)([unit, start_ts, expression.this])
1396            interval = exp.Interval(this=timestamp_diff, unit=unit)
1397            dateadd = build_date_delta_with_interval(exp.DateAdd)([start_ts, interval])
1398
1399            return self.sql(dateadd)
1400
1401        def converttimezone_sql(self, expression: exp.ConvertTimezone) -> str:
1402            from_tz = expression.args.get("source_tz")
1403            to_tz = expression.args.get("target_tz")
1404            dt = expression.args.get("timestamp")
1405
1406            return self.func("CONVERT_TZ", dt, from_tz, to_tz)
1407
1408        def attimezone_sql(self, expression: exp.AtTimeZone) -> str:
1409            self.unsupported("AT TIME ZONE is not supported by MySQL")
1410            return self.sql(expression.this)
1411
1412        def isascii_sql(self, expression: exp.IsAscii) -> str:
1413            return f"REGEXP_LIKE({self.sql(expression.this)}, '^[[:ascii:]]*$')"
1414
1415        def ignorenulls_sql(self, expression: exp.IgnoreNulls) -> str:
1416            # https://dev.mysql.com/doc/refman/8.4/en/window-function-descriptions.html
1417            self.unsupported("MySQL does not support IGNORE NULLS.")
1418            return self.sql(expression.this)
1419
1420        @unsupported_args("this")
1421        def currentschema_sql(self, expression: exp.CurrentSchema) -> str:
1422            return self.func("SCHEMA")
1423
1424        def partition_sql(self, expression: exp.Partition) -> str:
1425            parent = expression.parent
1426            if isinstance(parent, (exp.PartitionByRangeProperty, exp.PartitionByListProperty)):
1427                return self.expressions(expression, flat=True)
1428            return super().partition_sql(expression)
1429
1430        def _partition_by_sql(
1431            self, expression: exp.PartitionByRangeProperty | exp.PartitionByListProperty, kind: str
1432        ) -> str:
1433            partitions = self.expressions(expression, key="partition_expressions", flat=True)
1434            create = self.expressions(expression, key="create_expressions", flat=True)
1435            return f"PARTITION BY {kind} ({partitions}) ({create})"
1436
1437        def partitionbyrangeproperty_sql(self, expression: exp.PartitionByRangeProperty) -> str:
1438            return self._partition_by_sql(expression, "RANGE")
1439
1440        def partitionbylistproperty_sql(self, expression: exp.PartitionByListProperty) -> str:
1441            return self._partition_by_sql(expression, "LIST")
1442
1443        def partitionlist_sql(self, expression: exp.PartitionList) -> str:
1444            name = self.sql(expression, "this")
1445            values = self.expressions(expression, flat=True)
1446            return f"PARTITION {name} VALUES IN ({values})"
1447
1448        def partitionrange_sql(self, expression: exp.PartitionRange) -> str:
1449            name = self.sql(expression, "this")
1450            values = self.expressions(expression, flat=True)
1451            return f"PARTITION {name} VALUES LESS THAN ({values})"

Generator converts a given syntax tree to the corresponding SQL string.

Arguments:
  • pretty: Whether to format the produced SQL string. Default: False.
  • identify: Determines when an identifier should be quoted. Possible values are: False (default): Never quote, except in cases where it's mandatory by the dialect. True: Always quote except for specials cases. 'safe': Only quote identifiers that are case insensitive.
  • normalize: Whether to normalize identifiers to lowercase. Default: False.
  • pad: The pad size in a formatted string. For example, this affects the indentation of a projection in a query, relative to its nesting level. Default: 2.
  • indent: The indentation size in a formatted string. For example, this affects the indentation of subqueries and filters under a WHERE clause. Default: 2.
  • normalize_functions: How to normalize function names. Possible values are: "upper" or True (default): Convert names to uppercase. "lower": Convert names to lowercase. False: Disables function name normalization.
  • unsupported_level: Determines the generator's behavior when it encounters unsupported expressions. Default ErrorLevel.WARN.
  • max_unsupported: Maximum number of unsupported messages to include in a raised UnsupportedError. This is only relevant if unsupported_level is ErrorLevel.RAISE. Default: 3
  • leading_comma: Whether the comma is leading or trailing in select expressions. This is only relevant when generating in pretty mode. Default: False
  • max_text_width: The max number of characters in a segment before creating new lines in pretty mode. The default is on the smaller end because the length only represents a segment and not the true line length. Default: 80
  • comments: Whether to preserve comments in the output SQL code. Default: True
INTERVAL_ALLOWS_PLURAL_FORM = False
LOCKING_READS_SUPPORTED = True
NULL_ORDERING_SUPPORTED: Optional[bool] = None
JOIN_HINTS = False
TABLE_HINTS = True
DUPLICATE_KEY_UPDATE_WITH_SET = False
QUERY_HINT_SEP = ' '
VALUES_AS_TABLE = False
NVL2_SUPPORTED = False
LAST_DAY_SUPPORTS_DATE_PART = False
JSON_TYPE_REQUIRED_FOR_EXTRACTION = True
JSON_PATH_BRACKETED_KEY_SUPPORTED = False
JSON_KEY_VALUE_PAIR_SEP = ','
SUPPORTS_TO_NUMBER = False
PARSE_JSON_NAME: Optional[str] = None
PAD_FILL_PATTERN_IS_REQUIRED = True
WRAP_DERIVED_VALUES = False
VARCHAR_REQUIRES_SIZE = True
SUPPORTS_MEDIAN = False
UPDATE_STATEMENT_SUPPORTS_FROM = False
TRANSFORMS = {<class 'sqlglot.expressions.JSONPathFilter'>: <function <lambda>>, <class 'sqlglot.expressions.JSONPathKey'>: <function <lambda>>, <class 'sqlglot.expressions.JSONPathRecursive'>: <function <lambda>>, <class 'sqlglot.expressions.JSONPathRoot'>: <function <lambda>>, <class 'sqlglot.expressions.JSONPathScript'>: <function <lambda>>, <class 'sqlglot.expressions.JSONPathSelector'>: <function <lambda>>, <class 'sqlglot.expressions.JSONPathSlice'>: <function <lambda>>, <class 'sqlglot.expressions.JSONPathSubscript'>: <function <lambda>>, <class 'sqlglot.expressions.JSONPathUnion'>: <function <lambda>>, <class 'sqlglot.expressions.JSONPathWildcard'>: <function <lambda>>, <class 'sqlglot.expressions.Adjacent'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.AllowedValuesProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.AnalyzeColumns'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.AnalyzeWith'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.ArrayContainsAll'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.ArrayOverlaps'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.AutoRefreshProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.BackupProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.CaseSpecificColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.Ceil'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.CharacterSetColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.CharacterSetProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.ClusteredColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.CollateColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.CommentColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.ConnectByRoot'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.ConvertToCharset'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.CopyGrantsProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.CredentialsProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.CurrentCatalog'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.SessionUser'>: <function MySQL.Generator.<lambda>>, <class 'sqlglot.expressions.DateFormatColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.DefaultColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.DynamicProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.EmptyProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.EncodeColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.EndStatement'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.EnviromentProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.EphemeralColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.ExcludeColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.ExecuteAsProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.Except'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.ExternalProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.Floor'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.Get'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.GlobalProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.HeapProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.IcebergProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.InheritsProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.InlineLengthColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.InputModelProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.Intersect'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.IntervalSpan'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.Int64'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.JSONBContainsAnyTopKeys'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.JSONBContainsAllTopKeys'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.JSONBDeleteAtPath'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.LanguageProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.LocationProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.LogProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.MaterializedProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.NetFunc'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.NonClusteredColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.NoPrimaryIndexProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.NotForReplicationColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.OnCommitProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.OnProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.OnUpdateColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.Operator'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.OutputModelProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.ExtendsLeft'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.ExtendsRight'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.PathColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.PartitionedByBucket'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.PartitionByTruncate'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.PivotAny'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.PositionalColumn'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.ProjectionPolicyColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.ZeroFillColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.Put'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.RemoteWithConnectionModelProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.ReturnsProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.SafeFunc'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.SampleProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.SecureProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.SecurityProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.SetConfigProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.SetProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.SettingsProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.SharingProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.SqlReadWriteProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.SqlSecurityProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.StabilityProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.Stream'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.StreamingTableProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.StrictProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.SwapTable'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.TableColumn'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.Tags'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.TemporaryProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.TitleColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.ToMap'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.ToTableProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.TransformModelProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.TransientProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.TriggerExecute'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.Union'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.UnloggedProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.UsingTemplateProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.UsingData'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.UppercaseColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.UtcDate'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.UtcTime'>: <function rename_func.<locals>.<lambda>>, <class 'sqlglot.expressions.UtcTimestamp'>: <function rename_func.<locals>.<lambda>>, <class 'sqlglot.expressions.Variadic'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.VarMap'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.ViewAttributeProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.VolatileProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.WithJournalTableProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.WithProcedureOptions'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.WithSchemaBindingProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.WithOperator'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.ForceProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.ArrayAgg'>: <function rename_func.<locals>.<lambda>>, <class 'sqlglot.expressions.BitwiseAndAgg'>: <function rename_func.<locals>.<lambda>>, <class 'sqlglot.expressions.BitwiseOrAgg'>: <function rename_func.<locals>.<lambda>>, <class 'sqlglot.expressions.BitwiseXorAgg'>: <function rename_func.<locals>.<lambda>>, <class 'sqlglot.expressions.BitwiseCount'>: <function rename_func.<locals>.<lambda>>, <class 'sqlglot.expressions.Chr'>: <function MySQL.Generator.<lambda>>, <class 'sqlglot.expressions.CurrentDate'>: <function no_paren_current_date_sql>, <class 'sqlglot.expressions.CurrentVersion'>: <function rename_func.<locals>.<lambda>>, <class 'sqlglot.expressions.DateDiff'>: <function _remove_ts_or_ds_to_date.<locals>.func>, <class 'sqlglot.expressions.DateAdd'>: <function _remove_ts_or_ds_to_date.<locals>.func>, <class 'sqlglot.expressions.DateStrToDate'>: <function datestrtodate_sql>, <class 'sqlglot.expressions.DateSub'>: <function _remove_ts_or_ds_to_date.<locals>.func>, <class 'sqlglot.expressions.DateTrunc'>: <function _date_trunc_sql>, <class 'sqlglot.expressions.Day'>: <function _remove_ts_or_ds_to_date.<locals>.func>, <class 'sqlglot.expressions.DayOfMonth'>: <function _remove_ts_or_ds_to_date.<locals>.func>, <class 'sqlglot.expressions.DayOfWeek'>: <function _remove_ts_or_ds_to_date.<locals>.func>, <class 'sqlglot.expressions.DayOfYear'>: <function _remove_ts_or_ds_to_date.<locals>.func>, <class 'sqlglot.expressions.GroupConcat'>: <function MySQL.Generator.<lambda>>, <class 'sqlglot.expressions.ILike'>: <function no_ilike_sql>, <class 'sqlglot.expressions.JSONExtractScalar'>: <function arrow_json_extract_sql>, <class 'sqlglot.expressions.Length'>: <function length_or_char_length_sql>, <class 'sqlglot.expressions.LogicalOr'>: <function rename_func.<locals>.<lambda>>, <class 'sqlglot.expressions.LogicalAnd'>: <function rename_func.<locals>.<lambda>>, <class 'sqlglot.expressions.Max'>: <function max_or_greatest>, <class 'sqlglot.expressions.Min'>: <function min_or_least>, <class 'sqlglot.expressions.Month'>: <function _remove_ts_or_ds_to_date.<locals>.func>, <class 'sqlglot.expressions.NullSafeEQ'>: <function MySQL.Generator.<lambda>>, <class 'sqlglot.expressions.NullSafeNEQ'>: <function MySQL.Generator.<lambda>>, <class 'sqlglot.expressions.NumberToStr'>: <function rename_func.<locals>.<lambda>>, <class 'sqlglot.expressions.Pivot'>: <function no_pivot_sql>, <class 'sqlglot.expressions.Select'>: <function preprocess.<locals>._to_sql>, <class 'sqlglot.expressions.StrPosition'>: <function MySQL.Generator.<lambda>>, <class 'sqlglot.expressions.StrToDate'>: <function _str_to_date_sql>, <class 'sqlglot.expressions.StrToTime'>: <function _str_to_date_sql>, <class 'sqlglot.expressions.Stuff'>: <function rename_func.<locals>.<lambda>>, <class 'sqlglot.expressions.TableSample'>: <function no_tablesample_sql>, <class 'sqlglot.expressions.TimeFromParts'>: <function rename_func.<locals>.<lambda>>, <class 'sqlglot.expressions.TimestampAdd'>: <function date_add_interval_sql.<locals>.func>, <class 'sqlglot.expressions.TimestampDiff'>: <function MySQL.Generator.<lambda>>, <class 'sqlglot.expressions.TimestampSub'>: <function date_add_interval_sql.<locals>.func>, <class 'sqlglot.expressions.TimeStrToUnix'>: <function rename_func.<locals>.<lambda>>, <class 'sqlglot.expressions.TimeStrToTime'>: <function MySQL.Generator.<lambda>>, <class 'sqlglot.expressions.TimeToStr'>: <function _remove_ts_or_ds_to_date.<locals>.func>, <class 'sqlglot.expressions.Trim'>: <function trim_sql>, <class 'sqlglot.expressions.Trunc'>: <function rename_func.<locals>.<lambda>>, <class 'sqlglot.expressions.TryCast'>: <function no_trycast_sql>, <class 'sqlglot.expressions.TsOrDsAdd'>: <function date_add_sql.<locals>.func>, <class 'sqlglot.expressions.TsOrDsDiff'>: <function MySQL.Generator.<lambda>>, <class 'sqlglot.expressions.TsOrDsToDate'>: <function _ts_or_ds_to_date_sql>, <class 'sqlglot.expressions.Unicode'>: <function MySQL.Generator.<lambda>>, <class 'sqlglot.expressions.UnixToTime'>: <function _unix_to_time_sql>, <class 'sqlglot.expressions.Week'>: <function _remove_ts_or_ds_to_date.<locals>.func>, <class 'sqlglot.expressions.WeekOfYear'>: <function _remove_ts_or_ds_to_date.<locals>.func>, <class 'sqlglot.expressions.Year'>: <function _remove_ts_or_ds_to_date.<locals>.func>}
UNSIGNED_TYPE_MAPPING = {<Type.UBIGINT: 'UBIGINT'>: 'BIGINT', <Type.UINT: 'UINT'>: 'INT', <Type.UMEDIUMINT: 'UMEDIUMINT'>: 'MEDIUMINT', <Type.USMALLINT: 'USMALLINT'>: 'SMALLINT', <Type.UTINYINT: 'UTINYINT'>: 'TINYINT', <Type.UDECIMAL: 'UDECIMAL'>: 'DECIMAL', <Type.UDOUBLE: 'UDOUBLE'>: 'DOUBLE'}
TIMESTAMP_TYPE_MAPPING = {<Type.DATETIME2: 'DATETIME2'>: 'DATETIME', <Type.SMALLDATETIME: 'SMALLDATETIME'>: 'DATETIME', <Type.TIMESTAMP: 'TIMESTAMP'>: 'DATETIME', <Type.TIMESTAMPNTZ: 'TIMESTAMPNTZ'>: 'DATETIME', <Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>: 'TIMESTAMP', <Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>: 'TIMESTAMP'}
TYPE_MAPPING = {<Type.DATETIME2: 'DATETIME2'>: 'DATETIME', <Type.NCHAR: 'NCHAR'>: 'CHAR', <Type.NVARCHAR: 'NVARCHAR'>: 'VARCHAR', <Type.INET: 'INET'>: 'INET', <Type.ROWVERSION: 'ROWVERSION'>: 'VARBINARY', <Type.SMALLDATETIME: 'SMALLDATETIME'>: 'DATETIME', <Type.UBIGINT: 'UBIGINT'>: 'BIGINT', <Type.UINT: 'UINT'>: 'INT', <Type.UMEDIUMINT: 'UMEDIUMINT'>: 'MEDIUMINT', <Type.USMALLINT: 'USMALLINT'>: 'SMALLINT', <Type.UTINYINT: 'UTINYINT'>: 'TINYINT', <Type.UDECIMAL: 'UDECIMAL'>: 'DECIMAL', <Type.UDOUBLE: 'UDOUBLE'>: 'DOUBLE', <Type.TIMESTAMP: 'TIMESTAMP'>: 'DATETIME', <Type.TIMESTAMPNTZ: 'TIMESTAMPNTZ'>: 'DATETIME', <Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>: 'TIMESTAMP', <Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>: 'TIMESTAMP'}
PROPERTIES_LOCATION = {<class 'sqlglot.expressions.AllowedValuesProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.AlgorithmProperty'>: <Location.POST_CREATE: 'POST_CREATE'>, <class 'sqlglot.expressions.AutoIncrementProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.AutoRefreshProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.BackupProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.BlockCompressionProperty'>: <Location.POST_NAME: 'POST_NAME'>, <class 'sqlglot.expressions.CharacterSetProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.ChecksumProperty'>: <Location.POST_NAME: 'POST_NAME'>, <class 'sqlglot.expressions.CollateProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.CopyGrantsProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.Cluster'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.ClusteredByProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.DistributedByProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.DuplicateKeyProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.DataBlocksizeProperty'>: <Location.POST_NAME: 'POST_NAME'>, <class 'sqlglot.expressions.DataDeletionProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.DefinerProperty'>: <Location.POST_CREATE: 'POST_CREATE'>, <class 'sqlglot.expressions.DictRange'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.DictProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.DynamicProperty'>: <Location.POST_CREATE: 'POST_CREATE'>, <class 'sqlglot.expressions.DistKeyProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.DistStyleProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.EmptyProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.EncodeProperty'>: <Location.POST_EXPRESSION: 'POST_EXPRESSION'>, <class 'sqlglot.expressions.EngineProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.EnviromentProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.ExecuteAsProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.ExternalProperty'>: <Location.POST_CREATE: 'POST_CREATE'>, <class 'sqlglot.expressions.FallbackProperty'>: <Location.POST_NAME: 'POST_NAME'>, <class 'sqlglot.expressions.FileFormatProperty'>: <Location.POST_WITH: 'POST_WITH'>, <class 'sqlglot.expressions.FreespaceProperty'>: <Location.POST_NAME: 'POST_NAME'>, <class 'sqlglot.expressions.GlobalProperty'>: <Location.POST_CREATE: 'POST_CREATE'>, <class 'sqlglot.expressions.HeapProperty'>: <Location.POST_WITH: 'POST_WITH'>, <class 'sqlglot.expressions.InheritsProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.IcebergProperty'>: <Location.POST_CREATE: 'POST_CREATE'>, <class 'sqlglot.expressions.IncludeProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.InputModelProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.IsolatedLoadingProperty'>: <Location.POST_NAME: 'POST_NAME'>, <class 'sqlglot.expressions.JournalProperty'>: <Location.POST_NAME: 'POST_NAME'>, <class 'sqlglot.expressions.LanguageProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.LikeProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.LocationProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.LockProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.LockingProperty'>: <Location.POST_ALIAS: 'POST_ALIAS'>, <class 'sqlglot.expressions.LogProperty'>: <Location.POST_NAME: 'POST_NAME'>, <class 'sqlglot.expressions.MaterializedProperty'>: <Location.POST_CREATE: 'POST_CREATE'>, <class 'sqlglot.expressions.MergeBlockRatioProperty'>: <Location.POST_NAME: 'POST_NAME'>, <class 'sqlglot.expressions.NoPrimaryIndexProperty'>: <Location.POST_EXPRESSION: 'POST_EXPRESSION'>, <class 'sqlglot.expressions.OnProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.OnCommitProperty'>: <Location.POST_EXPRESSION: 'POST_EXPRESSION'>, <class 'sqlglot.expressions.Order'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.OutputModelProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.PartitionedByProperty'>: <Location.UNSUPPORTED: 'UNSUPPORTED'>, <class 'sqlglot.expressions.PartitionedOfProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.PrimaryKey'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.Property'>: <Location.POST_WITH: 'POST_WITH'>, <class 'sqlglot.expressions.RefreshTriggerProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.RemoteWithConnectionModelProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.ReturnsProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.RollupProperty'>: <Location.UNSUPPORTED: 'UNSUPPORTED'>, <class 'sqlglot.expressions.RowFormatProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.RowFormatDelimitedProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.RowFormatSerdeProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.SampleProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.SchemaCommentProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.SecureProperty'>: <Location.POST_CREATE: 'POST_CREATE'>, <class 'sqlglot.expressions.SecurityProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.SerdeProperties'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.Set'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.SettingsProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.SetProperty'>: <Location.POST_CREATE: 'POST_CREATE'>, <class 'sqlglot.expressions.SetConfigProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.SharingProperty'>: <Location.POST_EXPRESSION: 'POST_EXPRESSION'>, <class 'sqlglot.expressions.SequenceProperties'>: <Location.POST_EXPRESSION: 'POST_EXPRESSION'>, <class 'sqlglot.expressions.TriggerProperties'>: <Location.POST_EXPRESSION: 'POST_EXPRESSION'>, <class 'sqlglot.expressions.SortKeyProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.SqlReadWriteProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.SqlSecurityProperty'>: <Location.POST_CREATE: 'POST_CREATE'>, <class 'sqlglot.expressions.StabilityProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.StorageHandlerProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.StreamingTableProperty'>: <Location.POST_CREATE: 'POST_CREATE'>, <class 'sqlglot.expressions.StrictProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.Tags'>: <Location.POST_WITH: 'POST_WITH'>, <class 'sqlglot.expressions.TemporaryProperty'>: <Location.POST_CREATE: 'POST_CREATE'>, <class 'sqlglot.expressions.ToTableProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.TransientProperty'>: <Location.UNSUPPORTED: 'UNSUPPORTED'>, <class 'sqlglot.expressions.TransformModelProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.MergeTreeTTL'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.UnloggedProperty'>: <Location.POST_CREATE: 'POST_CREATE'>, <class 'sqlglot.expressions.UsingTemplateProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.ViewAttributeProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.VolatileProperty'>: <Location.UNSUPPORTED: 'UNSUPPORTED'>, <class 'sqlglot.expressions.WithDataProperty'>: <Location.POST_EXPRESSION: 'POST_EXPRESSION'>, <class 'sqlglot.expressions.WithJournalTableProperty'>: <Location.POST_NAME: 'POST_NAME'>, <class 'sqlglot.expressions.WithProcedureOptions'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.WithSchemaBindingProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.WithSystemVersioningProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.ForceProperty'>: <Location.POST_CREATE: 'POST_CREATE'>, <class 'sqlglot.expressions.PartitionByRangeProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.PartitionByListProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>}
LIMIT_FETCH = 'LIMIT'
LIMIT_ONLY_LITERALS = True
CHAR_CAST_MAPPING = {<Type.LONGTEXT: 'LONGTEXT'>: 'CHAR', <Type.LONGBLOB: 'LONGBLOB'>: 'CHAR', <Type.MEDIUMBLOB: 'MEDIUMBLOB'>: 'CHAR', <Type.MEDIUMTEXT: 'MEDIUMTEXT'>: 'CHAR', <Type.TEXT: 'TEXT'>: 'CHAR', <Type.TINYBLOB: 'TINYBLOB'>: 'CHAR', <Type.TINYTEXT: 'TINYTEXT'>: 'CHAR', <Type.VARCHAR: 'VARCHAR'>: 'CHAR'}
SIGNED_CAST_MAPPING = {<Type.BIGINT: 'BIGINT'>: 'SIGNED', <Type.BOOLEAN: 'BOOLEAN'>: 'SIGNED', <Type.INT: 'INT'>: 'SIGNED', <Type.SMALLINT: 'SMALLINT'>: 'SIGNED', <Type.TINYINT: 'TINYINT'>: 'SIGNED', <Type.MEDIUMINT: 'MEDIUMINT'>: 'SIGNED'}
CAST_MAPPING = {<Type.LONGTEXT: 'LONGTEXT'>: 'CHAR', <Type.LONGBLOB: 'LONGBLOB'>: 'CHAR', <Type.MEDIUMBLOB: 'MEDIUMBLOB'>: 'CHAR', <Type.MEDIUMTEXT: 'MEDIUMTEXT'>: 'CHAR', <Type.TEXT: 'TEXT'>: 'CHAR', <Type.TINYBLOB: 'TINYBLOB'>: 'CHAR', <Type.TINYTEXT: 'TINYTEXT'>: 'CHAR', <Type.VARCHAR: 'VARCHAR'>: 'CHAR', <Type.BIGINT: 'BIGINT'>: 'SIGNED', <Type.BOOLEAN: 'BOOLEAN'>: 'SIGNED', <Type.INT: 'INT'>: 'SIGNED', <Type.SMALLINT: 'SMALLINT'>: 'SIGNED', <Type.TINYINT: 'TINYINT'>: 'SIGNED', <Type.MEDIUMINT: 'MEDIUMINT'>: 'SIGNED', <Type.UBIGINT: 'UBIGINT'>: 'UNSIGNED'}
TIMESTAMP_FUNC_TYPES = {<Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, <Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>}
RESERVED_KEYWORDS = {'union', 'row_number', 'over', 'asensitive', 'utc_time', 'sql_small_result', 'sql_calc_found_rows', 'range', 'tinyblob', 'continue', 'insert', 'integer', 'outfile', 'empty', 'sensitive', 'exit', 'deterministic', 'varying', 'replace', 'current_user', 'from', 'keys', 'sql', 'bigint', 'call', 'inner', 'mediumtext', 'current_time', 'rank', 'cross', 'where', 'character', 'declare', 'alter', 'int', 'natural', 'order', 'group', 'by', 'stored', 'schemas', 'maxvalue', 'reads', 'insensitive', 'leading', 'values', 'day_hour', 'and', 'xor', 'key', 'long', 'drop', 'current_date', 'first_value', 'constraint', 'all', 'localtimestamp', 'rename', 'to', 'outer', 'day_second', 'escaped', 'modifies', 'case', 'resignal', 'as', 'distinct', 'intersect', 'desc', 'option', 'json_table', 'cursor', 'enclosed', 'show', 'both', 'having', 'in', 'sqlstate', 'ssl', 'master_ssl_verify_server_cert', 'linear', 'float', 'use', 'analyze', 'percent_rank', 'int8', 'real', 'specific', 'for', 'of', 'right', 'signal', 'not', 'float4', 'sqlwarning', 'is', 'optionally', 'get', 'longblob', 'spatial', 'io_before_gtids', 'into', 'lead', 'inout', 'fetch', 'loop', 'select', 'int4', 'minute_second', 'grant', 'sql_big_result', 'virtual', 'infile', 'float8', 'varbinary', 'left', 'database', 'undo', 'default', 'lag', 'update', 'blob', 'mediumblob', 'grouping', 'terminated', 'explain', 'force', 'localtime', 'condition', 'optimize', 'describe', 'unsigned', 'release', 'rlike', 'ntile', 'rows', 'high_priority', 'div', 'generated', 'restrict', 'middleint', 'accessible', 'change', 'dense_rank', 'dec', 'separator', 'hour_minute', 'require', 'write', 'varchar', 'while', 'else', 'char', 'match', 'procedure', 'check', 'primary', 'groups', 'trigger', 'dual', 'last_value', 'create', 'exists', 'tinytext', 'unique', 'schema', 'unlock', 'revoke', 'int1', 'on', 'binary', 'fulltext', 'lateral', 'row', 'except', 'leave', 'elseif', 'mod', 'low_priority', 'hour_second', 'null', 'before', 'tinyint', 'references', 'true', 'convert', 'return', 'ignore', 'starting', 'longtext', 'then', 'limit', 'cume_dist', 'optimizer_costs', 'decimal', 'table', 'smallint', 'master_bind', 'minute_microsecond', 'purge', 'load', 'collate', 'partition', 'system', 'distinctrow', 'false', 'or', 'usage', 'cube', 'index', 'sqlexception', 'asc', 'lock', 'lines', 'between', 'regexp', 'recursive', 'no_write_to_binlog', 'out', 'int3', 'function', 'varcharacter', 'mediumint', 'foreign', 'day_minute', 'trailing', 'straight_join', 'using', 'delayed', 'iterate', 'numeric', 'io_after_gtids', 'read_write', 'int2', 'when', 'repeat', 'set', 'second_microsecond', 'delete', 'kill', 'cascade', 'with', 'interval', 'utc_timestamp', 'nth_value', 'hour_microsecond', 'like', 'double', 'zerofill', 'utc_date', 'databases', 'read', 'add', 'year_month', 'precision', 'window', 'column', 'join', 'if', 'current_timestamp', 'each', 'day_microsecond'}
def computedcolumnconstraint_sql(self, expression: sqlglot.expressions.ComputedColumnConstraint) -> str:
1260        def computedcolumnconstraint_sql(self, expression: exp.ComputedColumnConstraint) -> str:
1261            persisted = "STORED" if expression.args.get("persisted") else "VIRTUAL"
1262            return f"GENERATED ALWAYS AS ({self.sql(expression.this.unnest())}) {persisted}"
def array_sql(self, expression: sqlglot.expressions.Array) -> str:
1264        def array_sql(self, expression: exp.Array) -> str:
1265            self.unsupported("Arrays are not supported by MySQL")
1266            return self.function_fallback_sql(expression)
def arraycontainsall_sql(self, expression: sqlglot.expressions.ArrayContainsAll) -> str:
1268        def arraycontainsall_sql(self, expression: exp.ArrayContainsAll) -> str:
1269            self.unsupported("Array operations are not supported by MySQL")
1270            return self.function_fallback_sql(expression)
def dpipe_sql(self, expression: sqlglot.expressions.DPipe) -> str:
1272        def dpipe_sql(self, expression: exp.DPipe) -> str:
1273            return self.func("CONCAT", *expression.flatten())
def extract_sql(self, expression: sqlglot.expressions.Extract) -> str:
1275        def extract_sql(self, expression: exp.Extract) -> str:
1276            unit = expression.name
1277            if unit and unit.lower() == "epoch":
1278                return self.func("UNIX_TIMESTAMP", expression.expression)
1279
1280            return super().extract_sql(expression)
def datatype_sql(self, expression: sqlglot.expressions.DataType) -> str:
1282        def datatype_sql(self, expression: exp.DataType) -> str:
1283            if (
1284                self.VARCHAR_REQUIRES_SIZE
1285                and expression.is_type(exp.DataType.Type.VARCHAR)
1286                and not expression.expressions
1287            ):
1288                # `VARCHAR` must always have a size - if it doesn't, we always generate `TEXT`
1289                return "TEXT"
1290
1291            # https://dev.mysql.com/doc/refman/8.0/en/numeric-type-syntax.html
1292            result = super().datatype_sql(expression)
1293            if expression.this in self.UNSIGNED_TYPE_MAPPING:
1294                result = f"{result} UNSIGNED"
1295
1296            return result
def jsonarraycontains_sql(self, expression: sqlglot.expressions.JSONArrayContains) -> str:
1298        def jsonarraycontains_sql(self, expression: exp.JSONArrayContains) -> str:
1299            return f"{self.sql(expression, 'this')} MEMBER OF({self.sql(expression, 'expression')})"
def cast_sql( self, expression: sqlglot.expressions.Cast, safe_prefix: Optional[str] = None) -> str:
1301        def cast_sql(self, expression: exp.Cast, safe_prefix: t.Optional[str] = None) -> str:
1302            if expression.to.this in self.TIMESTAMP_FUNC_TYPES:
1303                return self.func("TIMESTAMP", expression.this)
1304
1305            to = self.CAST_MAPPING.get(expression.to.this)
1306
1307            if to:
1308                expression.to.set("this", to)
1309            return super().cast_sql(expression)
def show_sql(self, expression: sqlglot.expressions.Show) -> str:
1311        def show_sql(self, expression: exp.Show) -> str:
1312            this = f" {expression.name}"
1313            full = " FULL" if expression.args.get("full") else ""
1314            global_ = " GLOBAL" if expression.args.get("global_") else ""
1315
1316            target = self.sql(expression, "target")
1317            target = f" {target}" if target else ""
1318            if expression.name in ("COLUMNS", "INDEX"):
1319                target = f" FROM{target}"
1320            elif expression.name == "GRANTS":
1321                target = f" FOR{target}"
1322            elif expression.name in ("LINKS", "PARTITIONS"):
1323                target = f" ON{target}" if target else ""
1324            elif expression.name == "PROJECTIONS":
1325                target = f" ON TABLE{target}" if target else ""
1326
1327            db = self._prefixed_sql("FROM", expression, "db")
1328
1329            like = self._prefixed_sql("LIKE", expression, "like")
1330            where = self.sql(expression, "where")
1331
1332            types = self.expressions(expression, key="types")
1333            types = f" {types}" if types else types
1334            query = self._prefixed_sql("FOR QUERY", expression, "query")
1335
1336            if expression.name == "PROFILE":
1337                offset = self._prefixed_sql("OFFSET", expression, "offset")
1338                limit = self._prefixed_sql("LIMIT", expression, "limit")
1339            else:
1340                offset = ""
1341                limit = self._oldstyle_limit_sql(expression)
1342
1343            log = self._prefixed_sql("IN", expression, "log")
1344            position = self._prefixed_sql("FROM", expression, "position")
1345
1346            channel = self._prefixed_sql("FOR CHANNEL", expression, "channel")
1347
1348            if expression.name == "ENGINE":
1349                mutex_or_status = " MUTEX" if expression.args.get("mutex") else " STATUS"
1350            else:
1351                mutex_or_status = ""
1352
1353            for_table = self._prefixed_sql("FOR TABLE", expression, "for_table")
1354            for_group = self._prefixed_sql("FOR GROUP", expression, "for_group")
1355            for_user = self._prefixed_sql("FOR USER", expression, "for_user")
1356            for_role = self._prefixed_sql("FOR ROLE", expression, "for_role")
1357            into_outfile = self._prefixed_sql("INTO OUTFILE", expression, "into_outfile")
1358            json = " JSON" if expression.args.get("json") else ""
1359
1360            return f"SHOW{full}{global_}{this}{json}{target}{for_table}{types}{db}{query}{log}{position}{channel}{mutex_or_status}{like}{where}{offset}{limit}{for_group}{for_user}{for_role}{into_outfile}"
def alterrename_sql( self, expression: sqlglot.expressions.AlterRename, include_to: bool = True) -> str:
1362        def alterrename_sql(self, expression: exp.AlterRename, include_to: bool = True) -> str:
1363            """To avoid TO keyword in ALTER ... RENAME statements.
1364            It's moved from Doris, because it's the same for all MySQL, Doris, and StarRocks.
1365            """
1366            return super().alterrename_sql(expression, include_to=False)

To avoid TO keyword in ALTER ... RENAME statements. It's moved from Doris, because it's the same for all MySQL, Doris, and StarRocks.

def altercolumn_sql(self, expression: sqlglot.expressions.AlterColumn) -> str:
1368        def altercolumn_sql(self, expression: exp.AlterColumn) -> str:
1369            dtype = self.sql(expression, "dtype")
1370            if not dtype:
1371                return super().altercolumn_sql(expression)
1372
1373            this = self.sql(expression, "this")
1374            return f"MODIFY COLUMN {this} {dtype}"
def timestamptrunc_sql(self, expression: sqlglot.expressions.TimestampTrunc) -> str:
1388        def timestamptrunc_sql(self, expression: exp.TimestampTrunc) -> str:
1389            unit = expression.args.get("unit")
1390
1391            # Pick an old-enough date to avoid negative timestamp diffs
1392            start_ts = "'0000-01-01 00:00:00'"
1393
1394            # Source: https://stackoverflow.com/a/32955740
1395            timestamp_diff = build_date_delta(exp.TimestampDiff)([unit, start_ts, expression.this])
1396            interval = exp.Interval(this=timestamp_diff, unit=unit)
1397            dateadd = build_date_delta_with_interval(exp.DateAdd)([start_ts, interval])
1398
1399            return self.sql(dateadd)
def converttimezone_sql(self, expression: sqlglot.expressions.ConvertTimezone) -> str:
1401        def converttimezone_sql(self, expression: exp.ConvertTimezone) -> str:
1402            from_tz = expression.args.get("source_tz")
1403            to_tz = expression.args.get("target_tz")
1404            dt = expression.args.get("timestamp")
1405
1406            return self.func("CONVERT_TZ", dt, from_tz, to_tz)
def attimezone_sql(self, expression: sqlglot.expressions.AtTimeZone) -> str:
1408        def attimezone_sql(self, expression: exp.AtTimeZone) -> str:
1409            self.unsupported("AT TIME ZONE is not supported by MySQL")
1410            return self.sql(expression.this)
def isascii_sql(self, expression: sqlglot.expressions.IsAscii) -> str:
1412        def isascii_sql(self, expression: exp.IsAscii) -> str:
1413            return f"REGEXP_LIKE({self.sql(expression.this)}, '^[[:ascii:]]*$')"
def ignorenulls_sql(self, expression: sqlglot.expressions.IgnoreNulls) -> str:
1415        def ignorenulls_sql(self, expression: exp.IgnoreNulls) -> str:
1416            # https://dev.mysql.com/doc/refman/8.4/en/window-function-descriptions.html
1417            self.unsupported("MySQL does not support IGNORE NULLS.")
1418            return self.sql(expression.this)
@unsupported_args('this')
def currentschema_sql(self, expression: sqlglot.expressions.CurrentSchema) -> str:
1420        @unsupported_args("this")
1421        def currentschema_sql(self, expression: exp.CurrentSchema) -> str:
1422            return self.func("SCHEMA")
def partition_sql(self, expression: sqlglot.expressions.Partition) -> str:
1424        def partition_sql(self, expression: exp.Partition) -> str:
1425            parent = expression.parent
1426            if isinstance(parent, (exp.PartitionByRangeProperty, exp.PartitionByListProperty)):
1427                return self.expressions(expression, flat=True)
1428            return super().partition_sql(expression)
def partitionbyrangeproperty_sql(self, expression: sqlglot.expressions.PartitionByRangeProperty) -> str:
1437        def partitionbyrangeproperty_sql(self, expression: exp.PartitionByRangeProperty) -> str:
1438            return self._partition_by_sql(expression, "RANGE")
def partitionbylistproperty_sql(self, expression: sqlglot.expressions.PartitionByListProperty) -> str:
1440        def partitionbylistproperty_sql(self, expression: exp.PartitionByListProperty) -> str:
1441            return self._partition_by_sql(expression, "LIST")
def partitionlist_sql(self, expression: sqlglot.expressions.PartitionList) -> str:
1443        def partitionlist_sql(self, expression: exp.PartitionList) -> str:
1444            name = self.sql(expression, "this")
1445            values = self.expressions(expression, flat=True)
1446            return f"PARTITION {name} VALUES IN ({values})"
def partitionrange_sql(self, expression: sqlglot.expressions.PartitionRange) -> str:
1448        def partitionrange_sql(self, expression: exp.PartitionRange) -> str:
1449            name = self.sql(expression, "this")
1450            values = self.expressions(expression, flat=True)
1451            return f"PARTITION {name} VALUES LESS THAN ({values})"
SELECT_KINDS: Tuple[str, ...] = ()
TRY_SUPPORTED = False
SUPPORTS_UESCAPE = False
SUPPORTS_DECODE_CASE = False
AFTER_HAVING_MODIFIER_TRANSFORMS = {'windows': <function Generator.<lambda>>, 'qualify': <function Generator.<lambda>>}
Inherited Members
sqlglot.generator.Generator
Generator
IGNORE_NULLS_IN_FUNC
EXCEPT_INTERSECT_SUPPORT_ALL_CLAUSE
CREATE_FUNCTION_RETURN_AS
MATCHED_BY_SOURCE
SINGLE_STRING_INTERVAL
RENAME_TABLE_WITH_DB
GROUPINGS_SEP
INDEX_ON
INOUT_SEPARATOR
DIRECTED_JOINS
QUERY_HINTS
IS_BOOL_ALLOWED
LIMIT_IS_TOP
RETURNING_END
EXTRACT_ALLOWS_QUOTES
TZ_TO_WITH_TIME_ZONE
ALTER_TABLE_INCLUDE_COLUMN_KEYWORD
UNNEST_WITH_ORDINALITY
AGGREGATE_FILTER_SUPPORTED
SEMI_ANTI_JOIN_WITH_SIDE
COMPUTED_COLUMN_WITH_TYPE
SUPPORTS_TABLE_COPY
TABLESAMPLE_REQUIRES_PARENS
TABLESAMPLE_SIZE_IS_ROWS
TABLESAMPLE_KEYWORDS
TABLESAMPLE_WITH_METHOD
TABLESAMPLE_SEED_KEYWORD
COLLATE_IS_FUNC
DATA_TYPE_SPECIFIERS_ALLOWED
ENSURE_BOOLS
CTE_RECURSIVE_KEYWORD_REQUIRED
SUPPORTS_SINGLE_ARG_CONCAT
SUPPORTS_TABLE_ALIAS_COLUMNS
UNPIVOT_ALIASES_ARE_IDENTIFIERS
INSERT_OVERWRITE
SUPPORTS_SELECT_INTO
SUPPORTS_UNLOGGED_TABLES
SUPPORTS_CREATE_TABLE_LIKE
LIKE_PROPERTY_INSIDE_SCHEMA
MULTI_ARG_DISTINCT
JSON_PATH_SINGLE_QUOTE_ESCAPE
SUPPORTED_JSON_PATH_PARTS
CAN_IMPLEMENT_ARRAY_ANY
SUPPORTS_WINDOW_EXCLUDE
SET_OP_MODIFIERS
COPY_PARAMS_ARE_WRAPPED
COPY_PARAMS_EQ_REQUIRED
COPY_HAS_INTO_KEYWORD
UNICODE_SUBSTITUTE
STAR_EXCEPT
HEX_FUNC
WITH_PROPERTIES_PREFIX
QUOTE_JSON_PATH
SUPPORTS_EXPLODING_PROJECTIONS
ARRAY_CONCAT_IS_VAR_LEN
SUPPORTS_CONVERT_TIMEZONE
SUPPORTS_UNIX_SECONDS
ALTER_SET_WRAPPED
NORMALIZE_EXTRACT_DATE_PARTS
ARRAY_SIZE_NAME
ALTER_SET_TYPE
ARRAY_SIZE_DIM_REQUIRED
SUPPORTS_BETWEEN_FLAGS
SUPPORTS_LIKE_QUANTIFIERS
MATCH_AGAINST_TABLE_PREFIX
SET_ASSIGNMENT_REQUIRES_VARIABLE_KEYWORD
DECLARE_DEFAULT_ASSIGNMENT
STAR_EXCLUDE_REQUIRES_DERIVED_TABLE
UNSUPPORTED_TYPES
TIME_PART_SINGULARS
TOKEN_MAPPING
STRUCT_DELIMITER
PARAMETER_TOKEN
NAMED_PLACEHOLDER_TOKEN
EXPRESSION_PRECEDES_PROPERTIES_CREATABLES
WITH_SEPARATED_COMMENTS
EXCLUDE_COMMENTS
UNWRAPPED_INTERVAL_VALUES
PARAMETERIZABLE_TEXT_TYPES
EXPRESSIONS_WITHOUT_NESTED_CTES
RESPECT_IGNORE_NULLS_UNSUPPORTED_EXPRESSIONS
SAFE_JSON_PATH_KEY_RE
SENTINEL_LINE_BREAK
pretty
identify
normalize
pad
unsupported_level
max_unsupported
leading_comma
max_text_width
comments
dialect
normalize_functions
unsupported_messages
generate
preprocess
unsupported
sep
seg
sanitize_comment
maybe_comment
wrap
no_identify
normalize_func
indent
sql
uncache_sql
cache_sql
characterset_sql
column_parts
column_sql
pseudocolumn_sql
columnposition_sql
columndef_sql
columnconstraint_sql
autoincrementcolumnconstraint_sql
compresscolumnconstraint_sql
generatedasidentitycolumnconstraint_sql
generatedasrowcolumnconstraint_sql
periodforsystemtimeconstraint_sql
notnullcolumnconstraint_sql
primarykeycolumnconstraint_sql
uniquecolumnconstraint_sql
inoutcolumnconstraint_sql
createable_sql
create_sql
sequenceproperties_sql
triggerproperties_sql
triggerreferencing_sql
triggerevent_sql
clone_sql
describe_sql
heredoc_sql
prepend_ctes
with_sql
cte_sql
tablealias_sql
bitstring_sql
hexstring_sql
bytestring_sql
unicodestring_sql
rawstring_sql
datatypeparam_sql
directory_sql
delete_sql
drop_sql
set_operation
set_operations
fetch_sql
limitoptions_sql
filter_sql
hint_sql
indexparameters_sql
index_sql
identifier_sql
hex_sql
lowerhex_sql
inputoutputformat_sql
national_sql
properties_sql
root_properties
properties
with_properties
locate_properties
property_name
property_sql
likeproperty_sql
fallbackproperty_sql
journalproperty_sql
freespaceproperty_sql
checksumproperty_sql
mergeblockratioproperty_sql
datablocksizeproperty_sql
blockcompressionproperty_sql
isolatedloadingproperty_sql
partitionboundspec_sql
partitionedofproperty_sql
lockingproperty_sql
withdataproperty_sql
withsystemversioningproperty_sql
insert_sql
introducer_sql
kill_sql
pseudotype_sql
objectidentifier_sql
onconflict_sql
returning_sql
rowformatdelimitedproperty_sql
withtablehint_sql
indextablehint_sql
historicaldata_sql
table_parts
table_sql
tablefromrows_sql
tablesample_sql
pivot_sql
version_sql
tuple_sql
update_sql
values_sql
var_sql
into_sql
from_sql
groupingsets_sql
rollup_sql
rollupindex_sql
rollupproperty_sql
cube_sql
group_sql
having_sql
connect_sql
prior_sql
join_sql
lambda_sql
lateral_op
lateral_sql
limit_sql
offset_sql
setitem_sql
set_sql
queryband_sql
pragma_sql
lock_sql
literal_sql
escape_str
loaddata_sql
null_sql
boolean_sql
booland_sql
boolor_sql
order_sql
withfill_sql
cluster_sql
distribute_sql
sort_sql
ordered_sql
matchrecognizemeasure_sql
matchrecognize_sql
query_modifiers
options_modifier
for_modifiers
queryoption_sql
offset_limit_modifiers
after_limit_modifiers
select_sql
schema_sql
schema_columns_sql
star_sql
parameter_sql
sessionparameter_sql
placeholder_sql
subquery_sql
qualify_sql
unnest_sql
prewhere_sql
where_sql
window_sql
partition_by_sql
windowspec_sql
withingroup_sql
between_sql
bracket_offset_expressions
bracket_sql
all_sql
any_sql
exists_sql
case_sql
constraint_sql
nextvaluefor_sql
trim_sql
convert_concat_args
concat_sql
concatws_sql
check_sql
foreignkey_sql
primarykey_sql
if_sql
matchagainst_sql
jsonkeyvalue_sql
jsonpath_sql
json_path_part
formatjson_sql
formatphrase_sql
jsonobject_sql
jsonobjectagg_sql
jsonarray_sql
jsonarrayagg_sql
jsoncolumndef_sql
jsonschema_sql
jsontable_sql
openjsoncolumndef_sql
openjson_sql
in_sql
in_unnest_op
interval_sql
return_sql
reference_sql
anonymous_sql
paren_sql
neg_sql
not_sql
alias_sql
pivotalias_sql
aliases_sql
atindex_sql
fromtimezone_sql
add_sql
and_sql
or_sql
xor_sql
connector_sql
bitwiseand_sql
bitwiseleftshift_sql
bitwisenot_sql
bitwiseor_sql
bitwiserightshift_sql
bitwisexor_sql
strtotime_sql
currentdate_sql
collate_sql
command_sql
comment_sql
mergetreettlaction_sql
mergetreettl_sql
transaction_sql
commit_sql
rollback_sql
alterindex_sql
alterdiststyle_sql
altersortkey_sql
renamecolumn_sql
alterset_sql
alter_sql
altersession_sql
add_column_sql
droppartition_sql
addconstraint_sql
addpartition_sql
distinct_sql
respectnulls_sql
havingmax_sql
intdiv_sql
div_sql
safedivide_sql
overlaps_sql
distance_sql
dot_sql
eq_sql
propertyeq_sql
escape_sql
glob_sql
gt_sql
gte_sql
is_sql
like_sql
ilike_sql
match_sql
similarto_sql
lt_sql
lte_sql
mod_sql
mul_sql
neq_sql
nullsafeeq_sql
nullsafeneq_sql
sub_sql
trycast_sql
jsoncast_sql
try_sql
log_sql
use_sql
binary
ceil_floor
function_fallback_sql
func
format_args
too_wide
format_time
expressions
op_expressions
naked_property
tag_sql
token_sql
userdefinedfunction_sql
joinhint_sql
kwarg_sql
when_sql
whens_sql
merge_sql
tochar_sql
tonumber_sql
dictproperty_sql
dictrange_sql
dictsubproperty_sql
duplicatekeyproperty_sql
uniquekeyproperty_sql
distributedbyproperty_sql
oncluster_sql
clusteredbyproperty_sql
anyvalue_sql
querytransform_sql
indexconstraintoption_sql
checkcolumnconstraint_sql
indexcolumnconstraint_sql
nvl2_sql
comprehension_sql
columnprefix_sql
opclass_sql
predict_sql
generateembedding_sql
mltranslate_sql
mlforecast_sql
featuresattime_sql
vectorsearch_sql
forin_sql
refresh_sql
toarray_sql
tsordstotime_sql
tsordstotimestamp_sql
tsordstodatetime_sql
tsordstodate_sql
unixdate_sql
lastday_sql
dateadd_sql
arrayany_sql
struct_sql
truncatetable_sql
convert_sql
copyparameter_sql
credentials_sql
copy_sql
semicolon_sql
datadeletionproperty_sql
maskingpolicycolumnconstraint_sql
gapfill_sql
scope_resolution
scoperesolution_sql
parsejson_sql
rand_sql
changes_sql
pad_sql
summarize_sql
explodinggenerateseries_sql
json_sql
jsonvalue_sql
conditionalinsert_sql
multitableinserts_sql
oncondition_sql
jsonextractquote_sql
jsonexists_sql
arrayagg_sql
slice_sql
apply_sql
grant_sql
revoke_sql
grantprivilege_sql
grantprincipal_sql
columns_sql
overlay_sql
todouble_sql
string_sql
median_sql
overflowtruncatebehavior_sql
unixseconds_sql
arraysize_sql
attach_sql
detach_sql
attachoption_sql
watermarkcolumnconstraint_sql
encodeproperty_sql
includeproperty_sql
xmlelement_sql
xmlkeyvalueoption_sql
partitionbyrangepropertydynamic_sql
unpivotcolumns_sql
analyzesample_sql
analyzestatistics_sql
analyzehistogram_sql
analyzedelete_sql
analyzelistchainedrows_sql
analyzevalidate_sql
analyze_sql
xmltable_sql
xmlnamespace_sql
export_sql
declare_sql
declareitem_sql
recursivewithsearch_sql
parameterizedagg_sql
anonymousaggfunc_sql
combinedaggfunc_sql
combinedparameterizedagg_sql
install_sql
get_put_sql
translatecharacters_sql
decodecase_sql
semanticview_sql
getextract_sql
datefromunixdate_sql
space_sql
buildproperty_sql
refreshtriggerproperty_sql
modelattribute_sql
directorystage_sql
uuid_sql
initcap_sql
localtime_sql
localtimestamp_sql
weekstart_sql
chr_sql
block_sql
storedprocedure_sql
ifblock_sql
whileblock_sql
execute_sql
executesql_sql