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            "DATE": lambda args: exp.TsOrDsToDate(this=seq_get(args, 0)),
 342            "DATE_ADD": build_date_delta_with_interval(exp.DateAdd),
 343            "DATE_FORMAT": build_formatted_time(exp.TimeToStr, "mysql"),
 344            "DATE_SUB": build_date_delta_with_interval(exp.DateSub),
 345            "DAY": lambda args: exp.Day(this=exp.TsOrDsToDate(this=seq_get(args, 0))),
 346            "DAYOFMONTH": lambda args: exp.DayOfMonth(this=exp.TsOrDsToDate(this=seq_get(args, 0))),
 347            "DAYOFWEEK": lambda args: exp.DayOfWeek(this=exp.TsOrDsToDate(this=seq_get(args, 0))),
 348            "DAYOFYEAR": lambda args: exp.DayOfYear(this=exp.TsOrDsToDate(this=seq_get(args, 0))),
 349            "FORMAT": exp.NumberToStr.from_arg_list,
 350            "FROM_UNIXTIME": build_formatted_time(exp.UnixToTime, "mysql"),
 351            "ISNULL": isnull_to_is_null,
 352            "LENGTH": lambda args: exp.Length(this=seq_get(args, 0), binary=True),
 353            "MAKETIME": exp.TimeFromParts.from_arg_list,
 354            "MONTH": lambda args: exp.Month(this=exp.TsOrDsToDate(this=seq_get(args, 0))),
 355            "MONTHNAME": lambda args: exp.TimeToStr(
 356                this=exp.TsOrDsToDate(this=seq_get(args, 0)),
 357                format=exp.Literal.string("%B"),
 358            ),
 359            "SCHEMA": exp.CurrentSchema.from_arg_list,
 360            "DATABASE": exp.CurrentSchema.from_arg_list,
 361            "STR_TO_DATE": _str_to_date,
 362            "TIMESTAMPDIFF": build_date_delta(exp.TimestampDiff),
 363            "TO_DAYS": lambda args: exp.paren(
 364                exp.DateDiff(
 365                    this=exp.TsOrDsToDate(this=seq_get(args, 0)),
 366                    expression=exp.TsOrDsToDate(this=exp.Literal.string("0000-01-01")),
 367                    unit=exp.var("DAY"),
 368                )
 369                + 1
 370            ),
 371            "WEEK": lambda args: exp.Week(
 372                this=exp.TsOrDsToDate(this=seq_get(args, 0)), mode=seq_get(args, 1)
 373            ),
 374            "WEEKOFYEAR": lambda args: exp.WeekOfYear(this=exp.TsOrDsToDate(this=seq_get(args, 0))),
 375            "YEAR": lambda args: exp.Year(this=exp.TsOrDsToDate(this=seq_get(args, 0))),
 376        }
 377
 378        FUNCTION_PARSERS = {
 379            **parser.Parser.FUNCTION_PARSERS,
 380            "GROUP_CONCAT": lambda self: self._parse_group_concat(),
 381            # https://dev.mysql.com/doc/refman/5.7/en/miscellaneous-functions.html#function_values
 382            "VALUES": lambda self: self.expression(
 383                exp.Anonymous, this="VALUES", expressions=[self._parse_id_var()]
 384            ),
 385            "JSON_VALUE": lambda self: self._parse_json_value(),
 386            "SUBSTR": lambda self: self._parse_substring(),
 387        }
 388
 389        STATEMENT_PARSERS = {
 390            **parser.Parser.STATEMENT_PARSERS,
 391            TokenType.SHOW: lambda self: self._parse_show(),
 392        }
 393
 394        SHOW_PARSERS = {
 395            "BINARY LOGS": _show_parser("BINARY LOGS"),
 396            "MASTER LOGS": _show_parser("BINARY LOGS"),
 397            "BINLOG EVENTS": _show_parser("BINLOG EVENTS"),
 398            "CHARACTER SET": _show_parser("CHARACTER SET"),
 399            "CHARSET": _show_parser("CHARACTER SET"),
 400            "COLLATION": _show_parser("COLLATION"),
 401            "FULL COLUMNS": _show_parser("COLUMNS", target="FROM", full=True),
 402            "COLUMNS": _show_parser("COLUMNS", target="FROM"),
 403            "CREATE DATABASE": _show_parser("CREATE DATABASE", target=True),
 404            "CREATE EVENT": _show_parser("CREATE EVENT", target=True),
 405            "CREATE FUNCTION": _show_parser("CREATE FUNCTION", target=True),
 406            "CREATE PROCEDURE": _show_parser("CREATE PROCEDURE", target=True),
 407            "CREATE TABLE": _show_parser("CREATE TABLE", target=True),
 408            "CREATE TRIGGER": _show_parser("CREATE TRIGGER", target=True),
 409            "CREATE VIEW": _show_parser("CREATE VIEW", target=True),
 410            "DATABASES": _show_parser("DATABASES"),
 411            "SCHEMAS": _show_parser("DATABASES"),
 412            "ENGINE": _show_parser("ENGINE", target=True),
 413            "STORAGE ENGINES": _show_parser("ENGINES"),
 414            "ENGINES": _show_parser("ENGINES"),
 415            "ERRORS": _show_parser("ERRORS"),
 416            "EVENTS": _show_parser("EVENTS"),
 417            "FUNCTION CODE": _show_parser("FUNCTION CODE", target=True),
 418            "FUNCTION STATUS": _show_parser("FUNCTION STATUS"),
 419            "GRANTS": _show_parser("GRANTS", target="FOR"),
 420            "INDEX": _show_parser("INDEX", target="FROM"),
 421            "MASTER STATUS": _show_parser("MASTER STATUS"),
 422            "OPEN TABLES": _show_parser("OPEN TABLES"),
 423            "PLUGINS": _show_parser("PLUGINS"),
 424            "PROCEDURE CODE": _show_parser("PROCEDURE CODE", target=True),
 425            "PROCEDURE STATUS": _show_parser("PROCEDURE STATUS"),
 426            "PRIVILEGES": _show_parser("PRIVILEGES"),
 427            "FULL PROCESSLIST": _show_parser("PROCESSLIST", full=True),
 428            "PROCESSLIST": _show_parser("PROCESSLIST"),
 429            "PROFILE": _show_parser("PROFILE"),
 430            "PROFILES": _show_parser("PROFILES"),
 431            "RELAYLOG EVENTS": _show_parser("RELAYLOG EVENTS"),
 432            "REPLICAS": _show_parser("REPLICAS"),
 433            "SLAVE HOSTS": _show_parser("REPLICAS"),
 434            "REPLICA STATUS": _show_parser("REPLICA STATUS"),
 435            "SLAVE STATUS": _show_parser("REPLICA STATUS"),
 436            "GLOBAL STATUS": _show_parser("STATUS", global_=True),
 437            "SESSION STATUS": _show_parser("STATUS"),
 438            "STATUS": _show_parser("STATUS"),
 439            "TABLE STATUS": _show_parser("TABLE STATUS"),
 440            "FULL TABLES": _show_parser("TABLES", full=True),
 441            "TABLES": _show_parser("TABLES"),
 442            "TRIGGERS": _show_parser("TRIGGERS"),
 443            "GLOBAL VARIABLES": _show_parser("VARIABLES", global_=True),
 444            "SESSION VARIABLES": _show_parser("VARIABLES"),
 445            "VARIABLES": _show_parser("VARIABLES"),
 446            "WARNINGS": _show_parser("WARNINGS"),
 447        }
 448
 449        PROPERTY_PARSERS = {
 450            **parser.Parser.PROPERTY_PARSERS,
 451            "LOCK": lambda self: self._parse_property_assignment(exp.LockProperty),
 452            "PARTITION BY": lambda self: self._parse_partition_property(),
 453        }
 454
 455        SET_PARSERS = {
 456            **parser.Parser.SET_PARSERS,
 457            "PERSIST": lambda self: self._parse_set_item_assignment("PERSIST"),
 458            "PERSIST_ONLY": lambda self: self._parse_set_item_assignment("PERSIST_ONLY"),
 459            "CHARACTER SET": lambda self: self._parse_set_item_charset("CHARACTER SET"),
 460            "CHARSET": lambda self: self._parse_set_item_charset("CHARACTER SET"),
 461            "NAMES": lambda self: self._parse_set_item_names(),
 462        }
 463
 464        CONSTRAINT_PARSERS = {
 465            **parser.Parser.CONSTRAINT_PARSERS,
 466            "FULLTEXT": lambda self: self._parse_index_constraint(kind="FULLTEXT"),
 467            "INDEX": lambda self: self._parse_index_constraint(),
 468            "KEY": lambda self: self._parse_index_constraint(),
 469            "SPATIAL": lambda self: self._parse_index_constraint(kind="SPATIAL"),
 470            "ZEROFILL": lambda self: self.expression(exp.ZeroFillColumnConstraint),
 471        }
 472
 473        ALTER_PARSERS = {
 474            **parser.Parser.ALTER_PARSERS,
 475            "MODIFY": lambda self: self._parse_alter_table_alter(),
 476        }
 477
 478        ALTER_ALTER_PARSERS = {
 479            **parser.Parser.ALTER_ALTER_PARSERS,
 480            "INDEX": lambda self: self._parse_alter_table_alter_index(),
 481        }
 482
 483        SCHEMA_UNNAMED_CONSTRAINTS = {
 484            *parser.Parser.SCHEMA_UNNAMED_CONSTRAINTS,
 485            "FULLTEXT",
 486            "INDEX",
 487            "KEY",
 488            "SPATIAL",
 489        }
 490
 491        PROFILE_TYPES: parser.OPTIONS_TYPE = {
 492            **dict.fromkeys(("ALL", "CPU", "IPC", "MEMORY", "SOURCE", "SWAPS"), tuple()),
 493            "BLOCK": ("IO",),
 494            "CONTEXT": ("SWITCHES",),
 495            "PAGE": ("FAULTS",),
 496        }
 497
 498        TYPE_TOKENS = {
 499            *parser.Parser.TYPE_TOKENS,
 500            TokenType.SET,
 501        }
 502
 503        ENUM_TYPE_TOKENS = {
 504            *parser.Parser.ENUM_TYPE_TOKENS,
 505            TokenType.SET,
 506        }
 507
 508        # SELECT [ ALL | DISTINCT | DISTINCTROW ] [ <OPERATION_MODIFIERS> ]
 509        OPERATION_MODIFIERS = {
 510            "HIGH_PRIORITY",
 511            "STRAIGHT_JOIN",
 512            "SQL_SMALL_RESULT",
 513            "SQL_BIG_RESULT",
 514            "SQL_BUFFER_RESULT",
 515            "SQL_NO_CACHE",
 516            "SQL_CALC_FOUND_ROWS",
 517        }
 518
 519        LOG_DEFAULTS_TO_LN = True
 520        STRING_ALIASES = True
 521        VALUES_FOLLOWED_BY_PAREN = False
 522        SUPPORTS_PARTITION_SELECTION = True
 523
 524        def _parse_generated_as_identity(
 525            self,
 526        ) -> (
 527            exp.GeneratedAsIdentityColumnConstraint
 528            | exp.ComputedColumnConstraint
 529            | exp.GeneratedAsRowColumnConstraint
 530        ):
 531            this = super()._parse_generated_as_identity()
 532
 533            if self._match_texts(("STORED", "VIRTUAL")):
 534                persisted = self._prev.text.upper() == "STORED"
 535
 536                if isinstance(this, exp.ComputedColumnConstraint):
 537                    this.set("persisted", persisted)
 538                elif isinstance(this, exp.GeneratedAsIdentityColumnConstraint):
 539                    this = self.expression(
 540                        exp.ComputedColumnConstraint, this=this.expression, persisted=persisted
 541                    )
 542
 543            return this
 544
 545        def _parse_primary_key_part(self) -> t.Optional[exp.Expression]:
 546            this = self._parse_id_var()
 547            if not self._match(TokenType.L_PAREN):
 548                return this
 549
 550            expression = self._parse_number()
 551            self._match_r_paren()
 552            return self.expression(exp.ColumnPrefix, this=this, expression=expression)
 553
 554        def _parse_index_constraint(
 555            self, kind: t.Optional[str] = None
 556        ) -> exp.IndexColumnConstraint:
 557            if kind:
 558                self._match_texts(("INDEX", "KEY"))
 559
 560            this = self._parse_id_var(any_token=False)
 561            index_type = self._match(TokenType.USING) and self._advance_any() and self._prev.text
 562            expressions = self._parse_wrapped_csv(self._parse_ordered)
 563
 564            options = []
 565            while True:
 566                if self._match_text_seq("KEY_BLOCK_SIZE"):
 567                    self._match(TokenType.EQ)
 568                    opt = exp.IndexConstraintOption(key_block_size=self._parse_number())
 569                elif self._match(TokenType.USING):
 570                    opt = exp.IndexConstraintOption(using=self._advance_any() and self._prev.text)
 571                elif self._match_text_seq("WITH", "PARSER"):
 572                    opt = exp.IndexConstraintOption(parser=self._parse_var(any_token=True))
 573                elif self._match(TokenType.COMMENT):
 574                    opt = exp.IndexConstraintOption(comment=self._parse_string())
 575                elif self._match_text_seq("VISIBLE"):
 576                    opt = exp.IndexConstraintOption(visible=True)
 577                elif self._match_text_seq("INVISIBLE"):
 578                    opt = exp.IndexConstraintOption(visible=False)
 579                elif self._match_text_seq("ENGINE_ATTRIBUTE"):
 580                    self._match(TokenType.EQ)
 581                    opt = exp.IndexConstraintOption(engine_attr=self._parse_string())
 582                elif self._match_text_seq("SECONDARY_ENGINE_ATTRIBUTE"):
 583                    self._match(TokenType.EQ)
 584                    opt = exp.IndexConstraintOption(secondary_engine_attr=self._parse_string())
 585                else:
 586                    opt = None
 587
 588                if not opt:
 589                    break
 590
 591                options.append(opt)
 592
 593            return self.expression(
 594                exp.IndexColumnConstraint,
 595                this=this,
 596                expressions=expressions,
 597                kind=kind,
 598                index_type=index_type,
 599                options=options,
 600            )
 601
 602        def _parse_show_mysql(
 603            self,
 604            this: str,
 605            target: bool | str = False,
 606            full: t.Optional[bool] = None,
 607            global_: t.Optional[bool] = None,
 608        ) -> exp.Show:
 609            json = self._match_text_seq("JSON")
 610
 611            if target:
 612                if isinstance(target, str):
 613                    self._match_text_seq(*target.split(" "))
 614                target_id = self._parse_id_var()
 615            else:
 616                target_id = None
 617
 618            log = self._parse_string() if self._match_text_seq("IN") else None
 619
 620            if this in ("BINLOG EVENTS", "RELAYLOG EVENTS"):
 621                position = self._parse_number() if self._match_text_seq("FROM") else None
 622                db = None
 623            else:
 624                position = None
 625                db = None
 626
 627                if self._match(TokenType.FROM):
 628                    db = self._parse_id_var()
 629                elif self._match(TokenType.DOT):
 630                    db = target_id
 631                    target_id = self._parse_id_var()
 632
 633            channel = self._parse_id_var() if self._match_text_seq("FOR", "CHANNEL") else None
 634
 635            like = self._parse_string() if self._match_text_seq("LIKE") else None
 636            where = self._parse_where()
 637
 638            if this == "PROFILE":
 639                types = self._parse_csv(lambda: self._parse_var_from_options(self.PROFILE_TYPES))
 640                query = self._parse_number() if self._match_text_seq("FOR", "QUERY") else None
 641                offset = self._parse_number() if self._match_text_seq("OFFSET") else None
 642                limit = self._parse_number() if self._match_text_seq("LIMIT") else None
 643            else:
 644                types, query = None, None
 645                offset, limit = self._parse_oldstyle_limit()
 646
 647            mutex = True if self._match_text_seq("MUTEX") else None
 648            mutex = False if self._match_text_seq("STATUS") else mutex
 649
 650            for_table = self._parse_id_var() if self._match_text_seq("FOR", "TABLE") else None
 651            for_group = self._parse_string() if self._match_text_seq("FOR", "GROUP") else None
 652            for_user = self._parse_string() if self._match_text_seq("FOR", "USER") else None
 653            for_role = self._parse_string() if self._match_text_seq("FOR", "ROLE") else None
 654            into_outfile = self._parse_string() if self._match_text_seq("INTO", "OUTFILE") else None
 655
 656            return self.expression(
 657                exp.Show,
 658                this=this,
 659                target=target_id,
 660                full=full,
 661                log=log,
 662                position=position,
 663                db=db,
 664                channel=channel,
 665                like=like,
 666                where=where,
 667                types=types,
 668                query=query,
 669                offset=offset,
 670                limit=limit,
 671                mutex=mutex,
 672                for_table=for_table,
 673                for_group=for_group,
 674                for_user=for_user,
 675                for_role=for_role,
 676                into_outfile=into_outfile,
 677                json=json,
 678                global_=global_,
 679            )
 680
 681        def _parse_oldstyle_limit(
 682            self,
 683        ) -> t.Tuple[t.Optional[exp.Expression], t.Optional[exp.Expression]]:
 684            limit = None
 685            offset = None
 686            if self._match_text_seq("LIMIT"):
 687                parts = self._parse_csv(self._parse_number)
 688                if len(parts) == 1:
 689                    limit = parts[0]
 690                elif len(parts) == 2:
 691                    limit = parts[1]
 692                    offset = parts[0]
 693
 694            return offset, limit
 695
 696        def _parse_set_item_charset(self, kind: str) -> exp.Expression:
 697            this = self._parse_string() or self._parse_unquoted_field()
 698            return self.expression(exp.SetItem, this=this, kind=kind)
 699
 700        def _parse_set_item_names(self) -> exp.Expression:
 701            charset = self._parse_string() or self._parse_unquoted_field()
 702            if self._match_text_seq("COLLATE"):
 703                collate = self._parse_string() or self._parse_unquoted_field()
 704            else:
 705                collate = None
 706
 707            return self.expression(exp.SetItem, this=charset, collate=collate, kind="NAMES")
 708
 709        def _parse_type(
 710            self, parse_interval: bool = True, fallback_to_identifier: bool = False
 711        ) -> t.Optional[exp.Expression]:
 712            # mysql binary is special and can work anywhere, even in order by operations
 713            # it operates like a no paren func
 714            if self._match(TokenType.BINARY, advance=False):
 715                data_type = self._parse_types(check_func=True, allow_identifiers=False)
 716
 717                if isinstance(data_type, exp.DataType):
 718                    return self.expression(exp.Cast, this=self._parse_column(), to=data_type)
 719
 720            return super()._parse_type(
 721                parse_interval=parse_interval, fallback_to_identifier=fallback_to_identifier
 722            )
 723
 724        def _parse_alter_table_alter_index(self) -> exp.AlterIndex:
 725            index = self._parse_field(any_token=True)
 726
 727            if self._match_text_seq("VISIBLE"):
 728                visible = True
 729            elif self._match_text_seq("INVISIBLE"):
 730                visible = False
 731            else:
 732                visible = None
 733
 734            return self.expression(exp.AlterIndex, this=index, visible=visible)
 735
 736        def _parse_partition_property(
 737            self,
 738        ) -> t.Optional[exp.Expression] | t.List[exp.Expression]:
 739            partition_cls: t.Optional[t.Type[exp.Expression]] = None
 740            value_parser = None
 741
 742            if self._match_text_seq("RANGE"):
 743                partition_cls = exp.PartitionByRangeProperty
 744                value_parser = self._parse_partition_range_value
 745            elif self._match_text_seq("LIST"):
 746                partition_cls = exp.PartitionByListProperty
 747                value_parser = self._parse_partition_list_value
 748
 749            if not partition_cls or not value_parser:
 750                return None
 751
 752            partition_expressions = self._parse_wrapped_csv(self._parse_assignment)
 753
 754            # For Doris and Starrocks
 755            if not self._match_text_seq("(", "PARTITION", advance=False):
 756                return partition_expressions
 757
 758            create_expressions = self._parse_wrapped_csv(value_parser)
 759
 760            return self.expression(
 761                partition_cls,
 762                partition_expressions=partition_expressions,
 763                create_expressions=create_expressions,
 764            )
 765
 766        def _parse_partition_range_value(self) -> t.Optional[exp.Expression]:
 767            self._match_text_seq("PARTITION")
 768            name = self._parse_id_var()
 769
 770            if not self._match_text_seq("VALUES", "LESS", "THAN"):
 771                return name
 772
 773            values = self._parse_wrapped_csv(self._parse_expression)
 774
 775            if (
 776                len(values) == 1
 777                and isinstance(values[0], exp.Column)
 778                and values[0].name.upper() == "MAXVALUE"
 779            ):
 780                values = [exp.var("MAXVALUE")]
 781
 782            part_range = self.expression(exp.PartitionRange, this=name, expressions=values)
 783            return self.expression(exp.Partition, expressions=[part_range])
 784
 785        def _parse_partition_list_value(self) -> exp.Partition:
 786            self._match_text_seq("PARTITION")
 787            name = self._parse_id_var()
 788            self._match_text_seq("VALUES", "IN")
 789            values = self._parse_wrapped_csv(self._parse_expression)
 790            part_list = self.expression(exp.PartitionList, this=name, expressions=values)
 791            return self.expression(exp.Partition, expressions=[part_list])
 792
 793    class Generator(generator.Generator):
 794        INTERVAL_ALLOWS_PLURAL_FORM = False
 795        LOCKING_READS_SUPPORTED = True
 796        NULL_ORDERING_SUPPORTED: t.Optional[bool] = None
 797        JOIN_HINTS = False
 798        TABLE_HINTS = True
 799        DUPLICATE_KEY_UPDATE_WITH_SET = False
 800        QUERY_HINT_SEP = " "
 801        VALUES_AS_TABLE = False
 802        NVL2_SUPPORTED = False
 803        LAST_DAY_SUPPORTS_DATE_PART = False
 804        JSON_TYPE_REQUIRED_FOR_EXTRACTION = True
 805        JSON_PATH_BRACKETED_KEY_SUPPORTED = False
 806        JSON_KEY_VALUE_PAIR_SEP = ","
 807        SUPPORTS_TO_NUMBER = False
 808        PARSE_JSON_NAME: t.Optional[str] = None
 809        PAD_FILL_PATTERN_IS_REQUIRED = True
 810        WRAP_DERIVED_VALUES = False
 811        VARCHAR_REQUIRES_SIZE = True
 812        SUPPORTS_MEDIAN = False
 813        UPDATE_STATEMENT_SUPPORTS_FROM = False
 814
 815        TRANSFORMS = {
 816            **generator.Generator.TRANSFORMS,
 817            exp.ArrayAgg: rename_func("GROUP_CONCAT"),
 818            exp.BitwiseAndAgg: rename_func("BIT_AND"),
 819            exp.BitwiseOrAgg: rename_func("BIT_OR"),
 820            exp.BitwiseXorAgg: rename_func("BIT_XOR"),
 821            exp.BitwiseCount: rename_func("BIT_COUNT"),
 822            exp.Chr: lambda self, e: self.chr_sql(e, "CHAR"),
 823            exp.CurrentDate: no_paren_current_date_sql,
 824            exp.DateDiff: _remove_ts_or_ds_to_date(
 825                lambda self, e: self.func("DATEDIFF", e.this, e.expression), ("this", "expression")
 826            ),
 827            exp.DateAdd: _remove_ts_or_ds_to_date(date_add_sql("ADD")),
 828            exp.DateStrToDate: datestrtodate_sql,
 829            exp.DateSub: _remove_ts_or_ds_to_date(date_add_sql("SUB")),
 830            exp.DateTrunc: _date_trunc_sql,
 831            exp.Day: _remove_ts_or_ds_to_date(),
 832            exp.DayOfMonth: _remove_ts_or_ds_to_date(rename_func("DAYOFMONTH")),
 833            exp.DayOfWeek: _remove_ts_or_ds_to_date(rename_func("DAYOFWEEK")),
 834            exp.DayOfYear: _remove_ts_or_ds_to_date(rename_func("DAYOFYEAR")),
 835            exp.GroupConcat: lambda self,
 836            e: f"""GROUP_CONCAT({self.sql(e, "this")} SEPARATOR {self.sql(e, "separator") or "','"})""",
 837            exp.ILike: no_ilike_sql,
 838            exp.JSONExtractScalar: arrow_json_extract_sql,
 839            exp.Length: length_or_char_length_sql,
 840            exp.LogicalOr: rename_func("MAX"),
 841            exp.LogicalAnd: rename_func("MIN"),
 842            exp.Max: max_or_greatest,
 843            exp.Min: min_or_least,
 844            exp.Month: _remove_ts_or_ds_to_date(),
 845            exp.NullSafeEQ: lambda self, e: self.binary(e, "<=>"),
 846            exp.NullSafeNEQ: lambda self, e: f"NOT {self.binary(e, '<=>')}",
 847            exp.NumberToStr: rename_func("FORMAT"),
 848            exp.Pivot: no_pivot_sql,
 849            exp.Select: transforms.preprocess(
 850                [
 851                    transforms.eliminate_distinct_on,
 852                    transforms.eliminate_semi_and_anti_joins,
 853                    transforms.eliminate_qualify,
 854                    transforms.eliminate_full_outer_join,
 855                    transforms.unnest_generate_date_array_using_recursive_cte,
 856                ]
 857            ),
 858            exp.StrPosition: lambda self, e: strposition_sql(
 859                self, e, func_name="LOCATE", supports_position=True
 860            ),
 861            exp.StrToDate: _str_to_date_sql,
 862            exp.StrToTime: _str_to_date_sql,
 863            exp.Stuff: rename_func("INSERT"),
 864            exp.SessionUser: lambda *_: "SESSION_USER()",
 865            exp.TableSample: no_tablesample_sql,
 866            exp.TimeFromParts: rename_func("MAKETIME"),
 867            exp.TimestampAdd: date_add_interval_sql("DATE", "ADD"),
 868            exp.TimestampDiff: lambda self, e: self.func(
 869                "TIMESTAMPDIFF", unit_to_var(e), e.expression, e.this
 870            ),
 871            exp.TimestampSub: date_add_interval_sql("DATE", "SUB"),
 872            exp.TimeStrToUnix: rename_func("UNIX_TIMESTAMP"),
 873            exp.TimeStrToTime: lambda self, e: timestrtotime_sql(
 874                self,
 875                e,
 876                include_precision=not e.args.get("zone"),
 877            ),
 878            exp.TimeToStr: _remove_ts_or_ds_to_date(
 879                lambda self, e: self.func("DATE_FORMAT", e.this, self.format_time(e))
 880            ),
 881            exp.Trim: trim_sql,
 882            exp.TryCast: no_trycast_sql,
 883            exp.TsOrDsAdd: date_add_sql("ADD"),
 884            exp.TsOrDsDiff: lambda self, e: self.func("DATEDIFF", e.this, e.expression),
 885            exp.TsOrDsToDate: _ts_or_ds_to_date_sql,
 886            exp.Unicode: lambda self, e: f"ORD(CONVERT({self.sql(e.this)} USING utf32))",
 887            exp.UnixToTime: _unix_to_time_sql,
 888            exp.Week: _remove_ts_or_ds_to_date(),
 889            exp.WeekOfYear: _remove_ts_or_ds_to_date(rename_func("WEEKOFYEAR")),
 890            exp.Year: _remove_ts_or_ds_to_date(),
 891            exp.UtcTimestamp: rename_func("UTC_TIMESTAMP"),
 892            exp.UtcTime: rename_func("UTC_TIME"),
 893        }
 894
 895        UNSIGNED_TYPE_MAPPING = {
 896            exp.DataType.Type.UBIGINT: "BIGINT",
 897            exp.DataType.Type.UINT: "INT",
 898            exp.DataType.Type.UMEDIUMINT: "MEDIUMINT",
 899            exp.DataType.Type.USMALLINT: "SMALLINT",
 900            exp.DataType.Type.UTINYINT: "TINYINT",
 901            exp.DataType.Type.UDECIMAL: "DECIMAL",
 902            exp.DataType.Type.UDOUBLE: "DOUBLE",
 903        }
 904
 905        TIMESTAMP_TYPE_MAPPING = {
 906            exp.DataType.Type.DATETIME2: "DATETIME",
 907            exp.DataType.Type.SMALLDATETIME: "DATETIME",
 908            exp.DataType.Type.TIMESTAMP: "DATETIME",
 909            exp.DataType.Type.TIMESTAMPNTZ: "DATETIME",
 910            exp.DataType.Type.TIMESTAMPTZ: "TIMESTAMP",
 911            exp.DataType.Type.TIMESTAMPLTZ: "TIMESTAMP",
 912        }
 913
 914        TYPE_MAPPING = {
 915            **generator.Generator.TYPE_MAPPING,
 916            **UNSIGNED_TYPE_MAPPING,
 917            **TIMESTAMP_TYPE_MAPPING,
 918        }
 919
 920        TYPE_MAPPING.pop(exp.DataType.Type.MEDIUMTEXT)
 921        TYPE_MAPPING.pop(exp.DataType.Type.LONGTEXT)
 922        TYPE_MAPPING.pop(exp.DataType.Type.TINYTEXT)
 923        TYPE_MAPPING.pop(exp.DataType.Type.BLOB)
 924        TYPE_MAPPING.pop(exp.DataType.Type.MEDIUMBLOB)
 925        TYPE_MAPPING.pop(exp.DataType.Type.LONGBLOB)
 926        TYPE_MAPPING.pop(exp.DataType.Type.TINYBLOB)
 927
 928        PROPERTIES_LOCATION = {
 929            **generator.Generator.PROPERTIES_LOCATION,
 930            exp.TransientProperty: exp.Properties.Location.UNSUPPORTED,
 931            exp.VolatileProperty: exp.Properties.Location.UNSUPPORTED,
 932            exp.PartitionedByProperty: exp.Properties.Location.UNSUPPORTED,
 933            exp.PartitionByRangeProperty: exp.Properties.Location.POST_SCHEMA,
 934            exp.PartitionByListProperty: exp.Properties.Location.POST_SCHEMA,
 935        }
 936
 937        LIMIT_FETCH = "LIMIT"
 938
 939        LIMIT_ONLY_LITERALS = True
 940
 941        CHAR_CAST_MAPPING = dict.fromkeys(
 942            (
 943                exp.DataType.Type.LONGTEXT,
 944                exp.DataType.Type.LONGBLOB,
 945                exp.DataType.Type.MEDIUMBLOB,
 946                exp.DataType.Type.MEDIUMTEXT,
 947                exp.DataType.Type.TEXT,
 948                exp.DataType.Type.TINYBLOB,
 949                exp.DataType.Type.TINYTEXT,
 950                exp.DataType.Type.VARCHAR,
 951            ),
 952            "CHAR",
 953        )
 954        SIGNED_CAST_MAPPING = dict.fromkeys(
 955            (
 956                exp.DataType.Type.BIGINT,
 957                exp.DataType.Type.BOOLEAN,
 958                exp.DataType.Type.INT,
 959                exp.DataType.Type.SMALLINT,
 960                exp.DataType.Type.TINYINT,
 961                exp.DataType.Type.MEDIUMINT,
 962            ),
 963            "SIGNED",
 964        )
 965
 966        # MySQL doesn't support many datatypes in cast.
 967        # https://dev.mysql.com/doc/refman/8.0/en/cast-functions.html#function_cast
 968        CAST_MAPPING = {
 969            **CHAR_CAST_MAPPING,
 970            **SIGNED_CAST_MAPPING,
 971            exp.DataType.Type.UBIGINT: "UNSIGNED",
 972        }
 973
 974        TIMESTAMP_FUNC_TYPES = {
 975            exp.DataType.Type.TIMESTAMPTZ,
 976            exp.DataType.Type.TIMESTAMPLTZ,
 977        }
 978
 979        # https://dev.mysql.com/doc/refman/8.0/en/keywords.html
 980        RESERVED_KEYWORDS = {
 981            "accessible",
 982            "add",
 983            "all",
 984            "alter",
 985            "analyze",
 986            "and",
 987            "as",
 988            "asc",
 989            "asensitive",
 990            "before",
 991            "between",
 992            "bigint",
 993            "binary",
 994            "blob",
 995            "both",
 996            "by",
 997            "call",
 998            "cascade",
 999            "case",
1000            "change",
1001            "char",
1002            "character",
1003            "check",
1004            "collate",
1005            "column",
1006            "condition",
1007            "constraint",
1008            "continue",
1009            "convert",
1010            "create",
1011            "cross",
1012            "cube",
1013            "cume_dist",
1014            "current_date",
1015            "current_time",
1016            "current_timestamp",
1017            "current_user",
1018            "cursor",
1019            "database",
1020            "databases",
1021            "day_hour",
1022            "day_microsecond",
1023            "day_minute",
1024            "day_second",
1025            "dec",
1026            "decimal",
1027            "declare",
1028            "default",
1029            "delayed",
1030            "delete",
1031            "dense_rank",
1032            "desc",
1033            "describe",
1034            "deterministic",
1035            "distinct",
1036            "distinctrow",
1037            "div",
1038            "double",
1039            "drop",
1040            "dual",
1041            "each",
1042            "else",
1043            "elseif",
1044            "empty",
1045            "enclosed",
1046            "escaped",
1047            "except",
1048            "exists",
1049            "exit",
1050            "explain",
1051            "false",
1052            "fetch",
1053            "first_value",
1054            "float",
1055            "float4",
1056            "float8",
1057            "for",
1058            "force",
1059            "foreign",
1060            "from",
1061            "fulltext",
1062            "function",
1063            "generated",
1064            "get",
1065            "grant",
1066            "group",
1067            "grouping",
1068            "groups",
1069            "having",
1070            "high_priority",
1071            "hour_microsecond",
1072            "hour_minute",
1073            "hour_second",
1074            "if",
1075            "ignore",
1076            "in",
1077            "index",
1078            "infile",
1079            "inner",
1080            "inout",
1081            "insensitive",
1082            "insert",
1083            "int",
1084            "int1",
1085            "int2",
1086            "int3",
1087            "int4",
1088            "int8",
1089            "integer",
1090            "intersect",
1091            "interval",
1092            "into",
1093            "io_after_gtids",
1094            "io_before_gtids",
1095            "is",
1096            "iterate",
1097            "join",
1098            "json_table",
1099            "key",
1100            "keys",
1101            "kill",
1102            "lag",
1103            "last_value",
1104            "lateral",
1105            "lead",
1106            "leading",
1107            "leave",
1108            "left",
1109            "like",
1110            "limit",
1111            "linear",
1112            "lines",
1113            "load",
1114            "localtime",
1115            "localtimestamp",
1116            "lock",
1117            "long",
1118            "longblob",
1119            "longtext",
1120            "loop",
1121            "low_priority",
1122            "master_bind",
1123            "master_ssl_verify_server_cert",
1124            "match",
1125            "maxvalue",
1126            "mediumblob",
1127            "mediumint",
1128            "mediumtext",
1129            "middleint",
1130            "minute_microsecond",
1131            "minute_second",
1132            "mod",
1133            "modifies",
1134            "natural",
1135            "not",
1136            "no_write_to_binlog",
1137            "nth_value",
1138            "ntile",
1139            "null",
1140            "numeric",
1141            "of",
1142            "on",
1143            "optimize",
1144            "optimizer_costs",
1145            "option",
1146            "optionally",
1147            "or",
1148            "order",
1149            "out",
1150            "outer",
1151            "outfile",
1152            "over",
1153            "partition",
1154            "percent_rank",
1155            "precision",
1156            "primary",
1157            "procedure",
1158            "purge",
1159            "range",
1160            "rank",
1161            "read",
1162            "reads",
1163            "read_write",
1164            "real",
1165            "recursive",
1166            "references",
1167            "regexp",
1168            "release",
1169            "rename",
1170            "repeat",
1171            "replace",
1172            "require",
1173            "resignal",
1174            "restrict",
1175            "return",
1176            "revoke",
1177            "right",
1178            "rlike",
1179            "row",
1180            "rows",
1181            "row_number",
1182            "schema",
1183            "schemas",
1184            "second_microsecond",
1185            "select",
1186            "sensitive",
1187            "separator",
1188            "set",
1189            "show",
1190            "signal",
1191            "smallint",
1192            "spatial",
1193            "specific",
1194            "sql",
1195            "sqlexception",
1196            "sqlstate",
1197            "sqlwarning",
1198            "sql_big_result",
1199            "sql_calc_found_rows",
1200            "sql_small_result",
1201            "ssl",
1202            "starting",
1203            "stored",
1204            "straight_join",
1205            "system",
1206            "table",
1207            "terminated",
1208            "then",
1209            "tinyblob",
1210            "tinyint",
1211            "tinytext",
1212            "to",
1213            "trailing",
1214            "trigger",
1215            "true",
1216            "undo",
1217            "union",
1218            "unique",
1219            "unlock",
1220            "unsigned",
1221            "update",
1222            "usage",
1223            "use",
1224            "using",
1225            "utc_date",
1226            "utc_time",
1227            "utc_timestamp",
1228            "values",
1229            "varbinary",
1230            "varchar",
1231            "varcharacter",
1232            "varying",
1233            "virtual",
1234            "when",
1235            "where",
1236            "while",
1237            "window",
1238            "with",
1239            "write",
1240            "xor",
1241            "year_month",
1242            "zerofill",
1243        }
1244
1245        def computedcolumnconstraint_sql(self, expression: exp.ComputedColumnConstraint) -> str:
1246            persisted = "STORED" if expression.args.get("persisted") else "VIRTUAL"
1247            return f"GENERATED ALWAYS AS ({self.sql(expression.this.unnest())}) {persisted}"
1248
1249        def array_sql(self, expression: exp.Array) -> str:
1250            self.unsupported("Arrays are not supported by MySQL")
1251            return self.function_fallback_sql(expression)
1252
1253        def arraycontainsall_sql(self, expression: exp.ArrayContainsAll) -> str:
1254            self.unsupported("Array operations are not supported by MySQL")
1255            return self.function_fallback_sql(expression)
1256
1257        def dpipe_sql(self, expression: exp.DPipe) -> str:
1258            return self.func("CONCAT", *expression.flatten())
1259
1260        def extract_sql(self, expression: exp.Extract) -> str:
1261            unit = expression.name
1262            if unit and unit.lower() == "epoch":
1263                return self.func("UNIX_TIMESTAMP", expression.expression)
1264
1265            return super().extract_sql(expression)
1266
1267        def datatype_sql(self, expression: exp.DataType) -> str:
1268            if (
1269                self.VARCHAR_REQUIRES_SIZE
1270                and expression.is_type(exp.DataType.Type.VARCHAR)
1271                and not expression.expressions
1272            ):
1273                # `VARCHAR` must always have a size - if it doesn't, we always generate `TEXT`
1274                return "TEXT"
1275
1276            # https://dev.mysql.com/doc/refman/8.0/en/numeric-type-syntax.html
1277            result = super().datatype_sql(expression)
1278            if expression.this in self.UNSIGNED_TYPE_MAPPING:
1279                result = f"{result} UNSIGNED"
1280
1281            return result
1282
1283        def jsonarraycontains_sql(self, expression: exp.JSONArrayContains) -> str:
1284            return f"{self.sql(expression, 'this')} MEMBER OF({self.sql(expression, 'expression')})"
1285
1286        def cast_sql(self, expression: exp.Cast, safe_prefix: t.Optional[str] = None) -> str:
1287            if expression.to.this in self.TIMESTAMP_FUNC_TYPES:
1288                return self.func("TIMESTAMP", expression.this)
1289
1290            to = self.CAST_MAPPING.get(expression.to.this)
1291
1292            if to:
1293                expression.to.set("this", to)
1294            return super().cast_sql(expression)
1295
1296        def show_sql(self, expression: exp.Show) -> str:
1297            this = f" {expression.name}"
1298            full = " FULL" if expression.args.get("full") else ""
1299            global_ = " GLOBAL" if expression.args.get("global_") else ""
1300
1301            target = self.sql(expression, "target")
1302            target = f" {target}" if target else ""
1303            if expression.name in ("COLUMNS", "INDEX"):
1304                target = f" FROM{target}"
1305            elif expression.name == "GRANTS":
1306                target = f" FOR{target}"
1307            elif expression.name in ("LINKS", "PARTITIONS"):
1308                target = f" ON{target}" if target else ""
1309            elif expression.name == "PROJECTIONS":
1310                target = f" ON TABLE{target}" if target else ""
1311
1312            db = self._prefixed_sql("FROM", expression, "db")
1313
1314            like = self._prefixed_sql("LIKE", expression, "like")
1315            where = self.sql(expression, "where")
1316
1317            types = self.expressions(expression, key="types")
1318            types = f" {types}" if types else types
1319            query = self._prefixed_sql("FOR QUERY", expression, "query")
1320
1321            if expression.name == "PROFILE":
1322                offset = self._prefixed_sql("OFFSET", expression, "offset")
1323                limit = self._prefixed_sql("LIMIT", expression, "limit")
1324            else:
1325                offset = ""
1326                limit = self._oldstyle_limit_sql(expression)
1327
1328            log = self._prefixed_sql("IN", expression, "log")
1329            position = self._prefixed_sql("FROM", expression, "position")
1330
1331            channel = self._prefixed_sql("FOR CHANNEL", expression, "channel")
1332
1333            if expression.name == "ENGINE":
1334                mutex_or_status = " MUTEX" if expression.args.get("mutex") else " STATUS"
1335            else:
1336                mutex_or_status = ""
1337
1338            for_table = self._prefixed_sql("FOR TABLE", expression, "for_table")
1339            for_group = self._prefixed_sql("FOR GROUP", expression, "for_group")
1340            for_user = self._prefixed_sql("FOR USER", expression, "for_user")
1341            for_role = self._prefixed_sql("FOR ROLE", expression, "for_role")
1342            into_outfile = self._prefixed_sql("INTO OUTFILE", expression, "into_outfile")
1343            json = " JSON" if expression.args.get("json") else ""
1344
1345            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}"
1346
1347        def alterrename_sql(self, expression: exp.AlterRename, include_to: bool = True) -> str:
1348            """To avoid TO keyword in ALTER ... RENAME statements.
1349            It's moved from Doris, because it's the same for all MySQL, Doris, and StarRocks.
1350            """
1351            return super().alterrename_sql(expression, include_to=False)
1352
1353        def altercolumn_sql(self, expression: exp.AlterColumn) -> str:
1354            dtype = self.sql(expression, "dtype")
1355            if not dtype:
1356                return super().altercolumn_sql(expression)
1357
1358            this = self.sql(expression, "this")
1359            return f"MODIFY COLUMN {this} {dtype}"
1360
1361        def _prefixed_sql(self, prefix: str, expression: exp.Expression, arg: str) -> str:
1362            sql = self.sql(expression, arg)
1363            return f" {prefix} {sql}" if sql else ""
1364
1365        def _oldstyle_limit_sql(self, expression: exp.Show) -> str:
1366            limit = self.sql(expression, "limit")
1367            offset = self.sql(expression, "offset")
1368            if limit:
1369                limit_offset = f"{offset}, {limit}" if offset else limit
1370                return f" LIMIT {limit_offset}"
1371            return ""
1372
1373        def timestamptrunc_sql(self, expression: exp.TimestampTrunc) -> str:
1374            unit = expression.args.get("unit")
1375
1376            # Pick an old-enough date to avoid negative timestamp diffs
1377            start_ts = "'0000-01-01 00:00:00'"
1378
1379            # Source: https://stackoverflow.com/a/32955740
1380            timestamp_diff = build_date_delta(exp.TimestampDiff)([unit, start_ts, expression.this])
1381            interval = exp.Interval(this=timestamp_diff, unit=unit)
1382            dateadd = build_date_delta_with_interval(exp.DateAdd)([start_ts, interval])
1383
1384            return self.sql(dateadd)
1385
1386        def converttimezone_sql(self, expression: exp.ConvertTimezone) -> str:
1387            from_tz = expression.args.get("source_tz")
1388            to_tz = expression.args.get("target_tz")
1389            dt = expression.args.get("timestamp")
1390
1391            return self.func("CONVERT_TZ", dt, from_tz, to_tz)
1392
1393        def attimezone_sql(self, expression: exp.AtTimeZone) -> str:
1394            self.unsupported("AT TIME ZONE is not supported by MySQL")
1395            return self.sql(expression.this)
1396
1397        def isascii_sql(self, expression: exp.IsAscii) -> str:
1398            return f"REGEXP_LIKE({self.sql(expression.this)}, '^[[:ascii:]]*$')"
1399
1400        def ignorenulls_sql(self, expression: exp.IgnoreNulls) -> str:
1401            # https://dev.mysql.com/doc/refman/8.4/en/window-function-descriptions.html
1402            self.unsupported("MySQL does not support IGNORE NULLS.")
1403            return self.sql(expression.this)
1404
1405        @unsupported_args("this")
1406        def currentschema_sql(self, expression: exp.CurrentSchema) -> str:
1407            return self.func("SCHEMA")
1408
1409        def partition_sql(self, expression: exp.Partition) -> str:
1410            parent = expression.parent
1411            if isinstance(parent, (exp.PartitionByRangeProperty, exp.PartitionByListProperty)):
1412                return self.expressions(expression, flat=True)
1413            return super().partition_sql(expression)
1414
1415        def _partition_by_sql(
1416            self, expression: exp.PartitionByRangeProperty | exp.PartitionByListProperty, kind: str
1417        ) -> str:
1418            partitions = self.expressions(expression, key="partition_expressions", flat=True)
1419            create = self.expressions(expression, key="create_expressions", flat=True)
1420            return f"PARTITION BY {kind} ({partitions}) ({create})"
1421
1422        def partitionbyrangeproperty_sql(self, expression: exp.PartitionByRangeProperty) -> str:
1423            return self._partition_by_sql(expression, "RANGE")
1424
1425        def partitionbylistproperty_sql(self, expression: exp.PartitionByListProperty) -> str:
1426            return self._partition_by_sql(expression, "LIST")
1427
1428        def partitionlist_sql(self, expression: exp.PartitionList) -> str:
1429            name = self.sql(expression, "this")
1430            values = self.expressions(expression, flat=True)
1431            return f"PARTITION {name} VALUES IN ({values})"
1432
1433        def partitionrange_sql(self, expression: exp.PartitionRange) -> str:
1434            name = self.sql(expression, "this")
1435            values = self.expressions(expression, flat=True)
1436            return f"PARTITION {name} VALUES LESS THAN ({values})"
TIME_SPECIFIERS = {'H', 'p', 'i', 'k', 'f', 'S', 'h', 'l', 'r', 'T', 's', 'I'}
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            "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            "WEEK": lambda args: exp.Week(
 373                this=exp.TsOrDsToDate(this=seq_get(args, 0)), mode=seq_get(args, 1)
 374            ),
 375            "WEEKOFYEAR": lambda args: exp.WeekOfYear(this=exp.TsOrDsToDate(this=seq_get(args, 0))),
 376            "YEAR": lambda args: exp.Year(this=exp.TsOrDsToDate(this=seq_get(args, 0))),
 377        }
 378
 379        FUNCTION_PARSERS = {
 380            **parser.Parser.FUNCTION_PARSERS,
 381            "GROUP_CONCAT": lambda self: self._parse_group_concat(),
 382            # https://dev.mysql.com/doc/refman/5.7/en/miscellaneous-functions.html#function_values
 383            "VALUES": lambda self: self.expression(
 384                exp.Anonymous, this="VALUES", expressions=[self._parse_id_var()]
 385            ),
 386            "JSON_VALUE": lambda self: self._parse_json_value(),
 387            "SUBSTR": lambda self: self._parse_substring(),
 388        }
 389
 390        STATEMENT_PARSERS = {
 391            **parser.Parser.STATEMENT_PARSERS,
 392            TokenType.SHOW: lambda self: self._parse_show(),
 393        }
 394
 395        SHOW_PARSERS = {
 396            "BINARY LOGS": _show_parser("BINARY LOGS"),
 397            "MASTER LOGS": _show_parser("BINARY LOGS"),
 398            "BINLOG EVENTS": _show_parser("BINLOG EVENTS"),
 399            "CHARACTER SET": _show_parser("CHARACTER SET"),
 400            "CHARSET": _show_parser("CHARACTER SET"),
 401            "COLLATION": _show_parser("COLLATION"),
 402            "FULL COLUMNS": _show_parser("COLUMNS", target="FROM", full=True),
 403            "COLUMNS": _show_parser("COLUMNS", target="FROM"),
 404            "CREATE DATABASE": _show_parser("CREATE DATABASE", target=True),
 405            "CREATE EVENT": _show_parser("CREATE EVENT", target=True),
 406            "CREATE FUNCTION": _show_parser("CREATE FUNCTION", target=True),
 407            "CREATE PROCEDURE": _show_parser("CREATE PROCEDURE", target=True),
 408            "CREATE TABLE": _show_parser("CREATE TABLE", target=True),
 409            "CREATE TRIGGER": _show_parser("CREATE TRIGGER", target=True),
 410            "CREATE VIEW": _show_parser("CREATE VIEW", target=True),
 411            "DATABASES": _show_parser("DATABASES"),
 412            "SCHEMAS": _show_parser("DATABASES"),
 413            "ENGINE": _show_parser("ENGINE", target=True),
 414            "STORAGE ENGINES": _show_parser("ENGINES"),
 415            "ENGINES": _show_parser("ENGINES"),
 416            "ERRORS": _show_parser("ERRORS"),
 417            "EVENTS": _show_parser("EVENTS"),
 418            "FUNCTION CODE": _show_parser("FUNCTION CODE", target=True),
 419            "FUNCTION STATUS": _show_parser("FUNCTION STATUS"),
 420            "GRANTS": _show_parser("GRANTS", target="FOR"),
 421            "INDEX": _show_parser("INDEX", target="FROM"),
 422            "MASTER STATUS": _show_parser("MASTER STATUS"),
 423            "OPEN TABLES": _show_parser("OPEN TABLES"),
 424            "PLUGINS": _show_parser("PLUGINS"),
 425            "PROCEDURE CODE": _show_parser("PROCEDURE CODE", target=True),
 426            "PROCEDURE STATUS": _show_parser("PROCEDURE STATUS"),
 427            "PRIVILEGES": _show_parser("PRIVILEGES"),
 428            "FULL PROCESSLIST": _show_parser("PROCESSLIST", full=True),
 429            "PROCESSLIST": _show_parser("PROCESSLIST"),
 430            "PROFILE": _show_parser("PROFILE"),
 431            "PROFILES": _show_parser("PROFILES"),
 432            "RELAYLOG EVENTS": _show_parser("RELAYLOG EVENTS"),
 433            "REPLICAS": _show_parser("REPLICAS"),
 434            "SLAVE HOSTS": _show_parser("REPLICAS"),
 435            "REPLICA STATUS": _show_parser("REPLICA STATUS"),
 436            "SLAVE STATUS": _show_parser("REPLICA STATUS"),
 437            "GLOBAL STATUS": _show_parser("STATUS", global_=True),
 438            "SESSION STATUS": _show_parser("STATUS"),
 439            "STATUS": _show_parser("STATUS"),
 440            "TABLE STATUS": _show_parser("TABLE STATUS"),
 441            "FULL TABLES": _show_parser("TABLES", full=True),
 442            "TABLES": _show_parser("TABLES"),
 443            "TRIGGERS": _show_parser("TRIGGERS"),
 444            "GLOBAL VARIABLES": _show_parser("VARIABLES", global_=True),
 445            "SESSION VARIABLES": _show_parser("VARIABLES"),
 446            "VARIABLES": _show_parser("VARIABLES"),
 447            "WARNINGS": _show_parser("WARNINGS"),
 448        }
 449
 450        PROPERTY_PARSERS = {
 451            **parser.Parser.PROPERTY_PARSERS,
 452            "LOCK": lambda self: self._parse_property_assignment(exp.LockProperty),
 453            "PARTITION BY": lambda self: self._parse_partition_property(),
 454        }
 455
 456        SET_PARSERS = {
 457            **parser.Parser.SET_PARSERS,
 458            "PERSIST": lambda self: self._parse_set_item_assignment("PERSIST"),
 459            "PERSIST_ONLY": lambda self: self._parse_set_item_assignment("PERSIST_ONLY"),
 460            "CHARACTER SET": lambda self: self._parse_set_item_charset("CHARACTER SET"),
 461            "CHARSET": lambda self: self._parse_set_item_charset("CHARACTER SET"),
 462            "NAMES": lambda self: self._parse_set_item_names(),
 463        }
 464
 465        CONSTRAINT_PARSERS = {
 466            **parser.Parser.CONSTRAINT_PARSERS,
 467            "FULLTEXT": lambda self: self._parse_index_constraint(kind="FULLTEXT"),
 468            "INDEX": lambda self: self._parse_index_constraint(),
 469            "KEY": lambda self: self._parse_index_constraint(),
 470            "SPATIAL": lambda self: self._parse_index_constraint(kind="SPATIAL"),
 471            "ZEROFILL": lambda self: self.expression(exp.ZeroFillColumnConstraint),
 472        }
 473
 474        ALTER_PARSERS = {
 475            **parser.Parser.ALTER_PARSERS,
 476            "MODIFY": lambda self: self._parse_alter_table_alter(),
 477        }
 478
 479        ALTER_ALTER_PARSERS = {
 480            **parser.Parser.ALTER_ALTER_PARSERS,
 481            "INDEX": lambda self: self._parse_alter_table_alter_index(),
 482        }
 483
 484        SCHEMA_UNNAMED_CONSTRAINTS = {
 485            *parser.Parser.SCHEMA_UNNAMED_CONSTRAINTS,
 486            "FULLTEXT",
 487            "INDEX",
 488            "KEY",
 489            "SPATIAL",
 490        }
 491
 492        PROFILE_TYPES: parser.OPTIONS_TYPE = {
 493            **dict.fromkeys(("ALL", "CPU", "IPC", "MEMORY", "SOURCE", "SWAPS"), tuple()),
 494            "BLOCK": ("IO",),
 495            "CONTEXT": ("SWITCHES",),
 496            "PAGE": ("FAULTS",),
 497        }
 498
 499        TYPE_TOKENS = {
 500            *parser.Parser.TYPE_TOKENS,
 501            TokenType.SET,
 502        }
 503
 504        ENUM_TYPE_TOKENS = {
 505            *parser.Parser.ENUM_TYPE_TOKENS,
 506            TokenType.SET,
 507        }
 508
 509        # SELECT [ ALL | DISTINCT | DISTINCTROW ] [ <OPERATION_MODIFIERS> ]
 510        OPERATION_MODIFIERS = {
 511            "HIGH_PRIORITY",
 512            "STRAIGHT_JOIN",
 513            "SQL_SMALL_RESULT",
 514            "SQL_BIG_RESULT",
 515            "SQL_BUFFER_RESULT",
 516            "SQL_NO_CACHE",
 517            "SQL_CALC_FOUND_ROWS",
 518        }
 519
 520        LOG_DEFAULTS_TO_LN = True
 521        STRING_ALIASES = True
 522        VALUES_FOLLOWED_BY_PAREN = False
 523        SUPPORTS_PARTITION_SELECTION = True
 524
 525        def _parse_generated_as_identity(
 526            self,
 527        ) -> (
 528            exp.GeneratedAsIdentityColumnConstraint
 529            | exp.ComputedColumnConstraint
 530            | exp.GeneratedAsRowColumnConstraint
 531        ):
 532            this = super()._parse_generated_as_identity()
 533
 534            if self._match_texts(("STORED", "VIRTUAL")):
 535                persisted = self._prev.text.upper() == "STORED"
 536
 537                if isinstance(this, exp.ComputedColumnConstraint):
 538                    this.set("persisted", persisted)
 539                elif isinstance(this, exp.GeneratedAsIdentityColumnConstraint):
 540                    this = self.expression(
 541                        exp.ComputedColumnConstraint, this=this.expression, persisted=persisted
 542                    )
 543
 544            return this
 545
 546        def _parse_primary_key_part(self) -> t.Optional[exp.Expression]:
 547            this = self._parse_id_var()
 548            if not self._match(TokenType.L_PAREN):
 549                return this
 550
 551            expression = self._parse_number()
 552            self._match_r_paren()
 553            return self.expression(exp.ColumnPrefix, this=this, expression=expression)
 554
 555        def _parse_index_constraint(
 556            self, kind: t.Optional[str] = None
 557        ) -> exp.IndexColumnConstraint:
 558            if kind:
 559                self._match_texts(("INDEX", "KEY"))
 560
 561            this = self._parse_id_var(any_token=False)
 562            index_type = self._match(TokenType.USING) and self._advance_any() and self._prev.text
 563            expressions = self._parse_wrapped_csv(self._parse_ordered)
 564
 565            options = []
 566            while True:
 567                if self._match_text_seq("KEY_BLOCK_SIZE"):
 568                    self._match(TokenType.EQ)
 569                    opt = exp.IndexConstraintOption(key_block_size=self._parse_number())
 570                elif self._match(TokenType.USING):
 571                    opt = exp.IndexConstraintOption(using=self._advance_any() and self._prev.text)
 572                elif self._match_text_seq("WITH", "PARSER"):
 573                    opt = exp.IndexConstraintOption(parser=self._parse_var(any_token=True))
 574                elif self._match(TokenType.COMMENT):
 575                    opt = exp.IndexConstraintOption(comment=self._parse_string())
 576                elif self._match_text_seq("VISIBLE"):
 577                    opt = exp.IndexConstraintOption(visible=True)
 578                elif self._match_text_seq("INVISIBLE"):
 579                    opt = exp.IndexConstraintOption(visible=False)
 580                elif self._match_text_seq("ENGINE_ATTRIBUTE"):
 581                    self._match(TokenType.EQ)
 582                    opt = exp.IndexConstraintOption(engine_attr=self._parse_string())
 583                elif self._match_text_seq("SECONDARY_ENGINE_ATTRIBUTE"):
 584                    self._match(TokenType.EQ)
 585                    opt = exp.IndexConstraintOption(secondary_engine_attr=self._parse_string())
 586                else:
 587                    opt = None
 588
 589                if not opt:
 590                    break
 591
 592                options.append(opt)
 593
 594            return self.expression(
 595                exp.IndexColumnConstraint,
 596                this=this,
 597                expressions=expressions,
 598                kind=kind,
 599                index_type=index_type,
 600                options=options,
 601            )
 602
 603        def _parse_show_mysql(
 604            self,
 605            this: str,
 606            target: bool | str = False,
 607            full: t.Optional[bool] = None,
 608            global_: t.Optional[bool] = None,
 609        ) -> exp.Show:
 610            json = self._match_text_seq("JSON")
 611
 612            if target:
 613                if isinstance(target, str):
 614                    self._match_text_seq(*target.split(" "))
 615                target_id = self._parse_id_var()
 616            else:
 617                target_id = None
 618
 619            log = self._parse_string() if self._match_text_seq("IN") else None
 620
 621            if this in ("BINLOG EVENTS", "RELAYLOG EVENTS"):
 622                position = self._parse_number() if self._match_text_seq("FROM") else None
 623                db = None
 624            else:
 625                position = None
 626                db = None
 627
 628                if self._match(TokenType.FROM):
 629                    db = self._parse_id_var()
 630                elif self._match(TokenType.DOT):
 631                    db = target_id
 632                    target_id = self._parse_id_var()
 633
 634            channel = self._parse_id_var() if self._match_text_seq("FOR", "CHANNEL") else None
 635
 636            like = self._parse_string() if self._match_text_seq("LIKE") else None
 637            where = self._parse_where()
 638
 639            if this == "PROFILE":
 640                types = self._parse_csv(lambda: self._parse_var_from_options(self.PROFILE_TYPES))
 641                query = self._parse_number() if self._match_text_seq("FOR", "QUERY") else None
 642                offset = self._parse_number() if self._match_text_seq("OFFSET") else None
 643                limit = self._parse_number() if self._match_text_seq("LIMIT") else None
 644            else:
 645                types, query = None, None
 646                offset, limit = self._parse_oldstyle_limit()
 647
 648            mutex = True if self._match_text_seq("MUTEX") else None
 649            mutex = False if self._match_text_seq("STATUS") else mutex
 650
 651            for_table = self._parse_id_var() if self._match_text_seq("FOR", "TABLE") else None
 652            for_group = self._parse_string() if self._match_text_seq("FOR", "GROUP") else None
 653            for_user = self._parse_string() if self._match_text_seq("FOR", "USER") else None
 654            for_role = self._parse_string() if self._match_text_seq("FOR", "ROLE") else None
 655            into_outfile = self._parse_string() if self._match_text_seq("INTO", "OUTFILE") else None
 656
 657            return self.expression(
 658                exp.Show,
 659                this=this,
 660                target=target_id,
 661                full=full,
 662                log=log,
 663                position=position,
 664                db=db,
 665                channel=channel,
 666                like=like,
 667                where=where,
 668                types=types,
 669                query=query,
 670                offset=offset,
 671                limit=limit,
 672                mutex=mutex,
 673                for_table=for_table,
 674                for_group=for_group,
 675                for_user=for_user,
 676                for_role=for_role,
 677                into_outfile=into_outfile,
 678                json=json,
 679                global_=global_,
 680            )
 681
 682        def _parse_oldstyle_limit(
 683            self,
 684        ) -> t.Tuple[t.Optional[exp.Expression], t.Optional[exp.Expression]]:
 685            limit = None
 686            offset = None
 687            if self._match_text_seq("LIMIT"):
 688                parts = self._parse_csv(self._parse_number)
 689                if len(parts) == 1:
 690                    limit = parts[0]
 691                elif len(parts) == 2:
 692                    limit = parts[1]
 693                    offset = parts[0]
 694
 695            return offset, limit
 696
 697        def _parse_set_item_charset(self, kind: str) -> exp.Expression:
 698            this = self._parse_string() or self._parse_unquoted_field()
 699            return self.expression(exp.SetItem, this=this, kind=kind)
 700
 701        def _parse_set_item_names(self) -> exp.Expression:
 702            charset = self._parse_string() or self._parse_unquoted_field()
 703            if self._match_text_seq("COLLATE"):
 704                collate = self._parse_string() or self._parse_unquoted_field()
 705            else:
 706                collate = None
 707
 708            return self.expression(exp.SetItem, this=charset, collate=collate, kind="NAMES")
 709
 710        def _parse_type(
 711            self, parse_interval: bool = True, fallback_to_identifier: bool = False
 712        ) -> t.Optional[exp.Expression]:
 713            # mysql binary is special and can work anywhere, even in order by operations
 714            # it operates like a no paren func
 715            if self._match(TokenType.BINARY, advance=False):
 716                data_type = self._parse_types(check_func=True, allow_identifiers=False)
 717
 718                if isinstance(data_type, exp.DataType):
 719                    return self.expression(exp.Cast, this=self._parse_column(), to=data_type)
 720
 721            return super()._parse_type(
 722                parse_interval=parse_interval, fallback_to_identifier=fallback_to_identifier
 723            )
 724
 725        def _parse_alter_table_alter_index(self) -> exp.AlterIndex:
 726            index = self._parse_field(any_token=True)
 727
 728            if self._match_text_seq("VISIBLE"):
 729                visible = True
 730            elif self._match_text_seq("INVISIBLE"):
 731                visible = False
 732            else:
 733                visible = None
 734
 735            return self.expression(exp.AlterIndex, this=index, visible=visible)
 736
 737        def _parse_partition_property(
 738            self,
 739        ) -> t.Optional[exp.Expression] | t.List[exp.Expression]:
 740            partition_cls: t.Optional[t.Type[exp.Expression]] = None
 741            value_parser = None
 742
 743            if self._match_text_seq("RANGE"):
 744                partition_cls = exp.PartitionByRangeProperty
 745                value_parser = self._parse_partition_range_value
 746            elif self._match_text_seq("LIST"):
 747                partition_cls = exp.PartitionByListProperty
 748                value_parser = self._parse_partition_list_value
 749
 750            if not partition_cls or not value_parser:
 751                return None
 752
 753            partition_expressions = self._parse_wrapped_csv(self._parse_assignment)
 754
 755            # For Doris and Starrocks
 756            if not self._match_text_seq("(", "PARTITION", advance=False):
 757                return partition_expressions
 758
 759            create_expressions = self._parse_wrapped_csv(value_parser)
 760
 761            return self.expression(
 762                partition_cls,
 763                partition_expressions=partition_expressions,
 764                create_expressions=create_expressions,
 765            )
 766
 767        def _parse_partition_range_value(self) -> t.Optional[exp.Expression]:
 768            self._match_text_seq("PARTITION")
 769            name = self._parse_id_var()
 770
 771            if not self._match_text_seq("VALUES", "LESS", "THAN"):
 772                return name
 773
 774            values = self._parse_wrapped_csv(self._parse_expression)
 775
 776            if (
 777                len(values) == 1
 778                and isinstance(values[0], exp.Column)
 779                and values[0].name.upper() == "MAXVALUE"
 780            ):
 781                values = [exp.var("MAXVALUE")]
 782
 783            part_range = self.expression(exp.PartitionRange, this=name, expressions=values)
 784            return self.expression(exp.Partition, expressions=[part_range])
 785
 786        def _parse_partition_list_value(self) -> exp.Partition:
 787            self._match_text_seq("PARTITION")
 788            name = self._parse_id_var()
 789            self._match_text_seq("VALUES", "IN")
 790            values = self._parse_wrapped_csv(self._parse_expression)
 791            part_list = self.expression(exp.PartitionList, this=name, expressions=values)
 792            return self.expression(exp.Partition, expressions=[part_list])
 793
 794    class Generator(generator.Generator):
 795        INTERVAL_ALLOWS_PLURAL_FORM = False
 796        LOCKING_READS_SUPPORTED = True
 797        NULL_ORDERING_SUPPORTED: t.Optional[bool] = None
 798        JOIN_HINTS = False
 799        TABLE_HINTS = True
 800        DUPLICATE_KEY_UPDATE_WITH_SET = False
 801        QUERY_HINT_SEP = " "
 802        VALUES_AS_TABLE = False
 803        NVL2_SUPPORTED = False
 804        LAST_DAY_SUPPORTS_DATE_PART = False
 805        JSON_TYPE_REQUIRED_FOR_EXTRACTION = True
 806        JSON_PATH_BRACKETED_KEY_SUPPORTED = False
 807        JSON_KEY_VALUE_PAIR_SEP = ","
 808        SUPPORTS_TO_NUMBER = False
 809        PARSE_JSON_NAME: t.Optional[str] = None
 810        PAD_FILL_PATTERN_IS_REQUIRED = True
 811        WRAP_DERIVED_VALUES = False
 812        VARCHAR_REQUIRES_SIZE = True
 813        SUPPORTS_MEDIAN = False
 814        UPDATE_STATEMENT_SUPPORTS_FROM = False
 815
 816        TRANSFORMS = {
 817            **generator.Generator.TRANSFORMS,
 818            exp.ArrayAgg: rename_func("GROUP_CONCAT"),
 819            exp.BitwiseAndAgg: rename_func("BIT_AND"),
 820            exp.BitwiseOrAgg: rename_func("BIT_OR"),
 821            exp.BitwiseXorAgg: rename_func("BIT_XOR"),
 822            exp.BitwiseCount: rename_func("BIT_COUNT"),
 823            exp.Chr: lambda self, e: self.chr_sql(e, "CHAR"),
 824            exp.CurrentDate: no_paren_current_date_sql,
 825            exp.DateDiff: _remove_ts_or_ds_to_date(
 826                lambda self, e: self.func("DATEDIFF", e.this, e.expression), ("this", "expression")
 827            ),
 828            exp.DateAdd: _remove_ts_or_ds_to_date(date_add_sql("ADD")),
 829            exp.DateStrToDate: datestrtodate_sql,
 830            exp.DateSub: _remove_ts_or_ds_to_date(date_add_sql("SUB")),
 831            exp.DateTrunc: _date_trunc_sql,
 832            exp.Day: _remove_ts_or_ds_to_date(),
 833            exp.DayOfMonth: _remove_ts_or_ds_to_date(rename_func("DAYOFMONTH")),
 834            exp.DayOfWeek: _remove_ts_or_ds_to_date(rename_func("DAYOFWEEK")),
 835            exp.DayOfYear: _remove_ts_or_ds_to_date(rename_func("DAYOFYEAR")),
 836            exp.GroupConcat: lambda self,
 837            e: f"""GROUP_CONCAT({self.sql(e, "this")} SEPARATOR {self.sql(e, "separator") or "','"})""",
 838            exp.ILike: no_ilike_sql,
 839            exp.JSONExtractScalar: arrow_json_extract_sql,
 840            exp.Length: length_or_char_length_sql,
 841            exp.LogicalOr: rename_func("MAX"),
 842            exp.LogicalAnd: rename_func("MIN"),
 843            exp.Max: max_or_greatest,
 844            exp.Min: min_or_least,
 845            exp.Month: _remove_ts_or_ds_to_date(),
 846            exp.NullSafeEQ: lambda self, e: self.binary(e, "<=>"),
 847            exp.NullSafeNEQ: lambda self, e: f"NOT {self.binary(e, '<=>')}",
 848            exp.NumberToStr: rename_func("FORMAT"),
 849            exp.Pivot: no_pivot_sql,
 850            exp.Select: transforms.preprocess(
 851                [
 852                    transforms.eliminate_distinct_on,
 853                    transforms.eliminate_semi_and_anti_joins,
 854                    transforms.eliminate_qualify,
 855                    transforms.eliminate_full_outer_join,
 856                    transforms.unnest_generate_date_array_using_recursive_cte,
 857                ]
 858            ),
 859            exp.StrPosition: lambda self, e: strposition_sql(
 860                self, e, func_name="LOCATE", supports_position=True
 861            ),
 862            exp.StrToDate: _str_to_date_sql,
 863            exp.StrToTime: _str_to_date_sql,
 864            exp.Stuff: rename_func("INSERT"),
 865            exp.SessionUser: lambda *_: "SESSION_USER()",
 866            exp.TableSample: no_tablesample_sql,
 867            exp.TimeFromParts: rename_func("MAKETIME"),
 868            exp.TimestampAdd: date_add_interval_sql("DATE", "ADD"),
 869            exp.TimestampDiff: lambda self, e: self.func(
 870                "TIMESTAMPDIFF", unit_to_var(e), e.expression, e.this
 871            ),
 872            exp.TimestampSub: date_add_interval_sql("DATE", "SUB"),
 873            exp.TimeStrToUnix: rename_func("UNIX_TIMESTAMP"),
 874            exp.TimeStrToTime: lambda self, e: timestrtotime_sql(
 875                self,
 876                e,
 877                include_precision=not e.args.get("zone"),
 878            ),
 879            exp.TimeToStr: _remove_ts_or_ds_to_date(
 880                lambda self, e: self.func("DATE_FORMAT", e.this, self.format_time(e))
 881            ),
 882            exp.Trim: trim_sql,
 883            exp.TryCast: no_trycast_sql,
 884            exp.TsOrDsAdd: date_add_sql("ADD"),
 885            exp.TsOrDsDiff: lambda self, e: self.func("DATEDIFF", e.this, e.expression),
 886            exp.TsOrDsToDate: _ts_or_ds_to_date_sql,
 887            exp.Unicode: lambda self, e: f"ORD(CONVERT({self.sql(e.this)} USING utf32))",
 888            exp.UnixToTime: _unix_to_time_sql,
 889            exp.Week: _remove_ts_or_ds_to_date(),
 890            exp.WeekOfYear: _remove_ts_or_ds_to_date(rename_func("WEEKOFYEAR")),
 891            exp.Year: _remove_ts_or_ds_to_date(),
 892            exp.UtcTimestamp: rename_func("UTC_TIMESTAMP"),
 893            exp.UtcTime: rename_func("UTC_TIME"),
 894        }
 895
 896        UNSIGNED_TYPE_MAPPING = {
 897            exp.DataType.Type.UBIGINT: "BIGINT",
 898            exp.DataType.Type.UINT: "INT",
 899            exp.DataType.Type.UMEDIUMINT: "MEDIUMINT",
 900            exp.DataType.Type.USMALLINT: "SMALLINT",
 901            exp.DataType.Type.UTINYINT: "TINYINT",
 902            exp.DataType.Type.UDECIMAL: "DECIMAL",
 903            exp.DataType.Type.UDOUBLE: "DOUBLE",
 904        }
 905
 906        TIMESTAMP_TYPE_MAPPING = {
 907            exp.DataType.Type.DATETIME2: "DATETIME",
 908            exp.DataType.Type.SMALLDATETIME: "DATETIME",
 909            exp.DataType.Type.TIMESTAMP: "DATETIME",
 910            exp.DataType.Type.TIMESTAMPNTZ: "DATETIME",
 911            exp.DataType.Type.TIMESTAMPTZ: "TIMESTAMP",
 912            exp.DataType.Type.TIMESTAMPLTZ: "TIMESTAMP",
 913        }
 914
 915        TYPE_MAPPING = {
 916            **generator.Generator.TYPE_MAPPING,
 917            **UNSIGNED_TYPE_MAPPING,
 918            **TIMESTAMP_TYPE_MAPPING,
 919        }
 920
 921        TYPE_MAPPING.pop(exp.DataType.Type.MEDIUMTEXT)
 922        TYPE_MAPPING.pop(exp.DataType.Type.LONGTEXT)
 923        TYPE_MAPPING.pop(exp.DataType.Type.TINYTEXT)
 924        TYPE_MAPPING.pop(exp.DataType.Type.BLOB)
 925        TYPE_MAPPING.pop(exp.DataType.Type.MEDIUMBLOB)
 926        TYPE_MAPPING.pop(exp.DataType.Type.LONGBLOB)
 927        TYPE_MAPPING.pop(exp.DataType.Type.TINYBLOB)
 928
 929        PROPERTIES_LOCATION = {
 930            **generator.Generator.PROPERTIES_LOCATION,
 931            exp.TransientProperty: exp.Properties.Location.UNSUPPORTED,
 932            exp.VolatileProperty: exp.Properties.Location.UNSUPPORTED,
 933            exp.PartitionedByProperty: exp.Properties.Location.UNSUPPORTED,
 934            exp.PartitionByRangeProperty: exp.Properties.Location.POST_SCHEMA,
 935            exp.PartitionByListProperty: exp.Properties.Location.POST_SCHEMA,
 936        }
 937
 938        LIMIT_FETCH = "LIMIT"
 939
 940        LIMIT_ONLY_LITERALS = True
 941
 942        CHAR_CAST_MAPPING = dict.fromkeys(
 943            (
 944                exp.DataType.Type.LONGTEXT,
 945                exp.DataType.Type.LONGBLOB,
 946                exp.DataType.Type.MEDIUMBLOB,
 947                exp.DataType.Type.MEDIUMTEXT,
 948                exp.DataType.Type.TEXT,
 949                exp.DataType.Type.TINYBLOB,
 950                exp.DataType.Type.TINYTEXT,
 951                exp.DataType.Type.VARCHAR,
 952            ),
 953            "CHAR",
 954        )
 955        SIGNED_CAST_MAPPING = dict.fromkeys(
 956            (
 957                exp.DataType.Type.BIGINT,
 958                exp.DataType.Type.BOOLEAN,
 959                exp.DataType.Type.INT,
 960                exp.DataType.Type.SMALLINT,
 961                exp.DataType.Type.TINYINT,
 962                exp.DataType.Type.MEDIUMINT,
 963            ),
 964            "SIGNED",
 965        )
 966
 967        # MySQL doesn't support many datatypes in cast.
 968        # https://dev.mysql.com/doc/refman/8.0/en/cast-functions.html#function_cast
 969        CAST_MAPPING = {
 970            **CHAR_CAST_MAPPING,
 971            **SIGNED_CAST_MAPPING,
 972            exp.DataType.Type.UBIGINT: "UNSIGNED",
 973        }
 974
 975        TIMESTAMP_FUNC_TYPES = {
 976            exp.DataType.Type.TIMESTAMPTZ,
 977            exp.DataType.Type.TIMESTAMPLTZ,
 978        }
 979
 980        # https://dev.mysql.com/doc/refman/8.0/en/keywords.html
 981        RESERVED_KEYWORDS = {
 982            "accessible",
 983            "add",
 984            "all",
 985            "alter",
 986            "analyze",
 987            "and",
 988            "as",
 989            "asc",
 990            "asensitive",
 991            "before",
 992            "between",
 993            "bigint",
 994            "binary",
 995            "blob",
 996            "both",
 997            "by",
 998            "call",
 999            "cascade",
1000            "case",
1001            "change",
1002            "char",
1003            "character",
1004            "check",
1005            "collate",
1006            "column",
1007            "condition",
1008            "constraint",
1009            "continue",
1010            "convert",
1011            "create",
1012            "cross",
1013            "cube",
1014            "cume_dist",
1015            "current_date",
1016            "current_time",
1017            "current_timestamp",
1018            "current_user",
1019            "cursor",
1020            "database",
1021            "databases",
1022            "day_hour",
1023            "day_microsecond",
1024            "day_minute",
1025            "day_second",
1026            "dec",
1027            "decimal",
1028            "declare",
1029            "default",
1030            "delayed",
1031            "delete",
1032            "dense_rank",
1033            "desc",
1034            "describe",
1035            "deterministic",
1036            "distinct",
1037            "distinctrow",
1038            "div",
1039            "double",
1040            "drop",
1041            "dual",
1042            "each",
1043            "else",
1044            "elseif",
1045            "empty",
1046            "enclosed",
1047            "escaped",
1048            "except",
1049            "exists",
1050            "exit",
1051            "explain",
1052            "false",
1053            "fetch",
1054            "first_value",
1055            "float",
1056            "float4",
1057            "float8",
1058            "for",
1059            "force",
1060            "foreign",
1061            "from",
1062            "fulltext",
1063            "function",
1064            "generated",
1065            "get",
1066            "grant",
1067            "group",
1068            "grouping",
1069            "groups",
1070            "having",
1071            "high_priority",
1072            "hour_microsecond",
1073            "hour_minute",
1074            "hour_second",
1075            "if",
1076            "ignore",
1077            "in",
1078            "index",
1079            "infile",
1080            "inner",
1081            "inout",
1082            "insensitive",
1083            "insert",
1084            "int",
1085            "int1",
1086            "int2",
1087            "int3",
1088            "int4",
1089            "int8",
1090            "integer",
1091            "intersect",
1092            "interval",
1093            "into",
1094            "io_after_gtids",
1095            "io_before_gtids",
1096            "is",
1097            "iterate",
1098            "join",
1099            "json_table",
1100            "key",
1101            "keys",
1102            "kill",
1103            "lag",
1104            "last_value",
1105            "lateral",
1106            "lead",
1107            "leading",
1108            "leave",
1109            "left",
1110            "like",
1111            "limit",
1112            "linear",
1113            "lines",
1114            "load",
1115            "localtime",
1116            "localtimestamp",
1117            "lock",
1118            "long",
1119            "longblob",
1120            "longtext",
1121            "loop",
1122            "low_priority",
1123            "master_bind",
1124            "master_ssl_verify_server_cert",
1125            "match",
1126            "maxvalue",
1127            "mediumblob",
1128            "mediumint",
1129            "mediumtext",
1130            "middleint",
1131            "minute_microsecond",
1132            "minute_second",
1133            "mod",
1134            "modifies",
1135            "natural",
1136            "not",
1137            "no_write_to_binlog",
1138            "nth_value",
1139            "ntile",
1140            "null",
1141            "numeric",
1142            "of",
1143            "on",
1144            "optimize",
1145            "optimizer_costs",
1146            "option",
1147            "optionally",
1148            "or",
1149            "order",
1150            "out",
1151            "outer",
1152            "outfile",
1153            "over",
1154            "partition",
1155            "percent_rank",
1156            "precision",
1157            "primary",
1158            "procedure",
1159            "purge",
1160            "range",
1161            "rank",
1162            "read",
1163            "reads",
1164            "read_write",
1165            "real",
1166            "recursive",
1167            "references",
1168            "regexp",
1169            "release",
1170            "rename",
1171            "repeat",
1172            "replace",
1173            "require",
1174            "resignal",
1175            "restrict",
1176            "return",
1177            "revoke",
1178            "right",
1179            "rlike",
1180            "row",
1181            "rows",
1182            "row_number",
1183            "schema",
1184            "schemas",
1185            "second_microsecond",
1186            "select",
1187            "sensitive",
1188            "separator",
1189            "set",
1190            "show",
1191            "signal",
1192            "smallint",
1193            "spatial",
1194            "specific",
1195            "sql",
1196            "sqlexception",
1197            "sqlstate",
1198            "sqlwarning",
1199            "sql_big_result",
1200            "sql_calc_found_rows",
1201            "sql_small_result",
1202            "ssl",
1203            "starting",
1204            "stored",
1205            "straight_join",
1206            "system",
1207            "table",
1208            "terminated",
1209            "then",
1210            "tinyblob",
1211            "tinyint",
1212            "tinytext",
1213            "to",
1214            "trailing",
1215            "trigger",
1216            "true",
1217            "undo",
1218            "union",
1219            "unique",
1220            "unlock",
1221            "unsigned",
1222            "update",
1223            "usage",
1224            "use",
1225            "using",
1226            "utc_date",
1227            "utc_time",
1228            "utc_timestamp",
1229            "values",
1230            "varbinary",
1231            "varchar",
1232            "varcharacter",
1233            "varying",
1234            "virtual",
1235            "when",
1236            "where",
1237            "while",
1238            "window",
1239            "with",
1240            "write",
1241            "xor",
1242            "year_month",
1243            "zerofill",
1244        }
1245
1246        def computedcolumnconstraint_sql(self, expression: exp.ComputedColumnConstraint) -> str:
1247            persisted = "STORED" if expression.args.get("persisted") else "VIRTUAL"
1248            return f"GENERATED ALWAYS AS ({self.sql(expression.this.unnest())}) {persisted}"
1249
1250        def array_sql(self, expression: exp.Array) -> str:
1251            self.unsupported("Arrays are not supported by MySQL")
1252            return self.function_fallback_sql(expression)
1253
1254        def arraycontainsall_sql(self, expression: exp.ArrayContainsAll) -> str:
1255            self.unsupported("Array operations are not supported by MySQL")
1256            return self.function_fallback_sql(expression)
1257
1258        def dpipe_sql(self, expression: exp.DPipe) -> str:
1259            return self.func("CONCAT", *expression.flatten())
1260
1261        def extract_sql(self, expression: exp.Extract) -> str:
1262            unit = expression.name
1263            if unit and unit.lower() == "epoch":
1264                return self.func("UNIX_TIMESTAMP", expression.expression)
1265
1266            return super().extract_sql(expression)
1267
1268        def datatype_sql(self, expression: exp.DataType) -> str:
1269            if (
1270                self.VARCHAR_REQUIRES_SIZE
1271                and expression.is_type(exp.DataType.Type.VARCHAR)
1272                and not expression.expressions
1273            ):
1274                # `VARCHAR` must always have a size - if it doesn't, we always generate `TEXT`
1275                return "TEXT"
1276
1277            # https://dev.mysql.com/doc/refman/8.0/en/numeric-type-syntax.html
1278            result = super().datatype_sql(expression)
1279            if expression.this in self.UNSIGNED_TYPE_MAPPING:
1280                result = f"{result} UNSIGNED"
1281
1282            return result
1283
1284        def jsonarraycontains_sql(self, expression: exp.JSONArrayContains) -> str:
1285            return f"{self.sql(expression, 'this')} MEMBER OF({self.sql(expression, 'expression')})"
1286
1287        def cast_sql(self, expression: exp.Cast, safe_prefix: t.Optional[str] = None) -> str:
1288            if expression.to.this in self.TIMESTAMP_FUNC_TYPES:
1289                return self.func("TIMESTAMP", expression.this)
1290
1291            to = self.CAST_MAPPING.get(expression.to.this)
1292
1293            if to:
1294                expression.to.set("this", to)
1295            return super().cast_sql(expression)
1296
1297        def show_sql(self, expression: exp.Show) -> str:
1298            this = f" {expression.name}"
1299            full = " FULL" if expression.args.get("full") else ""
1300            global_ = " GLOBAL" if expression.args.get("global_") else ""
1301
1302            target = self.sql(expression, "target")
1303            target = f" {target}" if target else ""
1304            if expression.name in ("COLUMNS", "INDEX"):
1305                target = f" FROM{target}"
1306            elif expression.name == "GRANTS":
1307                target = f" FOR{target}"
1308            elif expression.name in ("LINKS", "PARTITIONS"):
1309                target = f" ON{target}" if target else ""
1310            elif expression.name == "PROJECTIONS":
1311                target = f" ON TABLE{target}" if target else ""
1312
1313            db = self._prefixed_sql("FROM", expression, "db")
1314
1315            like = self._prefixed_sql("LIKE", expression, "like")
1316            where = self.sql(expression, "where")
1317
1318            types = self.expressions(expression, key="types")
1319            types = f" {types}" if types else types
1320            query = self._prefixed_sql("FOR QUERY", expression, "query")
1321
1322            if expression.name == "PROFILE":
1323                offset = self._prefixed_sql("OFFSET", expression, "offset")
1324                limit = self._prefixed_sql("LIMIT", expression, "limit")
1325            else:
1326                offset = ""
1327                limit = self._oldstyle_limit_sql(expression)
1328
1329            log = self._prefixed_sql("IN", expression, "log")
1330            position = self._prefixed_sql("FROM", expression, "position")
1331
1332            channel = self._prefixed_sql("FOR CHANNEL", expression, "channel")
1333
1334            if expression.name == "ENGINE":
1335                mutex_or_status = " MUTEX" if expression.args.get("mutex") else " STATUS"
1336            else:
1337                mutex_or_status = ""
1338
1339            for_table = self._prefixed_sql("FOR TABLE", expression, "for_table")
1340            for_group = self._prefixed_sql("FOR GROUP", expression, "for_group")
1341            for_user = self._prefixed_sql("FOR USER", expression, "for_user")
1342            for_role = self._prefixed_sql("FOR ROLE", expression, "for_role")
1343            into_outfile = self._prefixed_sql("INTO OUTFILE", expression, "into_outfile")
1344            json = " JSON" if expression.args.get("json") else ""
1345
1346            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}"
1347
1348        def alterrename_sql(self, expression: exp.AlterRename, include_to: bool = True) -> str:
1349            """To avoid TO keyword in ALTER ... RENAME statements.
1350            It's moved from Doris, because it's the same for all MySQL, Doris, and StarRocks.
1351            """
1352            return super().alterrename_sql(expression, include_to=False)
1353
1354        def altercolumn_sql(self, expression: exp.AlterColumn) -> str:
1355            dtype = self.sql(expression, "dtype")
1356            if not dtype:
1357                return super().altercolumn_sql(expression)
1358
1359            this = self.sql(expression, "this")
1360            return f"MODIFY COLUMN {this} {dtype}"
1361
1362        def _prefixed_sql(self, prefix: str, expression: exp.Expression, arg: str) -> str:
1363            sql = self.sql(expression, arg)
1364            return f" {prefix} {sql}" if sql else ""
1365
1366        def _oldstyle_limit_sql(self, expression: exp.Show) -> str:
1367            limit = self.sql(expression, "limit")
1368            offset = self.sql(expression, "offset")
1369            if limit:
1370                limit_offset = f"{offset}, {limit}" if offset else limit
1371                return f" LIMIT {limit_offset}"
1372            return ""
1373
1374        def timestamptrunc_sql(self, expression: exp.TimestampTrunc) -> str:
1375            unit = expression.args.get("unit")
1376
1377            # Pick an old-enough date to avoid negative timestamp diffs
1378            start_ts = "'0000-01-01 00:00:00'"
1379
1380            # Source: https://stackoverflow.com/a/32955740
1381            timestamp_diff = build_date_delta(exp.TimestampDiff)([unit, start_ts, expression.this])
1382            interval = exp.Interval(this=timestamp_diff, unit=unit)
1383            dateadd = build_date_delta_with_interval(exp.DateAdd)([start_ts, interval])
1384
1385            return self.sql(dateadd)
1386
1387        def converttimezone_sql(self, expression: exp.ConvertTimezone) -> str:
1388            from_tz = expression.args.get("source_tz")
1389            to_tz = expression.args.get("target_tz")
1390            dt = expression.args.get("timestamp")
1391
1392            return self.func("CONVERT_TZ", dt, from_tz, to_tz)
1393
1394        def attimezone_sql(self, expression: exp.AtTimeZone) -> str:
1395            self.unsupported("AT TIME ZONE is not supported by MySQL")
1396            return self.sql(expression.this)
1397
1398        def isascii_sql(self, expression: exp.IsAscii) -> str:
1399            return f"REGEXP_LIKE({self.sql(expression.this)}, '^[[:ascii:]]*$')"
1400
1401        def ignorenulls_sql(self, expression: exp.IgnoreNulls) -> str:
1402            # https://dev.mysql.com/doc/refman/8.4/en/window-function-descriptions.html
1403            self.unsupported("MySQL does not support IGNORE NULLS.")
1404            return self.sql(expression.this)
1405
1406        @unsupported_args("this")
1407        def currentschema_sql(self, expression: exp.CurrentSchema) -> str:
1408            return self.func("SCHEMA")
1409
1410        def partition_sql(self, expression: exp.Partition) -> str:
1411            parent = expression.parent
1412            if isinstance(parent, (exp.PartitionByRangeProperty, exp.PartitionByListProperty)):
1413                return self.expressions(expression, flat=True)
1414            return super().partition_sql(expression)
1415
1416        def _partition_by_sql(
1417            self, expression: exp.PartitionByRangeProperty | exp.PartitionByListProperty, kind: str
1418        ) -> str:
1419            partitions = self.expressions(expression, key="partition_expressions", flat=True)
1420            create = self.expressions(expression, key="create_expressions", flat=True)
1421            return f"PARTITION BY {kind} ({partitions}) ({create})"
1422
1423        def partitionbyrangeproperty_sql(self, expression: exp.PartitionByRangeProperty) -> str:
1424            return self._partition_by_sql(expression, "RANGE")
1425
1426        def partitionbylistproperty_sql(self, expression: exp.PartitionByListProperty) -> str:
1427            return self._partition_by_sql(expression, "LIST")
1428
1429        def partitionlist_sql(self, expression: exp.PartitionList) -> str:
1430            name = self.sql(expression, "this")
1431            values = self.expressions(expression, flat=True)
1432            return f"PARTITION {name} VALUES IN ({values})"
1433
1434        def partitionrange_sql(self, expression: exp.PartitionRange) -> str:
1435            name = self.sql(expression, "this")
1436            values = self.expressions(expression, flat=True)
1437            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'>: {'annotator': <function <dictcomp>.<lambda>>}, <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.CountIf'>: {'returns': <Type.BIGINT: 'BIGINT'>}, <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.ArraySize'>: {'returns': <Type.BIGINT: 'BIGINT'>}, <class 'sqlglot.expressions.UnixDate'>: {'returns': <Type.BIGINT: 'BIGINT'>}, <class 'sqlglot.expressions.UnixSeconds'>: {'returns': <Type.BIGINT: 'BIGINT'>}, <class 'sqlglot.expressions.ApproxDistinct'>: {'returns': <Type.BIGINT: 'BIGINT'>}, <class 'sqlglot.expressions.FromBase64'>: {'returns': <Type.BINARY: 'BINARY'>}, <class 'sqlglot.expressions.FromBase32'>: {'returns': <Type.BINARY: 'BINARY'>}, <class 'sqlglot.expressions.In'>: {'returns': <Type.BOOLEAN: 'BOOLEAN'>}, <class 'sqlglot.expressions.IsNan'>: {'returns': <Type.BOOLEAN: 'BOOLEAN'>}, <class 'sqlglot.expressions.Contains'>: {'returns': <Type.BOOLEAN: 'BOOLEAN'>}, <class 'sqlglot.expressions.EndsWith'>: {'returns': <Type.BOOLEAN: 'BOOLEAN'>}, <class 'sqlglot.expressions.Between'>: {'returns': <Type.BOOLEAN: 'BOOLEAN'>}, <class 'sqlglot.expressions.Exists'>: {'returns': <Type.BOOLEAN: 'BOOLEAN'>}, <class 'sqlglot.expressions.LogicalAnd'>: {'returns': <Type.BOOLEAN: 'BOOLEAN'>}, <class 'sqlglot.expressions.StartsWith'>: {'returns': <Type.BOOLEAN: 'BOOLEAN'>}, <class 'sqlglot.expressions.Any'>: {'returns': <Type.BOOLEAN: 'BOOLEAN'>}, <class 'sqlglot.expressions.LogicalOr'>: {'returns': <Type.BOOLEAN: 'BOOLEAN'>}, <class 'sqlglot.expressions.Boolean'>: {'returns': <Type.BOOLEAN: 'BOOLEAN'>}, <class 'sqlglot.expressions.All'>: {'returns': <Type.BOOLEAN: 'BOOLEAN'>}, <class 'sqlglot.expressions.IsInf'>: {'returns': <Type.BOOLEAN: 'BOOLEAN'>}, <class 'sqlglot.expressions.CurrentDate'>: {'returns': <Type.DATE: 'DATE'>}, <class 'sqlglot.expressions.DateFromParts'>: {'returns': <Type.DATE: 'DATE'>}, <class 'sqlglot.expressions.TimeStrToDate'>: {'returns': <Type.DATE: 'DATE'>}, <class 'sqlglot.expressions.TsOrDsToDate'>: {'returns': <Type.DATE: 'DATE'>}, <class 'sqlglot.expressions.LastDay'>: {'returns': <Type.DATE: 'DATE'>}, <class 'sqlglot.expressions.DiToDate'>: {'returns': <Type.DATE: 'DATE'>}, <class 'sqlglot.expressions.Date'>: {'returns': <Type.DATE: 'DATE'>}, <class 'sqlglot.expressions.DateStrToDate'>: {'returns': <Type.DATE: 'DATE'>}, <class 'sqlglot.expressions.StrToDate'>: {'returns': <Type.DATE: 'DATE'>}, <class 'sqlglot.expressions.CurrentDatetime'>: {'returns': <Type.DATETIME: 'DATETIME'>}, <class 'sqlglot.expressions.DatetimeAdd'>: {'returns': <Type.DATETIME: 'DATETIME'>}, <class 'sqlglot.expressions.Datetime'>: {'returns': <Type.DATETIME: 'DATETIME'>}, <class 'sqlglot.expressions.DatetimeSub'>: {'returns': <Type.DATETIME: 'DATETIME'>}, <class 'sqlglot.expressions.Kurtosis'>: {'returns': <Type.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.Variance'>: {'returns': <Type.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.Radians'>: {'returns': <Type.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.Exp'>: {'returns': <Type.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.StddevSamp'>: {'returns': <Type.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.Stddev'>: {'returns': <Type.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.Ln'>: {'returns': <Type.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.Pi'>: {'returns': <Type.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.Quantile'>: {'returns': <Type.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.Skewness'>: {'returns': <Type.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.VariancePop'>: {'returns': <Type.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.Round'>: {'returns': <Type.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.Cbrt'>: {'returns': <Type.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.Avg'>: {'returns': <Type.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.StddevPop'>: {'returns': <Type.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.ToDouble'>: {'returns': <Type.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.Sqrt'>: {'returns': <Type.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.Log'>: {'returns': <Type.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.SafeDivide'>: {'returns': <Type.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.ApproxQuantile'>: {'returns': <Type.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.Ceil'>: {'returns': <Type.INT: 'INT'>}, <class 'sqlglot.expressions.Levenshtein'>: {'returns': <Type.INT: 'INT'>}, <class 'sqlglot.expressions.BitLength'>: {'returns': <Type.INT: 'INT'>}, <class 'sqlglot.expressions.TsOrDiToDi'>: {'returns': <Type.INT: 'INT'>}, <class 'sqlglot.expressions.TimestampDiff'>: {'returns': <Type.INT: 'INT'>}, <class 'sqlglot.expressions.StrPosition'>: {'returns': <Type.INT: 'INT'>}, <class 'sqlglot.expressions.TimeDiff'>: {'returns': <Type.INT: 'INT'>}, <class 'sqlglot.expressions.Length'>: {'returns': <Type.INT: 'INT'>}, <class 'sqlglot.expressions.Ascii'>: {'returns': <Type.INT: 'INT'>}, <class 'sqlglot.expressions.DatetimeDiff'>: {'returns': <Type.INT: 'INT'>}, <class 'sqlglot.expressions.Quarter'>: {'returns': <Type.INT: 'INT'>}, <class 'sqlglot.expressions.Sign'>: {'returns': <Type.INT: 'INT'>}, <class 'sqlglot.expressions.Getbit'>: {'returns': <Type.INT: 'INT'>}, <class 'sqlglot.expressions.Unicode'>: {'returns': <Type.INT: 'INT'>}, <class 'sqlglot.expressions.DateToDi'>: {'returns': <Type.INT: 'INT'>}, <class 'sqlglot.expressions.JustifyInterval'>: {'returns': <Type.INTERVAL: 'INTERVAL'>}, <class 'sqlglot.expressions.JustifyHours'>: {'returns': <Type.INTERVAL: 'INTERVAL'>}, <class 'sqlglot.expressions.JustifyDays'>: {'returns': <Type.INTERVAL: 'INTERVAL'>}, <class 'sqlglot.expressions.Interval'>: {'returns': <Type.INTERVAL: 'INTERVAL'>}, <class 'sqlglot.expressions.MakeInterval'>: {'returns': <Type.INTERVAL: 'INTERVAL'>}, <class 'sqlglot.expressions.ParseJSON'>: {'returns': <Type.JSON: 'JSON'>}, <class 'sqlglot.expressions.Time'>: {'returns': <Type.TIME: 'TIME'>}, <class 'sqlglot.expressions.TimeSub'>: {'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.TimestampLtzFromParts'>: {'returns': <Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>}, <class 'sqlglot.expressions.CurrentTimestampLTZ'>: {'returns': <Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>}, <class 'sqlglot.expressions.TimestampTzFromParts'>: {'returns': <Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>}, <class 'sqlglot.expressions.TimestampAdd'>: {'returns': <Type.TIMESTAMP: 'TIMESTAMP'>}, <class 'sqlglot.expressions.CurrentTimestamp'>: {'returns': <Type.TIMESTAMP: 'TIMESTAMP'>}, <class 'sqlglot.expressions.TimeStrToTime'>: {'returns': <Type.TIMESTAMP: 'TIMESTAMP'>}, <class 'sqlglot.expressions.StrToTime'>: {'returns': <Type.TIMESTAMP: 'TIMESTAMP'>}, <class 'sqlglot.expressions.UnixToTime'>: {'returns': <Type.TIMESTAMP: 'TIMESTAMP'>}, <class 'sqlglot.expressions.TimestampSub'>: {'returns': <Type.TIMESTAMP: 'TIMESTAMP'>}, <class 'sqlglot.expressions.DayOfWeekIso'>: {'returns': <Type.TINYINT: 'TINYINT'>}, <class 'sqlglot.expressions.DayOfWeek'>: {'returns': <Type.INT: 'INT'>}, <class 'sqlglot.expressions.YearOfWeekIso'>: {'returns': <Type.TINYINT: 'TINYINT'>}, <class 'sqlglot.expressions.Month'>: {'returns': <Type.INT: 'INT'>}, <class 'sqlglot.expressions.YearOfWeek'>: {'returns': <Type.TINYINT: 'TINYINT'>}, <class 'sqlglot.expressions.WeekOfYear'>: {'returns': <Type.TINYINT: 'TINYINT'>}, <class 'sqlglot.expressions.Week'>: {'returns': <Type.TINYINT: 'TINYINT'>}, <class 'sqlglot.expressions.Year'>: {'returns': <Type.TINYINT: 'TINYINT'>}, <class 'sqlglot.expressions.Day'>: {'returns': <Type.TINYINT: 'TINYINT'>}, <class 'sqlglot.expressions.DayOfYear'>: {'returns': <Type.TINYINT: 'TINYINT'>}, <class 'sqlglot.expressions.DayOfMonth'>: {'returns': <Type.TINYINT: 'TINYINT'>}, <class 'sqlglot.expressions.String'>: {'returns': <Type.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.DateToDateStr'>: {'returns': <Type.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.Trim'>: {'returns': <Type.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.GroupConcat'>: {'returns': <Type.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.ToBase64'>: {'returns': <Type.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.Dayname'>: {'returns': <Type.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.UnixToStr'>: {'returns': <Type.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.TimeToStr'>: {'returns': <Type.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.SHA'>: {'returns': <Type.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.Lower'>: {'returns': <Type.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.ConcatWs'>: {'returns': <Type.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.Chr'>: {'returns': <Type.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.TsOrDsToDateStr'>: {'returns': <Type.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.Space'>: {'returns': <Type.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.Initcap'>: {'returns': <Type.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.RawString'>: {'returns': <Type.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.ToBase32'>: {'returns': <Type.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.TimeToTimeStr'>: {'returns': <Type.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.Upper'>: {'returns': <Type.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.SHA2'>: {'returns': <Type.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.ArrayToString'>: {'returns': <Type.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.Concat'>: {'returns': <Type.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.UnixToTimeStr'>: {'returns': <Type.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.Substring'>: {'returns': <Type.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.LastValue'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.Filter'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.ArraySlice'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.Limit'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.HavingMax'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.Window'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.ArrayReverse'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.SortArray'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.ArrayConcatAgg'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.Order'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.Abs'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.AnyValue'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.ArrayConcat'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.Max'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.Min'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.Coalesce'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.Greatest'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.Least'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.ArrayLast'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.ArrayFirst'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.Anonymous'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.DateAdd'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.DateSub'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.DateTrunc'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.TryCast'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.Cast'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.Map'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.VarMap'>: {'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.Cot'>: {'returns': <Type.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.Atan2'>: {'returns': <Type.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.Sin'>: {'returns': <Type.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.Tan'>: {'returns': <Type.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.Atan'>: {'returns': <Type.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.Asin'>: {'returns': <Type.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.Degrees'>: {'returns': <Type.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.Cos'>: {'returns': <Type.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.Acos'>: {'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] = {'MON', 'DAY OF YEAR', 'YEARS', 'EPOCH_NANOSECONDS', 'WEEKOFYEAR', 'DAY_MINUTE', 'M', 'MIL', 'DY', 'MINUTE', 'Y', 'MILS', 'MONS', 'NSEC', 'DOW', 'EPOCH_MICROSECONDS', 'YYYY', 'YEAR_MONTH', 'Q', 'DAY OF WEEK', 'HR', 'MILLISECONDS', 'DW_ISO', 'QTRS', 'SECOND_MICROSECOND', 'HOUR_MICROSECOND', 'W', 'NSECONDS', 'US', 'MINUTES', 'NANOSECS', 'NANOSECOND', 'MILLISECS', 'DECADES', 'EPOCH_SECONDS', 'MILLISECOND', 'C', 'DAY_SECOND', 'DECS', 'DAYOFWEEK', 'DECADE', 'DAYS', 'CENTURY', 'YY', 'YR', 'SEC', 'QTR', 'DAY_MICROSECOND', 'MIN', 'WK', 'MM', 'DD', 'DW', 'YYY', 'TIMEZONE_HOUR', 'DOY', 'EPOCH_MILLISECONDS', 'TZH', 'DAYOFWEEK_ISO', 'MSEC', 'NANOSEC', 'CENTURIES', 'MICROSECS', 'MILLISECON', 'S', 'MI', 'WEEKDAY', 'EPOCH_NANOSECOND', 'WEEKOFYEARISO', 'MSECOND', 'HOURS', 'USECOND', 'EPOCH_SECOND', 'DAY', 'HH', 'SECS', 'MINUTE_MICROSECOND', 'NSECOND', 'EPOCH_MICROSECOND', 'MONTH', 'TZM', 'DOW_ISO', 'YEAR', 'D', 'MSECS', 'DAYOFMONTH', 'EPOCH_MILLISECOND', 'HOUR', 'DAY_HOUR', 'YRS', 'WY', 'MICROSECONDS', 'HOUR_MINUTE', 'HOUR_SECOND', 'DAYOFWEEKISO', 'WOY', 'WEEKDAY_ISO', 'H', 'MINS', 'MSECONDS', 'HRS', 'WEEK_ISO', 'TIMEZONE_MINUTE', 'MILLENNIUM', 'USECS', 'MINUTE_SECOND', 'MILLISEC', 'MICROSECOND', 'WEEKOFYEAR_ISO', 'SECOND', 'USECONDS', 'WEEKISO', 'QUARTERS', 'MONTHS', 'MICROSEC', 'WEEK', 'DAYOFYEAR', 'QUARTER', 'CENTS', 'EPOCH', 'CENT', 'MILLENIA', 'DEC', 'NS', 'SECONDS', 'USEC', 'MS'}
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.tokens.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: 'BLOCK_START'>, '{%+': <TokenType.BLOCK_START: 'BLOCK_START'>, '{%-': <TokenType.BLOCK_START: 'BLOCK_START'>, '%}': <TokenType.BLOCK_END: 'BLOCK_END'>, '+%}': <TokenType.BLOCK_END: 'BLOCK_END'>, '-%}': <TokenType.BLOCK_END: 'BLOCK_END'>, '{{+': <TokenType.BLOCK_START: 'BLOCK_START'>, '{{-': <TokenType.BLOCK_START: 'BLOCK_START'>, '+}}': <TokenType.BLOCK_END: 'BLOCK_END'>, '-}}': <TokenType.BLOCK_END: 'BLOCK_END'>, '/*+': <TokenType.HINT: 'HINT'>, '&<': <TokenType.AMP_LT: 'AMP_LT'>, '&>': <TokenType.AMP_GT: 'AMP_GT'>, '==': <TokenType.EQ: 'EQ'>, '::': <TokenType.DCOLON: 'DCOLON'>, '?::': <TokenType.QDCOLON: 'QDCOLON'>, '||': <TokenType.DPIPE: 'DPIPE'>, '|>': <TokenType.PIPE_GT: 'PIPE_GT'>, '>=': <TokenType.GTE: 'GTE'>, '<=': <TokenType.LTE: 'LTE'>, '<>': <TokenType.NEQ: 'NEQ'>, '!=': <TokenType.NEQ: 'NEQ'>, ':=': <TokenType.COLON_EQ: 'COLON_EQ'>, '<=>': <TokenType.NULLSAFE_EQ: 'NULLSAFE_EQ'>, '->': <TokenType.ARROW: 'ARROW'>, '->>': <TokenType.DARROW: 'DARROW'>, '=>': <TokenType.FARROW: 'FARROW'>, '#>': <TokenType.HASH_ARROW: 'HASH_ARROW'>, '#>>': <TokenType.DHASH_ARROW: 'DHASH_ARROW'>, '<->': <TokenType.LR_ARROW: 'LR_ARROW'>, '&&': <TokenType.DAMP: 'DAMP'>, '??': <TokenType.DQMARK: 'DQMARK'>, '~~~': <TokenType.GLOB: 'GLOB'>, '~~': <TokenType.LIKE: 'LIKE'>, '~~*': <TokenType.ILIKE: 'ILIKE'>, '~*': <TokenType.IRLIKE: 'IRLIKE'>, '-|-': <TokenType.ADJACENT: 'ADJACENT'>, 'ALL': <TokenType.ALL: 'ALL'>, 'AND': <TokenType.AND: 'AND'>, 'ANTI': <TokenType.ANTI: 'ANTI'>, 'ANY': <TokenType.ANY: 'ANY'>, 'ASC': <TokenType.ASC: 'ASC'>, 'AS': <TokenType.ALIAS: 'ALIAS'>, 'ASOF': <TokenType.ASOF: 'ASOF'>, 'AUTOINCREMENT': <TokenType.AUTO_INCREMENT: 'AUTO_INCREMENT'>, 'AUTO_INCREMENT': <TokenType.AUTO_INCREMENT: 'AUTO_INCREMENT'>, 'BEGIN': <TokenType.BEGIN: 'BEGIN'>, 'BETWEEN': <TokenType.BETWEEN: 'BETWEEN'>, 'CACHE': <TokenType.CACHE: 'CACHE'>, 'UNCACHE': <TokenType.UNCACHE: 'UNCACHE'>, 'CASE': <TokenType.CASE: 'CASE'>, 'CHARACTER SET': <TokenType.CHARACTER_SET: 'CHARACTER_SET'>, 'CLUSTER BY': <TokenType.CLUSTER_BY: 'CLUSTER_BY'>, 'COLLATE': <TokenType.COLLATE: 'COLLATE'>, 'COLUMN': <TokenType.COLUMN: 'COLUMN'>, 'COMMIT': <TokenType.COMMIT: 'COMMIT'>, 'CONNECT BY': <TokenType.CONNECT_BY: 'CONNECT_BY'>, 'CONSTRAINT': <TokenType.CONSTRAINT: 'CONSTRAINT'>, 'COPY': <TokenType.COPY: 'COPY'>, 'CREATE': <TokenType.CREATE: 'CREATE'>, 'CROSS': <TokenType.CROSS: 'CROSS'>, 'CUBE': <TokenType.CUBE: 'CUBE'>, 'CURRENT_DATE': <TokenType.CURRENT_DATE: 'CURRENT_DATE'>, 'CURRENT_SCHEMA': <TokenType.CURRENT_SCHEMA: 'CURRENT_SCHEMA'>, 'CURRENT_TIME': <TokenType.CURRENT_TIME: 'CURRENT_TIME'>, 'CURRENT_TIMESTAMP': <TokenType.CURRENT_TIMESTAMP: 'CURRENT_TIMESTAMP'>, 'CURRENT_USER': <TokenType.CURRENT_USER: 'CURRENT_USER'>, 'CURRENT_CATALOG': <TokenType.CURRENT_CATALOG: 'CURRENT_CATALOG'>, 'DATABASE': <TokenType.DATABASE: 'DATABASE'>, 'DEFAULT': <TokenType.DEFAULT: 'DEFAULT'>, 'DELETE': <TokenType.DELETE: 'DELETE'>, 'DESC': <TokenType.DESC: 'DESC'>, 'DESCRIBE': <TokenType.DESCRIBE: 'DESCRIBE'>, 'DISTINCT': <TokenType.DISTINCT: 'DISTINCT'>, 'DISTRIBUTE BY': <TokenType.DISTRIBUTE_BY: 'DISTRIBUTE_BY'>, 'DIV': <TokenType.DIV: 'DIV'>, 'DROP': <TokenType.DROP: 'DROP'>, 'ELSE': <TokenType.ELSE: 'ELSE'>, 'END': <TokenType.END: 'END'>, 'ENUM': <TokenType.ENUM: 'ENUM'>, 'ESCAPE': <TokenType.ESCAPE: 'ESCAPE'>, 'EXCEPT': <TokenType.EXCEPT: 'EXCEPT'>, 'EXECUTE': <TokenType.EXECUTE: 'EXECUTE'>, 'EXISTS': <TokenType.EXISTS: 'EXISTS'>, 'FALSE': <TokenType.FALSE: 'FALSE'>, 'FETCH': <TokenType.FETCH: 'FETCH'>, 'FILTER': <TokenType.FILTER: 'FILTER'>, 'FILE': <TokenType.FILE: 'FILE'>, 'FIRST': <TokenType.FIRST: 'FIRST'>, 'FULL': <TokenType.FULL: 'FULL'>, 'FUNCTION': <TokenType.FUNCTION: 'FUNCTION'>, 'FOR': <TokenType.FOR: 'FOR'>, 'FOREIGN KEY': <TokenType.FOREIGN_KEY: 'FOREIGN_KEY'>, 'FORMAT': <TokenType.FORMAT: 'FORMAT'>, 'FROM': <TokenType.FROM: 'FROM'>, 'GEOGRAPHY': <TokenType.GEOGRAPHY: 'GEOGRAPHY'>, 'GEOMETRY': <TokenType.GEOMETRY: 'GEOMETRY'>, 'GLOB': <TokenType.GLOB: 'GLOB'>, 'GROUP BY': <TokenType.GROUP_BY: 'GROUP_BY'>, 'GROUPING SETS': <TokenType.GROUPING_SETS: 'GROUPING_SETS'>, 'HAVING': <TokenType.HAVING: 'HAVING'>, 'ILIKE': <TokenType.ILIKE: 'ILIKE'>, 'IN': <TokenType.IN: 'IN'>, 'INDEX': <TokenType.INDEX: 'INDEX'>, 'INET': <TokenType.INET: 'INET'>, 'INNER': <TokenType.INNER: 'INNER'>, 'INSERT': <TokenType.INSERT: 'INSERT'>, 'INTERVAL': <TokenType.INTERVAL: 'INTERVAL'>, 'INTERSECT': <TokenType.INTERSECT: 'INTERSECT'>, 'INTO': <TokenType.INTO: 'INTO'>, 'IS': <TokenType.IS: 'IS'>, 'ISNULL': <TokenType.ISNULL: 'ISNULL'>, 'JOIN': <TokenType.JOIN: 'JOIN'>, 'KEEP': <TokenType.KEEP: 'KEEP'>, 'KILL': <TokenType.KILL: 'KILL'>, 'LATERAL': <TokenType.LATERAL: 'LATERAL'>, 'LEFT': <TokenType.LEFT: 'LEFT'>, 'LIKE': <TokenType.LIKE: 'LIKE'>, 'LIMIT': <TokenType.LIMIT: 'LIMIT'>, 'LOAD': <TokenType.LOAD: 'LOAD'>, 'LOCALTIME': <TokenType.LOCALTIME: 'LOCALTIME'>, 'LOCALTIMESTAMP': <TokenType.LOCALTIMESTAMP: 'LOCALTIMESTAMP'>, 'LOCK': <TokenType.LOCK: 'LOCK'>, 'MERGE': <TokenType.MERGE: 'MERGE'>, 'NAMESPACE': <TokenType.NAMESPACE: 'NAMESPACE'>, 'NATURAL': <TokenType.NATURAL: 'NATURAL'>, 'NEXT': <TokenType.NEXT: 'NEXT'>, 'NOT': <TokenType.NOT: 'NOT'>, 'NOTNULL': <TokenType.NOTNULL: 'NOTNULL'>, 'NULL': <TokenType.NULL: 'NULL'>, 'OBJECT': <TokenType.OBJECT: 'OBJECT'>, 'OFFSET': <TokenType.OFFSET: 'OFFSET'>, 'ON': <TokenType.ON: 'ON'>, 'OR': <TokenType.OR: 'OR'>, 'XOR': <TokenType.XOR: 'XOR'>, 'ORDER BY': <TokenType.ORDER_BY: 'ORDER_BY'>, 'ORDINALITY': <TokenType.ORDINALITY: 'ORDINALITY'>, 'OUT': <TokenType.OUT: 'OUT'>, 'OUTER': <TokenType.OUTER: 'OUTER'>, 'OVER': <TokenType.OVER: 'OVER'>, 'OVERLAPS': <TokenType.OVERLAPS: 'OVERLAPS'>, 'OVERWRITE': <TokenType.OVERWRITE: 'OVERWRITE'>, 'PARTITION': <TokenType.PARTITION: 'PARTITION'>, 'PARTITION BY': <TokenType.PARTITION_BY: 'PARTITION_BY'>, 'PARTITIONED BY': <TokenType.PARTITION_BY: 'PARTITION_BY'>, 'PARTITIONED_BY': <TokenType.PARTITION_BY: 'PARTITION_BY'>, 'PERCENT': <TokenType.PERCENT: 'PERCENT'>, 'PIVOT': <TokenType.PIVOT: 'PIVOT'>, 'PRAGMA': <TokenType.PRAGMA: 'PRAGMA'>, 'PRIMARY KEY': <TokenType.PRIMARY_KEY: 'PRIMARY_KEY'>, 'PROCEDURE': <TokenType.PROCEDURE: 'PROCEDURE'>, 'OPERATOR': <TokenType.OPERATOR: 'OPERATOR'>, 'QUALIFY': <TokenType.QUALIFY: 'QUALIFY'>, 'RANGE': <TokenType.RANGE: 'RANGE'>, 'RECURSIVE': <TokenType.RECURSIVE: 'RECURSIVE'>, 'REGEXP': <TokenType.RLIKE: 'RLIKE'>, 'RENAME': <TokenType.RENAME: 'RENAME'>, 'REPLACE': <TokenType.REPLACE: 'REPLACE'>, 'RETURNING': <TokenType.RETURNING: 'RETURNING'>, 'REFERENCES': <TokenType.REFERENCES: 'REFERENCES'>, 'RIGHT': <TokenType.RIGHT: 'RIGHT'>, 'RLIKE': <TokenType.RLIKE: 'RLIKE'>, 'ROLLBACK': <TokenType.ROLLBACK: 'ROLLBACK'>, 'ROLLUP': <TokenType.ROLLUP: 'ROLLUP'>, 'ROW': <TokenType.ROW: 'ROW'>, 'ROWS': <TokenType.ROWS: 'ROWS'>, 'SCHEMA': <TokenType.SCHEMA: 'SCHEMA'>, 'SELECT': <TokenType.SELECT: 'SELECT'>, 'SEMI': <TokenType.SEMI: 'SEMI'>, 'SESSION': <TokenType.SESSION: 'SESSION'>, 'SESSION_USER': <TokenType.SESSION_USER: 'SESSION_USER'>, 'SET': <TokenType.SET: 'SET'>, 'SETTINGS': <TokenType.SETTINGS: 'SETTINGS'>, 'SHOW': <TokenType.SHOW: 'SHOW'>, 'SIMILAR TO': <TokenType.SIMILAR_TO: 'SIMILAR_TO'>, 'SOME': <TokenType.SOME: 'SOME'>, 'SORT BY': <TokenType.SORT_BY: 'SORT_BY'>, 'START WITH': <TokenType.START_WITH: 'START_WITH'>, 'STRAIGHT_JOIN': <TokenType.STRAIGHT_JOIN: 'STRAIGHT_JOIN'>, 'TABLE': <TokenType.TABLE: 'TABLE'>, 'TABLESAMPLE': <TokenType.TABLE_SAMPLE: 'TABLE_SAMPLE'>, 'TEMP': <TokenType.TEMPORARY: 'TEMPORARY'>, 'TEMPORARY': <TokenType.TEMPORARY: 'TEMPORARY'>, 'THEN': <TokenType.THEN: 'THEN'>, 'TRUE': <TokenType.TRUE: 'TRUE'>, 'TRUNCATE': <TokenType.TRUNCATE: 'TRUNCATE'>, 'UNION': <TokenType.UNION: 'UNION'>, 'UNKNOWN': <TokenType.UNKNOWN: 'UNKNOWN'>, 'UNNEST': <TokenType.UNNEST: 'UNNEST'>, 'UNPIVOT': <TokenType.UNPIVOT: 'UNPIVOT'>, 'UPDATE': <TokenType.UPDATE: 'UPDATE'>, 'USE': <TokenType.USE: 'USE'>, 'USING': <TokenType.USING: 'USING'>, 'UUID': <TokenType.UUID: 'UUID'>, 'VALUES': <TokenType.VALUES: 'VALUES'>, 'VIEW': <TokenType.VIEW: 'VIEW'>, 'VOLATILE': <TokenType.VOLATILE: 'VOLATILE'>, 'WHEN': <TokenType.WHEN: 'WHEN'>, 'WHERE': <TokenType.WHERE: 'WHERE'>, 'WINDOW': <TokenType.WINDOW: 'WINDOW'>, 'WITH': <TokenType.WITH: 'WITH'>, 'APPLY': <TokenType.APPLY: 'APPLY'>, 'ARRAY': <TokenType.ARRAY: 'ARRAY'>, 'BIT': <TokenType.BIT: 'BIT'>, 'BOOL': <TokenType.BOOLEAN: 'BOOLEAN'>, 'BOOLEAN': <TokenType.BOOLEAN: 'BOOLEAN'>, 'BYTE': <TokenType.TINYINT: 'TINYINT'>, 'MEDIUMINT': <TokenType.MEDIUMINT: 'MEDIUMINT'>, 'INT1': <TokenType.TINYINT: 'TINYINT'>, 'TINYINT': <TokenType.TINYINT: 'TINYINT'>, 'INT16': <TokenType.SMALLINT: 'SMALLINT'>, 'SHORT': <TokenType.SMALLINT: 'SMALLINT'>, 'SMALLINT': <TokenType.SMALLINT: 'SMALLINT'>, 'HUGEINT': <TokenType.INT128: 'INT128'>, 'UHUGEINT': <TokenType.UINT128: 'UINT128'>, 'INT2': <TokenType.SMALLINT: 'SMALLINT'>, 'INTEGER': <TokenType.INT: 'INT'>, 'INT': <TokenType.INT: 'INT'>, 'INT4': <TokenType.INT: 'INT'>, 'INT32': <TokenType.INT: 'INT'>, 'INT64': <TokenType.BIGINT: 'BIGINT'>, 'INT128': <TokenType.INT128: 'INT128'>, 'INT256': <TokenType.INT256: 'INT256'>, 'LONG': <TokenType.BIGINT: 'BIGINT'>, 'BIGINT': <TokenType.BIGINT: 'BIGINT'>, 'INT8': <TokenType.TINYINT: 'TINYINT'>, 'UINT': <TokenType.UINT: 'UINT'>, 'UINT128': <TokenType.UINT128: 'UINT128'>, 'UINT256': <TokenType.UINT256: 'UINT256'>, 'DEC': <TokenType.DECIMAL: 'DECIMAL'>, 'DECIMAL': <TokenType.DECIMAL: 'DECIMAL'>, 'DECIMAL32': <TokenType.DECIMAL32: 'DECIMAL32'>, 'DECIMAL64': <TokenType.DECIMAL64: 'DECIMAL64'>, 'DECIMAL128': <TokenType.DECIMAL128: 'DECIMAL128'>, 'DECIMAL256': <TokenType.DECIMAL256: 'DECIMAL256'>, 'DECFLOAT': <TokenType.DECFLOAT: 'DECFLOAT'>, 'BIGDECIMAL': <TokenType.BIGDECIMAL: 'BIGDECIMAL'>, 'BIGNUMERIC': <TokenType.BIGDECIMAL: 'BIGDECIMAL'>, 'BIGNUM': <TokenType.BIGNUM: 'BIGNUM'>, 'LIST': <TokenType.LIST: 'LIST'>, 'MAP': <TokenType.MAP: 'MAP'>, 'NULLABLE': <TokenType.NULLABLE: 'NULLABLE'>, 'NUMBER': <TokenType.DECIMAL: 'DECIMAL'>, 'NUMERIC': <TokenType.DECIMAL: 'DECIMAL'>, 'FIXED': <TokenType.DECIMAL: 'DECIMAL'>, 'REAL': <TokenType.FLOAT: 'FLOAT'>, 'FLOAT': <TokenType.FLOAT: 'FLOAT'>, 'FLOAT4': <TokenType.FLOAT: 'FLOAT'>, 'FLOAT8': <TokenType.DOUBLE: 'DOUBLE'>, 'DOUBLE': <TokenType.DOUBLE: 'DOUBLE'>, 'DOUBLE PRECISION': <TokenType.DOUBLE: 'DOUBLE'>, 'JSON': <TokenType.JSON: 'JSON'>, 'JSONB': <TokenType.JSONB: 'JSONB'>, 'CHAR': <TokenType.CHAR: 'CHAR'>, 'CHARACTER': <TokenType.CHAR: 'CHAR'>, 'CHAR VARYING': <TokenType.VARCHAR: 'VARCHAR'>, 'CHARACTER VARYING': <TokenType.VARCHAR: 'VARCHAR'>, 'NCHAR': <TokenType.NCHAR: 'NCHAR'>, 'VARCHAR': <TokenType.VARCHAR: 'VARCHAR'>, 'VARCHAR2': <TokenType.VARCHAR: 'VARCHAR'>, 'NVARCHAR': <TokenType.NVARCHAR: 'NVARCHAR'>, 'NVARCHAR2': <TokenType.NVARCHAR: 'NVARCHAR'>, 'BPCHAR': <TokenType.BPCHAR: 'BPCHAR'>, 'STR': <TokenType.TEXT: 'TEXT'>, 'STRING': <TokenType.TEXT: 'TEXT'>, 'TEXT': <TokenType.TEXT: 'TEXT'>, 'LONGTEXT': <TokenType.LONGTEXT: 'LONGTEXT'>, 'MEDIUMTEXT': <TokenType.MEDIUMTEXT: 'MEDIUMTEXT'>, 'TINYTEXT': <TokenType.TINYTEXT: 'TINYTEXT'>, 'CLOB': <TokenType.TEXT: 'TEXT'>, 'LONGVARCHAR': <TokenType.TEXT: 'TEXT'>, 'BINARY': <TokenType.BINARY: 'BINARY'>, 'BLOB': <TokenType.BLOB: 'BLOB'>, 'LONGBLOB': <TokenType.LONGBLOB: 'LONGBLOB'>, 'MEDIUMBLOB': <TokenType.MEDIUMBLOB: 'MEDIUMBLOB'>, 'TINYBLOB': <TokenType.TINYBLOB: 'TINYBLOB'>, 'BYTEA': <TokenType.VARBINARY: 'VARBINARY'>, 'VARBINARY': <TokenType.VARBINARY: 'VARBINARY'>, 'TIME': <TokenType.TIME: 'TIME'>, 'TIMETZ': <TokenType.TIMETZ: 'TIMETZ'>, 'TIME_NS': <TokenType.TIME_NS: 'TIME_NS'>, 'TIMESTAMP': <TokenType.TIMESTAMPTZ: 'TIMESTAMPTZ'>, 'TIMESTAMPTZ': <TokenType.TIMESTAMPTZ: 'TIMESTAMPTZ'>, 'TIMESTAMPLTZ': <TokenType.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, 'TIMESTAMP_LTZ': <TokenType.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, 'TIMESTAMPNTZ': <TokenType.TIMESTAMPNTZ: 'TIMESTAMPNTZ'>, 'TIMESTAMP_NTZ': <TokenType.TIMESTAMPNTZ: 'TIMESTAMPNTZ'>, 'DATE': <TokenType.DATE: 'DATE'>, 'DATETIME': <TokenType.DATETIME: 'DATETIME'>, 'INT4RANGE': <TokenType.INT4RANGE: 'INT4RANGE'>, 'INT4MULTIRANGE': <TokenType.INT4MULTIRANGE: 'INT4MULTIRANGE'>, 'INT8RANGE': <TokenType.INT8RANGE: 'INT8RANGE'>, 'INT8MULTIRANGE': <TokenType.INT8MULTIRANGE: 'INT8MULTIRANGE'>, 'NUMRANGE': <TokenType.NUMRANGE: 'NUMRANGE'>, 'NUMMULTIRANGE': <TokenType.NUMMULTIRANGE: 'NUMMULTIRANGE'>, 'TSRANGE': <TokenType.TSRANGE: 'TSRANGE'>, 'TSMULTIRANGE': <TokenType.TSMULTIRANGE: 'TSMULTIRANGE'>, 'TSTZRANGE': <TokenType.TSTZRANGE: 'TSTZRANGE'>, 'TSTZMULTIRANGE': <TokenType.TSTZMULTIRANGE: 'TSTZMULTIRANGE'>, 'DATERANGE': <TokenType.DATERANGE: 'DATERANGE'>, 'DATEMULTIRANGE': <TokenType.DATEMULTIRANGE: 'DATEMULTIRANGE'>, 'UNIQUE': <TokenType.UNIQUE: 'UNIQUE'>, 'VECTOR': <TokenType.VECTOR: 'VECTOR'>, 'STRUCT': <TokenType.STRUCT: 'STRUCT'>, 'SEQUENCE': <TokenType.SEQUENCE: 'SEQUENCE'>, 'VARIANT': <TokenType.VARIANT: 'VARIANT'>, 'ALTER': <TokenType.ALTER: 'ALTER'>, 'ANALYZE': <TokenType.ANALYZE: 'ANALYZE'>, 'CALL': <TokenType.COMMAND: 'COMMAND'>, 'COMMENT': <TokenType.COMMENT: 'COMMENT'>, 'EXPLAIN': <TokenType.DESCRIBE: 'DESCRIBE'>, 'GRANT': <TokenType.GRANT: 'GRANT'>, 'REVOKE': <TokenType.REVOKE: 'REVOKE'>, 'OPTIMIZE': <TokenType.COMMAND: 'COMMAND'>, 'PREPARE': <TokenType.COMMAND: 'COMMAND'>, 'VACUUM': <TokenType.COMMAND: 'COMMAND'>, 'USER-DEFINED': <TokenType.USERDEFINED: 'USERDEFINED'>, 'FOR VERSION': <TokenType.VERSION_SNAPSHOT: 'VERSION_SNAPSHOT'>, 'FOR TIMESTAMP': <TokenType.TIMESTAMP_SNAPSHOT: 'TIMESTAMP_SNAPSHOT'>, 'CHARSET': <TokenType.CHARACTER_SET: 'CHARACTER_SET'>, 'DISTINCTROW': <TokenType.DISTINCT: 'DISTINCT'>, 'FORCE': <TokenType.FORCE: 'FORCE'>, 'IGNORE': <TokenType.IGNORE: 'IGNORE'>, 'KEY': <TokenType.KEY: 'KEY'>, 'LOCK TABLES': <TokenType.COMMAND: 'COMMAND'>, 'MEMBER OF': <TokenType.MEMBER_OF: 'MEMBER_OF'>, 'MOD': <TokenType.MOD: 'MOD'>, 'SEPARATOR': <TokenType.SEPARATOR: 'SEPARATOR'>, 'SERIAL': <TokenType.SERIAL: 'SERIAL'>, 'SIGNED': <TokenType.BIGINT: 'BIGINT'>, 'SIGNED INTEGER': <TokenType.BIGINT: 'BIGINT'>, 'SOUNDS LIKE': <TokenType.SOUNDS_LIKE: 'SOUNDS_LIKE'>, 'START': <TokenType.BEGIN: 'BEGIN'>, 'UNLOCK TABLES': <TokenType.COMMAND: 'COMMAND'>, 'UNSIGNED': <TokenType.UBIGINT: 'UBIGINT'>, 'UNSIGNED INTEGER': <TokenType.UBIGINT: 'UBIGINT'>, 'YEAR': <TokenType.YEAR: 'YEAR'>, '_ARMSCII8': <TokenType.INTRODUCER: 'INTRODUCER'>, '_ASCII': <TokenType.INTRODUCER: 'INTRODUCER'>, '_BIG5': <TokenType.INTRODUCER: 'INTRODUCER'>, '_BINARY': <TokenType.INTRODUCER: 'INTRODUCER'>, '_CP1250': <TokenType.INTRODUCER: 'INTRODUCER'>, '_CP1251': <TokenType.INTRODUCER: 'INTRODUCER'>, '_CP1256': <TokenType.INTRODUCER: 'INTRODUCER'>, '_CP1257': <TokenType.INTRODUCER: 'INTRODUCER'>, '_CP850': <TokenType.INTRODUCER: 'INTRODUCER'>, '_CP852': <TokenType.INTRODUCER: 'INTRODUCER'>, '_CP866': <TokenType.INTRODUCER: 'INTRODUCER'>, '_CP932': <TokenType.INTRODUCER: 'INTRODUCER'>, '_DEC8': <TokenType.INTRODUCER: 'INTRODUCER'>, '_EUCJPMS': <TokenType.INTRODUCER: 'INTRODUCER'>, '_EUCKR': <TokenType.INTRODUCER: 'INTRODUCER'>, '_GB18030': <TokenType.INTRODUCER: 'INTRODUCER'>, '_GB2312': <TokenType.INTRODUCER: 'INTRODUCER'>, '_GBK': <TokenType.INTRODUCER: 'INTRODUCER'>, '_GEOSTD8': <TokenType.INTRODUCER: 'INTRODUCER'>, '_GREEK': <TokenType.INTRODUCER: 'INTRODUCER'>, '_HEBREW': <TokenType.INTRODUCER: 'INTRODUCER'>, '_HP8': <TokenType.INTRODUCER: 'INTRODUCER'>, '_KEYBCS2': <TokenType.INTRODUCER: 'INTRODUCER'>, '_KOI8R': <TokenType.INTRODUCER: 'INTRODUCER'>, '_KOI8U': <TokenType.INTRODUCER: 'INTRODUCER'>, '_LATIN1': <TokenType.INTRODUCER: 'INTRODUCER'>, '_LATIN2': <TokenType.INTRODUCER: 'INTRODUCER'>, '_LATIN5': <TokenType.INTRODUCER: 'INTRODUCER'>, '_LATIN7': <TokenType.INTRODUCER: 'INTRODUCER'>, '_MACCE': <TokenType.INTRODUCER: 'INTRODUCER'>, '_MACROMAN': <TokenType.INTRODUCER: 'INTRODUCER'>, '_SJIS': <TokenType.INTRODUCER: 'INTRODUCER'>, '_SWE7': <TokenType.INTRODUCER: 'INTRODUCER'>, '_TIS620': <TokenType.INTRODUCER: 'INTRODUCER'>, '_UCS2': <TokenType.INTRODUCER: 'INTRODUCER'>, '_UJIS': <TokenType.INTRODUCER: 'INTRODUCER'>, '_UTF8': <TokenType.INTRODUCER: 'INTRODUCER'>, '_UTF16': <TokenType.INTRODUCER: 'INTRODUCER'>, '_UTF16LE': <TokenType.INTRODUCER: 'INTRODUCER'>, '_UTF32': <TokenType.INTRODUCER: 'INTRODUCER'>, '_UTF8MB3': <TokenType.INTRODUCER: 'INTRODUCER'>, '_UTF8MB4': <TokenType.INTRODUCER: 'INTRODUCER'>, '@@': <TokenType.SESSION_PARAMETER: 'SESSION_PARAMETER'>}
COMMANDS = {<TokenType.REPLACE: 'REPLACE'>, <TokenType.RENAME: 'RENAME'>, <TokenType.EXECUTE: 'EXECUTE'>, <TokenType.COMMAND: 'COMMAND'>, <TokenType.FETCH: 'FETCH'>}
BYTE_STRING_ESCAPES: 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            "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            "WEEK": lambda args: exp.Week(
373                this=exp.TsOrDsToDate(this=seq_get(args, 0)), mode=seq_get(args, 1)
374            ),
375            "WEEKOFYEAR": lambda args: exp.WeekOfYear(this=exp.TsOrDsToDate(this=seq_get(args, 0))),
376            "YEAR": lambda args: exp.Year(this=exp.TsOrDsToDate(this=seq_get(args, 0))),
377        }
378
379        FUNCTION_PARSERS = {
380            **parser.Parser.FUNCTION_PARSERS,
381            "GROUP_CONCAT": lambda self: self._parse_group_concat(),
382            # https://dev.mysql.com/doc/refman/5.7/en/miscellaneous-functions.html#function_values
383            "VALUES": lambda self: self.expression(
384                exp.Anonymous, this="VALUES", expressions=[self._parse_id_var()]
385            ),
386            "JSON_VALUE": lambda self: self._parse_json_value(),
387            "SUBSTR": lambda self: self._parse_substring(),
388        }
389
390        STATEMENT_PARSERS = {
391            **parser.Parser.STATEMENT_PARSERS,
392            TokenType.SHOW: lambda self: self._parse_show(),
393        }
394
395        SHOW_PARSERS = {
396            "BINARY LOGS": _show_parser("BINARY LOGS"),
397            "MASTER LOGS": _show_parser("BINARY LOGS"),
398            "BINLOG EVENTS": _show_parser("BINLOG EVENTS"),
399            "CHARACTER SET": _show_parser("CHARACTER SET"),
400            "CHARSET": _show_parser("CHARACTER SET"),
401            "COLLATION": _show_parser("COLLATION"),
402            "FULL COLUMNS": _show_parser("COLUMNS", target="FROM", full=True),
403            "COLUMNS": _show_parser("COLUMNS", target="FROM"),
404            "CREATE DATABASE": _show_parser("CREATE DATABASE", target=True),
405            "CREATE EVENT": _show_parser("CREATE EVENT", target=True),
406            "CREATE FUNCTION": _show_parser("CREATE FUNCTION", target=True),
407            "CREATE PROCEDURE": _show_parser("CREATE PROCEDURE", target=True),
408            "CREATE TABLE": _show_parser("CREATE TABLE", target=True),
409            "CREATE TRIGGER": _show_parser("CREATE TRIGGER", target=True),
410            "CREATE VIEW": _show_parser("CREATE VIEW", target=True),
411            "DATABASES": _show_parser("DATABASES"),
412            "SCHEMAS": _show_parser("DATABASES"),
413            "ENGINE": _show_parser("ENGINE", target=True),
414            "STORAGE ENGINES": _show_parser("ENGINES"),
415            "ENGINES": _show_parser("ENGINES"),
416            "ERRORS": _show_parser("ERRORS"),
417            "EVENTS": _show_parser("EVENTS"),
418            "FUNCTION CODE": _show_parser("FUNCTION CODE", target=True),
419            "FUNCTION STATUS": _show_parser("FUNCTION STATUS"),
420            "GRANTS": _show_parser("GRANTS", target="FOR"),
421            "INDEX": _show_parser("INDEX", target="FROM"),
422            "MASTER STATUS": _show_parser("MASTER STATUS"),
423            "OPEN TABLES": _show_parser("OPEN TABLES"),
424            "PLUGINS": _show_parser("PLUGINS"),
425            "PROCEDURE CODE": _show_parser("PROCEDURE CODE", target=True),
426            "PROCEDURE STATUS": _show_parser("PROCEDURE STATUS"),
427            "PRIVILEGES": _show_parser("PRIVILEGES"),
428            "FULL PROCESSLIST": _show_parser("PROCESSLIST", full=True),
429            "PROCESSLIST": _show_parser("PROCESSLIST"),
430            "PROFILE": _show_parser("PROFILE"),
431            "PROFILES": _show_parser("PROFILES"),
432            "RELAYLOG EVENTS": _show_parser("RELAYLOG EVENTS"),
433            "REPLICAS": _show_parser("REPLICAS"),
434            "SLAVE HOSTS": _show_parser("REPLICAS"),
435            "REPLICA STATUS": _show_parser("REPLICA STATUS"),
436            "SLAVE STATUS": _show_parser("REPLICA STATUS"),
437            "GLOBAL STATUS": _show_parser("STATUS", global_=True),
438            "SESSION STATUS": _show_parser("STATUS"),
439            "STATUS": _show_parser("STATUS"),
440            "TABLE STATUS": _show_parser("TABLE STATUS"),
441            "FULL TABLES": _show_parser("TABLES", full=True),
442            "TABLES": _show_parser("TABLES"),
443            "TRIGGERS": _show_parser("TRIGGERS"),
444            "GLOBAL VARIABLES": _show_parser("VARIABLES", global_=True),
445            "SESSION VARIABLES": _show_parser("VARIABLES"),
446            "VARIABLES": _show_parser("VARIABLES"),
447            "WARNINGS": _show_parser("WARNINGS"),
448        }
449
450        PROPERTY_PARSERS = {
451            **parser.Parser.PROPERTY_PARSERS,
452            "LOCK": lambda self: self._parse_property_assignment(exp.LockProperty),
453            "PARTITION BY": lambda self: self._parse_partition_property(),
454        }
455
456        SET_PARSERS = {
457            **parser.Parser.SET_PARSERS,
458            "PERSIST": lambda self: self._parse_set_item_assignment("PERSIST"),
459            "PERSIST_ONLY": lambda self: self._parse_set_item_assignment("PERSIST_ONLY"),
460            "CHARACTER SET": lambda self: self._parse_set_item_charset("CHARACTER SET"),
461            "CHARSET": lambda self: self._parse_set_item_charset("CHARACTER SET"),
462            "NAMES": lambda self: self._parse_set_item_names(),
463        }
464
465        CONSTRAINT_PARSERS = {
466            **parser.Parser.CONSTRAINT_PARSERS,
467            "FULLTEXT": lambda self: self._parse_index_constraint(kind="FULLTEXT"),
468            "INDEX": lambda self: self._parse_index_constraint(),
469            "KEY": lambda self: self._parse_index_constraint(),
470            "SPATIAL": lambda self: self._parse_index_constraint(kind="SPATIAL"),
471            "ZEROFILL": lambda self: self.expression(exp.ZeroFillColumnConstraint),
472        }
473
474        ALTER_PARSERS = {
475            **parser.Parser.ALTER_PARSERS,
476            "MODIFY": lambda self: self._parse_alter_table_alter(),
477        }
478
479        ALTER_ALTER_PARSERS = {
480            **parser.Parser.ALTER_ALTER_PARSERS,
481            "INDEX": lambda self: self._parse_alter_table_alter_index(),
482        }
483
484        SCHEMA_UNNAMED_CONSTRAINTS = {
485            *parser.Parser.SCHEMA_UNNAMED_CONSTRAINTS,
486            "FULLTEXT",
487            "INDEX",
488            "KEY",
489            "SPATIAL",
490        }
491
492        PROFILE_TYPES: parser.OPTIONS_TYPE = {
493            **dict.fromkeys(("ALL", "CPU", "IPC", "MEMORY", "SOURCE", "SWAPS"), tuple()),
494            "BLOCK": ("IO",),
495            "CONTEXT": ("SWITCHES",),
496            "PAGE": ("FAULTS",),
497        }
498
499        TYPE_TOKENS = {
500            *parser.Parser.TYPE_TOKENS,
501            TokenType.SET,
502        }
503
504        ENUM_TYPE_TOKENS = {
505            *parser.Parser.ENUM_TYPE_TOKENS,
506            TokenType.SET,
507        }
508
509        # SELECT [ ALL | DISTINCT | DISTINCTROW ] [ <OPERATION_MODIFIERS> ]
510        OPERATION_MODIFIERS = {
511            "HIGH_PRIORITY",
512            "STRAIGHT_JOIN",
513            "SQL_SMALL_RESULT",
514            "SQL_BIG_RESULT",
515            "SQL_BUFFER_RESULT",
516            "SQL_NO_CACHE",
517            "SQL_CALC_FOUND_ROWS",
518        }
519
520        LOG_DEFAULTS_TO_LN = True
521        STRING_ALIASES = True
522        VALUES_FOLLOWED_BY_PAREN = False
523        SUPPORTS_PARTITION_SELECTION = True
524
525        def _parse_generated_as_identity(
526            self,
527        ) -> (
528            exp.GeneratedAsIdentityColumnConstraint
529            | exp.ComputedColumnConstraint
530            | exp.GeneratedAsRowColumnConstraint
531        ):
532            this = super()._parse_generated_as_identity()
533
534            if self._match_texts(("STORED", "VIRTUAL")):
535                persisted = self._prev.text.upper() == "STORED"
536
537                if isinstance(this, exp.ComputedColumnConstraint):
538                    this.set("persisted", persisted)
539                elif isinstance(this, exp.GeneratedAsIdentityColumnConstraint):
540                    this = self.expression(
541                        exp.ComputedColumnConstraint, this=this.expression, persisted=persisted
542                    )
543
544            return this
545
546        def _parse_primary_key_part(self) -> t.Optional[exp.Expression]:
547            this = self._parse_id_var()
548            if not self._match(TokenType.L_PAREN):
549                return this
550
551            expression = self._parse_number()
552            self._match_r_paren()
553            return self.expression(exp.ColumnPrefix, this=this, expression=expression)
554
555        def _parse_index_constraint(
556            self, kind: t.Optional[str] = None
557        ) -> exp.IndexColumnConstraint:
558            if kind:
559                self._match_texts(("INDEX", "KEY"))
560
561            this = self._parse_id_var(any_token=False)
562            index_type = self._match(TokenType.USING) and self._advance_any() and self._prev.text
563            expressions = self._parse_wrapped_csv(self._parse_ordered)
564
565            options = []
566            while True:
567                if self._match_text_seq("KEY_BLOCK_SIZE"):
568                    self._match(TokenType.EQ)
569                    opt = exp.IndexConstraintOption(key_block_size=self._parse_number())
570                elif self._match(TokenType.USING):
571                    opt = exp.IndexConstraintOption(using=self._advance_any() and self._prev.text)
572                elif self._match_text_seq("WITH", "PARSER"):
573                    opt = exp.IndexConstraintOption(parser=self._parse_var(any_token=True))
574                elif self._match(TokenType.COMMENT):
575                    opt = exp.IndexConstraintOption(comment=self._parse_string())
576                elif self._match_text_seq("VISIBLE"):
577                    opt = exp.IndexConstraintOption(visible=True)
578                elif self._match_text_seq("INVISIBLE"):
579                    opt = exp.IndexConstraintOption(visible=False)
580                elif self._match_text_seq("ENGINE_ATTRIBUTE"):
581                    self._match(TokenType.EQ)
582                    opt = exp.IndexConstraintOption(engine_attr=self._parse_string())
583                elif self._match_text_seq("SECONDARY_ENGINE_ATTRIBUTE"):
584                    self._match(TokenType.EQ)
585                    opt = exp.IndexConstraintOption(secondary_engine_attr=self._parse_string())
586                else:
587                    opt = None
588
589                if not opt:
590                    break
591
592                options.append(opt)
593
594            return self.expression(
595                exp.IndexColumnConstraint,
596                this=this,
597                expressions=expressions,
598                kind=kind,
599                index_type=index_type,
600                options=options,
601            )
602
603        def _parse_show_mysql(
604            self,
605            this: str,
606            target: bool | str = False,
607            full: t.Optional[bool] = None,
608            global_: t.Optional[bool] = None,
609        ) -> exp.Show:
610            json = self._match_text_seq("JSON")
611
612            if target:
613                if isinstance(target, str):
614                    self._match_text_seq(*target.split(" "))
615                target_id = self._parse_id_var()
616            else:
617                target_id = None
618
619            log = self._parse_string() if self._match_text_seq("IN") else None
620
621            if this in ("BINLOG EVENTS", "RELAYLOG EVENTS"):
622                position = self._parse_number() if self._match_text_seq("FROM") else None
623                db = None
624            else:
625                position = None
626                db = None
627
628                if self._match(TokenType.FROM):
629                    db = self._parse_id_var()
630                elif self._match(TokenType.DOT):
631                    db = target_id
632                    target_id = self._parse_id_var()
633
634            channel = self._parse_id_var() if self._match_text_seq("FOR", "CHANNEL") else None
635
636            like = self._parse_string() if self._match_text_seq("LIKE") else None
637            where = self._parse_where()
638
639            if this == "PROFILE":
640                types = self._parse_csv(lambda: self._parse_var_from_options(self.PROFILE_TYPES))
641                query = self._parse_number() if self._match_text_seq("FOR", "QUERY") else None
642                offset = self._parse_number() if self._match_text_seq("OFFSET") else None
643                limit = self._parse_number() if self._match_text_seq("LIMIT") else None
644            else:
645                types, query = None, None
646                offset, limit = self._parse_oldstyle_limit()
647
648            mutex = True if self._match_text_seq("MUTEX") else None
649            mutex = False if self._match_text_seq("STATUS") else mutex
650
651            for_table = self._parse_id_var() if self._match_text_seq("FOR", "TABLE") else None
652            for_group = self._parse_string() if self._match_text_seq("FOR", "GROUP") else None
653            for_user = self._parse_string() if self._match_text_seq("FOR", "USER") else None
654            for_role = self._parse_string() if self._match_text_seq("FOR", "ROLE") else None
655            into_outfile = self._parse_string() if self._match_text_seq("INTO", "OUTFILE") else None
656
657            return self.expression(
658                exp.Show,
659                this=this,
660                target=target_id,
661                full=full,
662                log=log,
663                position=position,
664                db=db,
665                channel=channel,
666                like=like,
667                where=where,
668                types=types,
669                query=query,
670                offset=offset,
671                limit=limit,
672                mutex=mutex,
673                for_table=for_table,
674                for_group=for_group,
675                for_user=for_user,
676                for_role=for_role,
677                into_outfile=into_outfile,
678                json=json,
679                global_=global_,
680            )
681
682        def _parse_oldstyle_limit(
683            self,
684        ) -> t.Tuple[t.Optional[exp.Expression], t.Optional[exp.Expression]]:
685            limit = None
686            offset = None
687            if self._match_text_seq("LIMIT"):
688                parts = self._parse_csv(self._parse_number)
689                if len(parts) == 1:
690                    limit = parts[0]
691                elif len(parts) == 2:
692                    limit = parts[1]
693                    offset = parts[0]
694
695            return offset, limit
696
697        def _parse_set_item_charset(self, kind: str) -> exp.Expression:
698            this = self._parse_string() or self._parse_unquoted_field()
699            return self.expression(exp.SetItem, this=this, kind=kind)
700
701        def _parse_set_item_names(self) -> exp.Expression:
702            charset = self._parse_string() or self._parse_unquoted_field()
703            if self._match_text_seq("COLLATE"):
704                collate = self._parse_string() or self._parse_unquoted_field()
705            else:
706                collate = None
707
708            return self.expression(exp.SetItem, this=charset, collate=collate, kind="NAMES")
709
710        def _parse_type(
711            self, parse_interval: bool = True, fallback_to_identifier: bool = False
712        ) -> t.Optional[exp.Expression]:
713            # mysql binary is special and can work anywhere, even in order by operations
714            # it operates like a no paren func
715            if self._match(TokenType.BINARY, advance=False):
716                data_type = self._parse_types(check_func=True, allow_identifiers=False)
717
718                if isinstance(data_type, exp.DataType):
719                    return self.expression(exp.Cast, this=self._parse_column(), to=data_type)
720
721            return super()._parse_type(
722                parse_interval=parse_interval, fallback_to_identifier=fallback_to_identifier
723            )
724
725        def _parse_alter_table_alter_index(self) -> exp.AlterIndex:
726            index = self._parse_field(any_token=True)
727
728            if self._match_text_seq("VISIBLE"):
729                visible = True
730            elif self._match_text_seq("INVISIBLE"):
731                visible = False
732            else:
733                visible = None
734
735            return self.expression(exp.AlterIndex, this=index, visible=visible)
736
737        def _parse_partition_property(
738            self,
739        ) -> t.Optional[exp.Expression] | t.List[exp.Expression]:
740            partition_cls: t.Optional[t.Type[exp.Expression]] = None
741            value_parser = None
742
743            if self._match_text_seq("RANGE"):
744                partition_cls = exp.PartitionByRangeProperty
745                value_parser = self._parse_partition_range_value
746            elif self._match_text_seq("LIST"):
747                partition_cls = exp.PartitionByListProperty
748                value_parser = self._parse_partition_list_value
749
750            if not partition_cls or not value_parser:
751                return None
752
753            partition_expressions = self._parse_wrapped_csv(self._parse_assignment)
754
755            # For Doris and Starrocks
756            if not self._match_text_seq("(", "PARTITION", advance=False):
757                return partition_expressions
758
759            create_expressions = self._parse_wrapped_csv(value_parser)
760
761            return self.expression(
762                partition_cls,
763                partition_expressions=partition_expressions,
764                create_expressions=create_expressions,
765            )
766
767        def _parse_partition_range_value(self) -> t.Optional[exp.Expression]:
768            self._match_text_seq("PARTITION")
769            name = self._parse_id_var()
770
771            if not self._match_text_seq("VALUES", "LESS", "THAN"):
772                return name
773
774            values = self._parse_wrapped_csv(self._parse_expression)
775
776            if (
777                len(values) == 1
778                and isinstance(values[0], exp.Column)
779                and values[0].name.upper() == "MAXVALUE"
780            ):
781                values = [exp.var("MAXVALUE")]
782
783            part_range = self.expression(exp.PartitionRange, this=name, expressions=values)
784            return self.expression(exp.Partition, expressions=[part_range])
785
786        def _parse_partition_list_value(self) -> exp.Partition:
787            self._match_text_seq("PARTITION")
788            name = self._parse_id_var()
789            self._match_text_seq("VALUES", "IN")
790            values = self._parse_wrapped_csv(self._parse_expression)
791            part_list = self.expression(exp.PartitionList, this=name, expressions=values)
792            return self.expression(exp.Partition, expressions=[part_list])

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.INT8RANGE: 'INT8RANGE'>, <TokenType.UDECIMAL: 'UDECIMAL'>, <TokenType.COLLATE: 'COLLATE'>, <TokenType.BPCHAR: 'BPCHAR'>, <TokenType.UDOUBLE: 'UDOUBLE'>, <TokenType.JSON: 'JSON'>, <TokenType.CURRENT_TIMESTAMP: 'CURRENT_TIMESTAMP'>, <TokenType.DATE32: 'DATE32'>, <TokenType.TSTZMULTIRANGE: 'TSTZMULTIRANGE'>, <TokenType.DECIMAL256: 'DECIMAL256'>, <TokenType.TRUNCATE: 'TRUNCATE'>, <TokenType.INT4RANGE: 'INT4RANGE'>, <TokenType.UINT256: 'UINT256'>, <TokenType.UNKNOWN: 'UNKNOWN'>, <TokenType.MEDIUMINT: 'MEDIUMINT'>, <TokenType.VARBINARY: 'VARBINARY'>, <TokenType.BIGDECIMAL: 'BIGDECIMAL'>, <TokenType.NAME: 'NAME'>, <TokenType.INTERVAL: 'INTERVAL'>, <TokenType.UTINYINT: 'UTINYINT'>, <TokenType.SMALLDATETIME: 'SMALLDATETIME'>, <TokenType.ISNULL: 'ISNULL'>, <TokenType.MOD: 'MOD'>, <TokenType.CURRENT_TIME: 'CURRENT_TIME'>, <TokenType.BOOLEAN: 'BOOLEAN'>, <TokenType.UTC_TIMESTAMP: 'UTC_TIMESTAMP'>, <TokenType.SEQUENCE: 'SEQUENCE'>, <TokenType.FIXEDSTRING: 'FIXEDSTRING'>, <TokenType.VAR: 'VAR'>, <TokenType.LIST: 'LIST'>, <TokenType.USMALLINT: 'USMALLINT'>, <TokenType.GLOB: 'GLOB'>, <TokenType.TIME_NS: 'TIME_NS'>, <TokenType.UINT: 'UINT'>, <TokenType.UUID: 'UUID'>, <TokenType.TIMESTAMP_NS: 'TIMESTAMP_NS'>, <TokenType.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, <TokenType.CURRENT_USER: 'CURRENT_USER'>, <TokenType.NCHAR: 'NCHAR'>, <TokenType.INT256: 'INT256'>, <TokenType.LOCALTIME: 'LOCALTIME'>, <TokenType.DYNAMIC: 'DYNAMIC'>, <TokenType.TEXT: 'TEXT'>, <TokenType.TSTZRANGE: 'TSTZRANGE'>, <TokenType.JSONB: 'JSONB'>, <TokenType.CURRENT_DATETIME: 'CURRENT_DATETIME'>, <TokenType.MEDIUMBLOB: 'MEDIUMBLOB'>, <TokenType.TIMETZ: 'TIMETZ'>, <TokenType.FORMAT: 'FORMAT'>, <TokenType.TSMULTIRANGE: 'TSMULTIRANGE'>, <TokenType.NOTHING: 'NOTHING'>, <TokenType.SMALLSERIAL: 'SMALLSERIAL'>, <TokenType.TIMESTAMPTZ: 'TIMESTAMPTZ'>, <TokenType.CHARACTER_SET: 'CHARACTER_SET'>, <TokenType.BIGNUM: 'BIGNUM'>, <TokenType.VECTOR: 'VECTOR'>, <TokenType.LOCALTIMESTAMP: 'LOCALTIMESTAMP'>, <TokenType.TIMESTAMP_S: 'TIMESTAMP_S'>, <TokenType.INDEX: 'INDEX'>, <TokenType.IPV4: 'IPV4'>, <TokenType.VALUES: 'VALUES'>, <TokenType.TSRANGE: 'TSRANGE'>, <TokenType.OFFSET: 'OFFSET'>, <TokenType.MONEY: 'MONEY'>, <TokenType.ANY: 'ANY'>, <TokenType.PRIMARY_KEY: 'PRIMARY_KEY'>, <TokenType.REPLACE: 'REPLACE'>, <TokenType.ENUM16: 'ENUM16'>, <TokenType.BLOB: 'BLOB'>, <TokenType.OBJECT: 'OBJECT'>, <TokenType.ARRAY: 'ARRAY'>, <TokenType.VARIANT: 'VARIANT'>, <TokenType.CHAR: 'CHAR'>, <TokenType.SOME: 'SOME'>, <TokenType.LEFT: 'LEFT'>, <TokenType.FLOAT: 'FLOAT'>, <TokenType.UNNEST: 'UNNEST'>, <TokenType.LONGTEXT: 'LONGTEXT'>, <TokenType.MULTILINESTRING: 'MULTILINESTRING'>, <TokenType.LOWCARDINALITY: 'LOWCARDINALITY'>, <TokenType.BIGSERIAL: 'BIGSERIAL'>, <TokenType.STRUCT: 'STRUCT'>, <TokenType.FILTER: 'FILTER'>, <TokenType.DATERANGE: 'DATERANGE'>, <TokenType.VARCHAR: 'VARCHAR'>, <TokenType.ROWVERSION: 'ROWVERSION'>, <TokenType.TIMESTAMP: 'TIMESTAMP'>, <TokenType.IDENTIFIER: 'IDENTIFIER'>, <TokenType.TINYTEXT: 'TINYTEXT'>, <TokenType.SIMPLEAGGREGATEFUNCTION: 'SIMPLEAGGREGATEFUNCTION'>, <TokenType.AGGREGATEFUNCTION: 'AGGREGATEFUNCTION'>, <TokenType.DATABASE: 'DATABASE'>, <TokenType.TABLE: 'TABLE'>, <TokenType.UMEDIUMINT: 'UMEDIUMINT'>, <TokenType.GEOGRAPHY: 'GEOGRAPHY'>, <TokenType.INT128: 'INT128'>, <TokenType.NUMMULTIRANGE: 'NUMMULTIRANGE'>, <TokenType.POINT: 'POINT'>, <TokenType.DATE: 'DATE'>, <TokenType.LONGBLOB: 'LONGBLOB'>, <TokenType.ILIKE: 'ILIKE'>, <TokenType.CURRENT_SCHEMA: 'CURRENT_SCHEMA'>, <TokenType.INET: 'INET'>, <TokenType.CURRENT_CATALOG: 'CURRENT_CATALOG'>, <TokenType.INSERT: 'INSERT'>, <TokenType.UINT128: 'UINT128'>, <TokenType.UBIGINT: 'UBIGINT'>, <TokenType.DECIMAL32: 'DECIMAL32'>, <TokenType.MEDIUMTEXT: 'MEDIUMTEXT'>, <TokenType.TIMESTAMPNTZ: 'TIMESTAMPNTZ'>, <TokenType.SCHEMA: 'SCHEMA'>, <TokenType.SESSION_USER: 'SESSION_USER'>, <TokenType.ENUM: 'ENUM'>, <TokenType.LIKE: 'LIKE'>, <TokenType.INT8MULTIRANGE: 'INT8MULTIRANGE'>, <TokenType.NULLABLE: 'NULLABLE'>, <TokenType.DATETIME2: 'DATETIME2'>, <TokenType.RLIKE: 'RLIKE'>, <TokenType.IMAGE: 'IMAGE'>, <TokenType.GET: 'GET'>, <TokenType.IPV6: 'IPV6'>, <TokenType.ROW: 'ROW'>, <TokenType.ENUM8: 'ENUM8'>, <TokenType.POLYGON: 'POLYGON'>, <TokenType.NEXT: 'NEXT'>, <TokenType.TINYINT: 'TINYINT'>, <TokenType.DECIMAL: 'DECIMAL'>, <TokenType.SMALLINT: 'SMALLINT'>, <TokenType.SMALLMONEY: 'SMALLMONEY'>, <TokenType.EXISTS: 'EXISTS'>, <TokenType.PSEUDO_TYPE: 'PSEUDO_TYPE'>, <TokenType.INT: 'INT'>, <TokenType.UTC_DATE: 'UTC_DATE'>, <TokenType.XOR: 'XOR'>, <TokenType.NVARCHAR: 'NVARCHAR'>, <TokenType.DOUBLE: 'DOUBLE'>, <TokenType.VOID: 'VOID'>, <TokenType.BIGINT: 'BIGINT'>, <TokenType.DECIMAL64: 'DECIMAL64'>, <TokenType.DATETIME64: 'DATETIME64'>, <TokenType.SUPER: 'SUPER'>, <TokenType.NUMRANGE: 'NUMRANGE'>, <TokenType.USERDEFINED: 'USERDEFINED'>, <TokenType.IPADDRESS: 'IPADDRESS'>, <TokenType.NULL: 'NULL'>, <TokenType.FILE: 'FILE'>, <TokenType.NESTED: 'NESTED'>, <TokenType.FIRST: 'FIRST'>, <TokenType.DATEMULTIRANGE: 'DATEMULTIRANGE'>, <TokenType.TDIGEST: 'TDIGEST'>, <TokenType.HLLSKETCH: 'HLLSKETCH'>, <TokenType.YEAR: 'YEAR'>, <TokenType.COMMAND: 'COMMAND'>, <TokenType.TIMESTAMP_MS: 'TIMESTAMP_MS'>, <TokenType.UNION: 'UNION'>, <TokenType.UTC_TIME: 'UTC_TIME'>, <TokenType.GEOGRAPHYPOINT: 'GEOGRAPHYPOINT'>, <TokenType.LINESTRING: 'LINESTRING'>, <TokenType.RING: 'RING'>, <TokenType.WINDOW: 'WINDOW'>, <TokenType.HSTORE: 'HSTORE'>, <TokenType.ALL: 'ALL'>, <TokenType.MULTIPOLYGON: 'MULTIPOLYGON'>, <TokenType.SERIAL: 'SERIAL'>, <TokenType.XML: 'XML'>, <TokenType.DECIMAL128: 'DECIMAL128'>, <TokenType.OBJECT_IDENTIFIER: 'OBJECT_IDENTIFIER'>, <TokenType.IPPREFIX: 'IPPREFIX'>, <TokenType.CURRENT_DATE: 'CURRENT_DATE'>, <TokenType.RIGHT: 'RIGHT'>, <TokenType.MAP: 'MAP'>, <TokenType.TINYBLOB: 'TINYBLOB'>, <TokenType.TIME: 'TIME'>, <TokenType.BIT: 'BIT'>, <TokenType.GEOMETRY: 'GEOMETRY'>, <TokenType.MERGE: 'MERGE'>, <TokenType.BINARY: 'BINARY'>, <TokenType.INT4MULTIRANGE: 'INT4MULTIRANGE'>, <TokenType.RANGE: 'RANGE'>, <TokenType.DATETIME: 'DATETIME'>, <TokenType.DECFLOAT: 'DECFLOAT'>}
CONJUNCTION = {<TokenType.AND: 'AND'>: <class 'sqlglot.expressions.And'>, <TokenType.DAMP: 'DAMP'>: <class 'sqlglot.expressions.And'>, <TokenType.XOR: 'XOR'>: <class 'sqlglot.expressions.Xor'>}
DISJUNCTION = {<TokenType.OR: 'OR'>: <class 'sqlglot.expressions.Or'>, <TokenType.DPIPE: 'DPIPE'>: <class 'sqlglot.expressions.Or'>}
TABLE_ALIAS_TOKENS = {<TokenType.INT8RANGE: 'INT8RANGE'>, <TokenType.UDECIMAL: 'UDECIMAL'>, <TokenType.BPCHAR: 'BPCHAR'>, <TokenType.COLLATE: 'COLLATE'>, <TokenType.UDOUBLE: 'UDOUBLE'>, <TokenType.SHOW: 'SHOW'>, <TokenType.JSON: 'JSON'>, <TokenType.DATE32: 'DATE32'>, <TokenType.SETTINGS: 'SETTINGS'>, <TokenType.CURRENT_TIMESTAMP: 'CURRENT_TIMESTAMP'>, <TokenType.DECIMAL256: 'DECIMAL256'>, <TokenType.TRUNCATE: 'TRUNCATE'>, <TokenType.INT4RANGE: 'INT4RANGE'>, <TokenType.DIV: 'DIV'>, <TokenType.UINT256: 'UINT256'>, <TokenType.UNKNOWN: 'UNKNOWN'>, <TokenType.MEDIUMINT: 'MEDIUMINT'>, <TokenType.VARBINARY: 'VARBINARY'>, <TokenType.BIGDECIMAL: 'BIGDECIMAL'>, <TokenType.NAME: 'NAME'>, <TokenType.INTERVAL: 'INTERVAL'>, <TokenType.UTINYINT: 'UTINYINT'>, <TokenType.ESCAPE: 'ESCAPE'>, <TokenType.SMALLDATETIME: 'SMALLDATETIME'>, <TokenType.EXECUTE: 'EXECUTE'>, <TokenType.ISNULL: 'ISNULL'>, <TokenType.DESC: 'DESC'>, <TokenType.UNPIVOT: 'UNPIVOT'>, <TokenType.BOOLEAN: 'BOOLEAN'>, <TokenType.CURRENT_TIME: 'CURRENT_TIME'>, <TokenType.END: 'END'>, <TokenType.AUTO_INCREMENT: 'AUTO_INCREMENT'>, <TokenType.SEQUENCE: 'SEQUENCE'>, <TokenType.VAR: 'VAR'>, <TokenType.RENAME: 'RENAME'>, <TokenType.FIXEDSTRING: 'FIXEDSTRING'>, <TokenType.LIST: 'LIST'>, <TokenType.ATTACH: 'ATTACH'>, <TokenType.COMMENT: 'COMMENT'>, <TokenType.USMALLINT: 'USMALLINT'>, <TokenType.TIME_NS: 'TIME_NS'>, <TokenType.OPERATOR: 'OPERATOR'>, <TokenType.UINT: 'UINT'>, <TokenType.UUID: 'UUID'>, <TokenType.TIMESTAMP_NS: 'TIMESTAMP_NS'>, <TokenType.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, <TokenType.CURRENT_USER: 'CURRENT_USER'>, <TokenType.NCHAR: 'NCHAR'>, <TokenType.INT256: 'INT256'>, <TokenType.TOP: 'TOP'>, <TokenType.LOCALTIME: 'LOCALTIME'>, <TokenType.DYNAMIC: 'DYNAMIC'>, <TokenType.SEMI: 'SEMI'>, <TokenType.TEXT: 'TEXT'>, <TokenType.EXPORT: 'EXPORT'>, <TokenType.TSTZRANGE: 'TSTZRANGE'>, <TokenType.JSONB: 'JSONB'>, <TokenType.STREAMLIT: 'STREAMLIT'>, <TokenType.MEDIUMBLOB: 'MEDIUMBLOB'>, <TokenType.CURRENT_DATETIME: 'CURRENT_DATETIME'>, <TokenType.IS: 'IS'>, <TokenType.VIEW: 'VIEW'>, <TokenType.FORMAT: 'FORMAT'>, <TokenType.TIMETZ: 'TIMETZ'>, <TokenType.TSMULTIRANGE: 'TSMULTIRANGE'>, <TokenType.NOTHING: 'NOTHING'>, <TokenType.SMALLSERIAL: 'SMALLSERIAL'>, <TokenType.FOREIGN_KEY: 'FOREIGN_KEY'>, <TokenType.TIMESTAMPTZ: 'TIMESTAMPTZ'>, <TokenType.REFERENCES: 'REFERENCES'>, <TokenType.DETACH: 'DETACH'>, <TokenType.BIGNUM: 'BIGNUM'>, <TokenType.VECTOR: 'VECTOR'>, <TokenType.LOCALTIMESTAMP: 'LOCALTIMESTAMP'>, <TokenType.TAG: 'TAG'>, <TokenType.TRUE: 'TRUE'>, <TokenType.TIMESTAMP_S: 'TIMESTAMP_S'>, <TokenType.DICTIONARY: 'DICTIONARY'>, <TokenType.KILL: 'KILL'>, <TokenType.INDEX: 'INDEX'>, <TokenType.IPV4: 'IPV4'>, <TokenType.TSRANGE: 'TSRANGE'>, <TokenType.OFFSET: 'OFFSET'>, <TokenType.PIVOT: 'PIVOT'>, <TokenType.ANY: 'ANY'>, <TokenType.MONEY: 'MONEY'>, <TokenType.INOUT: 'INOUT'>, <TokenType.REPLACE: 'REPLACE'>, <TokenType.ENUM16: 'ENUM16'>, <TokenType.SET: 'SET'>, <TokenType.BLOB: 'BLOB'>, <TokenType.WAREHOUSE: 'WAREHOUSE'>, <TokenType.PROCEDURE: 'PROCEDURE'>, <TokenType.OBJECT: 'OBJECT'>, <TokenType.ARRAY: 'ARRAY'>, <TokenType.COPY: 'COPY'>, <TokenType.CUBE: 'CUBE'>, <TokenType.VARIANT: 'VARIANT'>, <TokenType.SINK: 'SINK'>, <TokenType.CHAR: 'CHAR'>, <TokenType.SOME: 'SOME'>, <TokenType.ANALYZE: 'ANALYZE'>, <TokenType.NAMESPACE: 'NAMESPACE'>, <TokenType.FLOAT: 'FLOAT'>, <TokenType.UNNEST: 'UNNEST'>, <TokenType.LONGTEXT: 'LONGTEXT'>, <TokenType.MULTILINESTRING: 'MULTILINESTRING'>, <TokenType.LOWCARDINALITY: 'LOWCARDINALITY'>, <TokenType.BIGSERIAL: 'BIGSERIAL'>, <TokenType.PERCENT: 'PERCENT'>, <TokenType.FILTER: 'FILTER'>, <TokenType.DATERANGE: 'DATERANGE'>, <TokenType.VARCHAR: 'VARCHAR'>, <TokenType.DESCRIBE: 'DESCRIBE'>, <TokenType.APPLY: 'APPLY'>, <TokenType.IDENTIFIER: 'IDENTIFIER'>, <TokenType.STORAGE_INTEGRATION: 'STORAGE_INTEGRATION'>, <TokenType.ROWVERSION: 'ROWVERSION'>, <TokenType.TIMESTAMP: 'TIMESTAMP'>, <TokenType.TINYTEXT: 'TINYTEXT'>, <TokenType.DATABASE: 'DATABASE'>, <TokenType.SIMPLEAGGREGATEFUNCTION: 'SIMPLEAGGREGATEFUNCTION'>, <TokenType.AGGREGATEFUNCTION: 'AGGREGATEFUNCTION'>, <TokenType.TABLE: 'TABLE'>, <TokenType.UMEDIUMINT: 'UMEDIUMINT'>, <TokenType.GEOGRAPHY: 'GEOGRAPHY'>, <TokenType.INT128: 'INT128'>, <TokenType.NUMMULTIRANGE: 'NUMMULTIRANGE'>, <TokenType.STAGE: 'STAGE'>, <TokenType.POINT: 'POINT'>, <TokenType.MATCH: 'MATCH'>, <TokenType.DATE: 'DATE'>, <TokenType.LONGBLOB: 'LONGBLOB'>, <TokenType.CURRENT_SCHEMA: 'CURRENT_SCHEMA'>, <TokenType.INET: 'INET'>, <TokenType.FALSE: 'FALSE'>, <TokenType.CASE: 'CASE'>, <TokenType.LIMIT: 'LIMIT'>, <TokenType.LOAD: 'LOAD'>, <TokenType.UINT128: 'UINT128'>, <TokenType.UBIGINT: 'UBIGINT'>, <TokenType.TEMPORARY: 'TEMPORARY'>, <TokenType.ROWS: 'ROWS'>, <TokenType.DECIMAL32: 'DECIMAL32'>, <TokenType.SCHEMA: 'SCHEMA'>, <TokenType.MEDIUMTEXT: 'MEDIUMTEXT'>, <TokenType.TIMESTAMPNTZ: 'TIMESTAMPNTZ'>, <TokenType.ENUM: 'ENUM'>, <TokenType.INT8MULTIRANGE: 'INT8MULTIRANGE'>, <TokenType.NULLABLE: 'NULLABLE'>, <TokenType.DATETIME2: 'DATETIME2'>, <TokenType.COMMIT: 'COMMIT'>, <TokenType.DELETE: 'DELETE'>, <TokenType.IMAGE: 'IMAGE'>, <TokenType.GET: 'GET'>, <TokenType.IPV6: 'IPV6'>, <TokenType.ROW: 'ROW'>, <TokenType.ENUM8: 'ENUM8'>, <TokenType.POLYGON: 'POLYGON'>, <TokenType.PARTITION: 'PARTITION'>, <TokenType.NEXT: 'NEXT'>, <TokenType.TINYINT: 'TINYINT'>, <TokenType.DECIMAL: 'DECIMAL'>, <TokenType.SMALLINT: 'SMALLINT'>, <TokenType.SMALLMONEY: 'SMALLMONEY'>, <TokenType.KEEP: 'KEEP'>, <TokenType.EXISTS: 'EXISTS'>, <TokenType.RANGE: 'RANGE'>, <TokenType.PSEUDO_TYPE: 'PSEUDO_TYPE'>, <TokenType.INT: 'INT'>, <TokenType.VOLATILE: 'VOLATILE'>, <TokenType.NVARCHAR: 'NVARCHAR'>, <TokenType.OVERWRITE: 'OVERWRITE'>, <TokenType.DOUBLE: 'DOUBLE'>, <TokenType.VOID: 'VOID'>, <TokenType.SOURCE: 'SOURCE'>, <TokenType.ORDINALITY: 'ORDINALITY'>, <TokenType.BIGINT: 'BIGINT'>, <TokenType.DECIMAL64: 'DECIMAL64'>, <TokenType.DATETIME64: 'DATETIME64'>, <TokenType.SUPER: 'SUPER'>, <TokenType.NUMRANGE: 'NUMRANGE'>, <TokenType.USERDEFINED: 'USERDEFINED'>, <TokenType.IPADDRESS: 'IPADDRESS'>, <TokenType.NULL: 'NULL'>, <TokenType.FILE: 'FILE'>, <TokenType.NESTED: 'NESTED'>, <TokenType.CONSTRAINT: 'CONSTRAINT'>, <TokenType.CURRENT_ROLE: 'CURRENT_ROLE'>, <TokenType.FIRST: 'FIRST'>, <TokenType.SESSION: 'SESSION'>, <TokenType.SEMANTIC_VIEW: 'SEMANTIC_VIEW'>, <TokenType.ROLLUP: 'ROLLUP'>, <TokenType.OVER: 'OVER'>, <TokenType.DATEMULTIRANGE: 'DATEMULTIRANGE'>, <TokenType.TDIGEST: 'TDIGEST'>, <TokenType.HLLSKETCH: 'HLLSKETCH'>, <TokenType.COLUMN: 'COLUMN'>, <TokenType.REFRESH: 'REFRESH'>, <TokenType.YEAR: 'YEAR'>, <TokenType.ANTI: 'ANTI'>, <TokenType.COMMAND: 'COMMAND'>, <TokenType.UNIQUE: 'UNIQUE'>, <TokenType.BEGIN: 'BEGIN'>, <TokenType.FUNCTION: 'FUNCTION'>, <TokenType.TIMESTAMP_MS: 'TIMESTAMP_MS'>, <TokenType.OVERLAPS: 'OVERLAPS'>, <TokenType.PRAGMA: 'PRAGMA'>, <TokenType.DECFLOAT: 'DECFLOAT'>, <TokenType.GEOGRAPHYPOINT: 'GEOGRAPHYPOINT'>, <TokenType.MODEL: 'MODEL'>, <TokenType.LINESTRING: 'LINESTRING'>, <TokenType.RING: 'RING'>, <TokenType.ASC: 'ASC'>, <TokenType.HSTORE: 'HSTORE'>, <TokenType.CACHE: 'CACHE'>, <TokenType.FINAL: 'FINAL'>, <TokenType.ALL: 'ALL'>, <TokenType.DEFAULT: 'DEFAULT'>, <TokenType.MULTIPOLYGON: 'MULTIPOLYGON'>, <TokenType.SERIAL: 'SERIAL'>, <TokenType.XML: 'XML'>, <TokenType.DECIMAL128: 'DECIMAL128'>, <TokenType.OBJECT_IDENTIFIER: 'OBJECT_IDENTIFIER'>, <TokenType.UPDATE: 'UPDATE'>, <TokenType.IPPREFIX: 'IPPREFIX'>, <TokenType.CURRENT_DATE: 'CURRENT_DATE'>, <TokenType.MAP: 'MAP'>, <TokenType.TINYBLOB: 'TINYBLOB'>, <TokenType.TIME: 'TIME'>, <TokenType.BIT: 'BIT'>, <TokenType.FILE_FORMAT: 'FILE_FORMAT'>, <TokenType.GEOMETRY: 'GEOMETRY'>, <TokenType.MERGE: 'MERGE'>, <TokenType.BINARY: 'BINARY'>, <TokenType.INT4MULTIRANGE: 'INT4MULTIRANGE'>, <TokenType.RECURSIVE: 'RECURSIVE'>, <TokenType.STRUCT: 'STRUCT'>, <TokenType.DATETIME: 'DATETIME'>, <TokenType.PUT: 'PUT'>, <TokenType.TSTZMULTIRANGE: 'TSTZMULTIRANGE'>}
RANGE_PARSERS = {<TokenType.AT_GT: 'AT_GT'>: <function binary_range_parser.<locals>._parse_binary_range>, <TokenType.BETWEEN: 'BETWEEN'>: <function Parser.<lambda>>, <TokenType.GLOB: 'GLOB'>: <function binary_range_parser.<locals>._parse_binary_range>, <TokenType.ILIKE: 'ILIKE'>: <function binary_range_parser.<locals>._parse_binary_range>, <TokenType.IN: 'IN'>: <function Parser.<lambda>>, <TokenType.IRLIKE: 'IRLIKE'>: <function binary_range_parser.<locals>._parse_binary_range>, <TokenType.IS: 'IS'>: <function Parser.<lambda>>, <TokenType.LIKE: 'LIKE'>: <function binary_range_parser.<locals>._parse_binary_range>, <TokenType.LT_AT: 'LT_AT'>: <function binary_range_parser.<locals>._parse_binary_range>, <TokenType.OVERLAPS: 'OVERLAPS'>: <function binary_range_parser.<locals>._parse_binary_range>, <TokenType.RLIKE: 'RLIKE'>: <function binary_range_parser.<locals>._parse_binary_range>, <TokenType.SIMILAR_TO: 'SIMILAR_TO'>: <function binary_range_parser.<locals>._parse_binary_range>, <TokenType.FOR: 'FOR'>: <function Parser.<lambda>>, <TokenType.QMARK_AMP: 'QMARK_AMP'>: <function binary_range_parser.<locals>._parse_binary_range>, <TokenType.QMARK_PIPE: 'QMARK_PIPE'>: <function binary_range_parser.<locals>._parse_binary_range>, <TokenType.HASH_DASH: 'HASH_DASH'>: <function binary_range_parser.<locals>._parse_binary_range>, <TokenType.ADJACENT: 'ADJACENT'>: <function binary_range_parser.<locals>._parse_binary_range>, <TokenType.OPERATOR: 'OPERATOR'>: <function Parser.<lambda>>, <TokenType.AMP_LT: 'AMP_LT'>: <function binary_range_parser.<locals>._parse_binary_range>, <TokenType.AMP_GT: 'AMP_GT'>: <function binary_range_parser.<locals>._parse_binary_range>, <TokenType.SOUNDS_LIKE: 'SOUNDS_LIKE'>: <function MySQL.Parser.<lambda>>, <TokenType.MEMBER_OF: 'MEMBER_OF'>: <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'>>, '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_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_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_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'>>, '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'>>, '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'>>}
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: 'ALTER'>: <function Parser.<lambda>>, <TokenType.ANALYZE: 'ANALYZE'>: <function Parser.<lambda>>, <TokenType.BEGIN: 'BEGIN'>: <function Parser.<lambda>>, <TokenType.CACHE: 'CACHE'>: <function Parser.<lambda>>, <TokenType.COMMENT: 'COMMENT'>: <function Parser.<lambda>>, <TokenType.COMMIT: 'COMMIT'>: <function Parser.<lambda>>, <TokenType.COPY: 'COPY'>: <function Parser.<lambda>>, <TokenType.CREATE: 'CREATE'>: <function Parser.<lambda>>, <TokenType.DELETE: 'DELETE'>: <function Parser.<lambda>>, <TokenType.DESC: 'DESC'>: <function Parser.<lambda>>, <TokenType.DESCRIBE: 'DESCRIBE'>: <function Parser.<lambda>>, <TokenType.DROP: 'DROP'>: <function Parser.<lambda>>, <TokenType.GRANT: 'GRANT'>: <function Parser.<lambda>>, <TokenType.REVOKE: 'REVOKE'>: <function Parser.<lambda>>, <TokenType.INSERT: 'INSERT'>: <function Parser.<lambda>>, <TokenType.KILL: 'KILL'>: <function Parser.<lambda>>, <TokenType.LOAD: 'LOAD'>: <function Parser.<lambda>>, <TokenType.MERGE: 'MERGE'>: <function Parser.<lambda>>, <TokenType.PIVOT: 'PIVOT'>: <function Parser.<lambda>>, <TokenType.PRAGMA: 'PRAGMA'>: <function Parser.<lambda>>, <TokenType.REFRESH: 'REFRESH'>: <function Parser.<lambda>>, <TokenType.ROLLBACK: 'ROLLBACK'>: <function Parser.<lambda>>, <TokenType.SET: 'SET'>: <function Parser.<lambda>>, <TokenType.TRUNCATE: 'TRUNCATE'>: <function Parser.<lambda>>, <TokenType.UNCACHE: 'UNCACHE'>: <function Parser.<lambda>>, <TokenType.UNPIVOT: 'UNPIVOT'>: <function Parser.<lambda>>, <TokenType.UPDATE: 'UPDATE'>: <function Parser.<lambda>>, <TokenType.USE: 'USE'>: <function Parser.<lambda>>, <TokenType.SEMICOLON: 'SEMICOLON'>: <function Parser.<lambda>>, <TokenType.SHOW: 'SHOW'>: <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 = {'FOREIGN KEY', 'UNIQUE', 'CHECK', 'BUCKET', 'FULLTEXT', 'PRIMARY KEY', 'PERIOD', 'EXCLUDE', 'KEY', 'SPATIAL', 'INDEX', 'TRUNCATE', '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.INT8RANGE: 'INT8RANGE'>, <TokenType.UDECIMAL: 'UDECIMAL'>, <TokenType.BPCHAR: 'BPCHAR'>, <TokenType.UDOUBLE: 'UDOUBLE'>, <TokenType.JSON: 'JSON'>, <TokenType.DATE32: 'DATE32'>, <TokenType.DECIMAL256: 'DECIMAL256'>, <TokenType.INT4RANGE: 'INT4RANGE'>, <TokenType.UINT256: 'UINT256'>, <TokenType.UNKNOWN: 'UNKNOWN'>, <TokenType.MEDIUMINT: 'MEDIUMINT'>, <TokenType.VARBINARY: 'VARBINARY'>, <TokenType.BIGDECIMAL: 'BIGDECIMAL'>, <TokenType.NAME: 'NAME'>, <TokenType.INTERVAL: 'INTERVAL'>, <TokenType.UTINYINT: 'UTINYINT'>, <TokenType.SMALLDATETIME: 'SMALLDATETIME'>, <TokenType.BOOLEAN: 'BOOLEAN'>, <TokenType.FIXEDSTRING: 'FIXEDSTRING'>, <TokenType.LIST: 'LIST'>, <TokenType.USMALLINT: 'USMALLINT'>, <TokenType.TIME_NS: 'TIME_NS'>, <TokenType.UINT: 'UINT'>, <TokenType.UUID: 'UUID'>, <TokenType.TIMESTAMP_NS: 'TIMESTAMP_NS'>, <TokenType.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, <TokenType.NCHAR: 'NCHAR'>, <TokenType.INT256: 'INT256'>, <TokenType.DYNAMIC: 'DYNAMIC'>, <TokenType.TEXT: 'TEXT'>, <TokenType.TSTZRANGE: 'TSTZRANGE'>, <TokenType.JSONB: 'JSONB'>, <TokenType.MEDIUMBLOB: 'MEDIUMBLOB'>, <TokenType.TIMETZ: 'TIMETZ'>, <TokenType.TSMULTIRANGE: 'TSMULTIRANGE'>, <TokenType.NOTHING: 'NOTHING'>, <TokenType.SMALLSERIAL: 'SMALLSERIAL'>, <TokenType.TIMESTAMPTZ: 'TIMESTAMPTZ'>, <TokenType.BIGNUM: 'BIGNUM'>, <TokenType.VECTOR: 'VECTOR'>, <TokenType.TIMESTAMP_S: 'TIMESTAMP_S'>, <TokenType.IPV4: 'IPV4'>, <TokenType.TSRANGE: 'TSRANGE'>, <TokenType.MONEY: 'MONEY'>, <TokenType.ENUM16: 'ENUM16'>, <TokenType.SET: 'SET'>, <TokenType.BLOB: 'BLOB'>, <TokenType.OBJECT: 'OBJECT'>, <TokenType.ARRAY: 'ARRAY'>, <TokenType.VARIANT: 'VARIANT'>, <TokenType.CHAR: 'CHAR'>, <TokenType.FLOAT: 'FLOAT'>, <TokenType.LONGTEXT: 'LONGTEXT'>, <TokenType.MULTILINESTRING: 'MULTILINESTRING'>, <TokenType.LOWCARDINALITY: 'LOWCARDINALITY'>, <TokenType.BIGSERIAL: 'BIGSERIAL'>, <TokenType.DATERANGE: 'DATERANGE'>, <TokenType.VARCHAR: 'VARCHAR'>, <TokenType.ROWVERSION: 'ROWVERSION'>, <TokenType.TIMESTAMP: 'TIMESTAMP'>, <TokenType.TINYTEXT: 'TINYTEXT'>, <TokenType.SIMPLEAGGREGATEFUNCTION: 'SIMPLEAGGREGATEFUNCTION'>, <TokenType.AGGREGATEFUNCTION: 'AGGREGATEFUNCTION'>, <TokenType.UMEDIUMINT: 'UMEDIUMINT'>, <TokenType.GEOGRAPHY: 'GEOGRAPHY'>, <TokenType.INT128: 'INT128'>, <TokenType.NUMMULTIRANGE: 'NUMMULTIRANGE'>, <TokenType.POINT: 'POINT'>, <TokenType.DATE: 'DATE'>, <TokenType.LONGBLOB: 'LONGBLOB'>, <TokenType.INET: 'INET'>, <TokenType.UINT128: 'UINT128'>, <TokenType.UBIGINT: 'UBIGINT'>, <TokenType.DECIMAL32: 'DECIMAL32'>, <TokenType.MEDIUMTEXT: 'MEDIUMTEXT'>, <TokenType.TIMESTAMPNTZ: 'TIMESTAMPNTZ'>, <TokenType.ENUM: 'ENUM'>, <TokenType.INT8MULTIRANGE: 'INT8MULTIRANGE'>, <TokenType.NULLABLE: 'NULLABLE'>, <TokenType.DATETIME2: 'DATETIME2'>, <TokenType.IMAGE: 'IMAGE'>, <TokenType.IPV6: 'IPV6'>, <TokenType.ENUM8: 'ENUM8'>, <TokenType.POLYGON: 'POLYGON'>, <TokenType.TINYINT: 'TINYINT'>, <TokenType.DECIMAL: 'DECIMAL'>, <TokenType.SMALLINT: 'SMALLINT'>, <TokenType.SMALLMONEY: 'SMALLMONEY'>, <TokenType.RANGE: 'RANGE'>, <TokenType.PSEUDO_TYPE: 'PSEUDO_TYPE'>, <TokenType.INT: 'INT'>, <TokenType.NVARCHAR: 'NVARCHAR'>, <TokenType.DOUBLE: 'DOUBLE'>, <TokenType.VOID: 'VOID'>, <TokenType.BIGINT: 'BIGINT'>, <TokenType.DECIMAL64: 'DECIMAL64'>, <TokenType.DATETIME64: 'DATETIME64'>, <TokenType.SUPER: 'SUPER'>, <TokenType.NUMRANGE: 'NUMRANGE'>, <TokenType.USERDEFINED: 'USERDEFINED'>, <TokenType.IPADDRESS: 'IPADDRESS'>, <TokenType.NULL: 'NULL'>, <TokenType.FILE: 'FILE'>, <TokenType.NESTED: 'NESTED'>, <TokenType.DATEMULTIRANGE: 'DATEMULTIRANGE'>, <TokenType.TDIGEST: 'TDIGEST'>, <TokenType.HLLSKETCH: 'HLLSKETCH'>, <TokenType.YEAR: 'YEAR'>, <TokenType.TIMESTAMP_MS: 'TIMESTAMP_MS'>, <TokenType.DECFLOAT: 'DECFLOAT'>, <TokenType.UNION: 'UNION'>, <TokenType.GEOGRAPHYPOINT: 'GEOGRAPHYPOINT'>, <TokenType.LINESTRING: 'LINESTRING'>, <TokenType.RING: 'RING'>, <TokenType.HSTORE: 'HSTORE'>, <TokenType.MULTIPOLYGON: 'MULTIPOLYGON'>, <TokenType.SERIAL: 'SERIAL'>, <TokenType.XML: 'XML'>, <TokenType.DECIMAL128: 'DECIMAL128'>, <TokenType.OBJECT_IDENTIFIER: 'OBJECT_IDENTIFIER'>, <TokenType.IPPREFIX: 'IPPREFIX'>, <TokenType.MAP: 'MAP'>, <TokenType.TINYBLOB: 'TINYBLOB'>, <TokenType.TIME: 'TIME'>, <TokenType.BIT: 'BIT'>, <TokenType.GEOMETRY: 'GEOMETRY'>, <TokenType.BINARY: 'BINARY'>, <TokenType.INT4MULTIRANGE: 'INT4MULTIRANGE'>, <TokenType.STRUCT: 'STRUCT'>, <TokenType.DATETIME: 'DATETIME'>, <TokenType.TSTZMULTIRANGE: 'TSTZMULTIRANGE'>}
ENUM_TYPE_TOKENS = {<TokenType.ENUM16: 'ENUM16'>, <TokenType.ENUM8: 'ENUM8'>, <TokenType.DYNAMIC: 'DYNAMIC'>, <TokenType.SET: 'SET'>, <TokenType.ENUM: 'ENUM'>}
OPERATION_MODIFIERS = {'SQL_BUFFER_RESULT', 'SQL_BIG_RESULT', 'SQL_SMALL_RESULT', 'STRAIGHT_JOIN', 'SQL_CALC_FOUND_ROWS', '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.INT8RANGE: 'INT8RANGE'>, <TokenType.UDECIMAL: 'UDECIMAL'>, <TokenType.LOCK: 'LOCK'>, <TokenType.BPCHAR: 'BPCHAR'>, <TokenType.COLLATE: 'COLLATE'>, <TokenType.UDOUBLE: 'UDOUBLE'>, <TokenType.SHOW: 'SHOW'>, <TokenType.JSON: 'JSON'>, <TokenType.DATE32: 'DATE32'>, <TokenType.SETTINGS: 'SETTINGS'>, <TokenType.CURRENT_TIMESTAMP: 'CURRENT_TIMESTAMP'>, <TokenType.DECIMAL256: 'DECIMAL256'>, <TokenType.TRUNCATE: 'TRUNCATE'>, <TokenType.INT4RANGE: 'INT4RANGE'>, <TokenType.DIV: 'DIV'>, <TokenType.UINT256: 'UINT256'>, <TokenType.UNKNOWN: 'UNKNOWN'>, <TokenType.MEDIUMINT: 'MEDIUMINT'>, <TokenType.VARBINARY: 'VARBINARY'>, <TokenType.BIGDECIMAL: 'BIGDECIMAL'>, <TokenType.NAME: 'NAME'>, <TokenType.INTERVAL: 'INTERVAL'>, <TokenType.UTINYINT: 'UTINYINT'>, <TokenType.ESCAPE: 'ESCAPE'>, <TokenType.SMALLDATETIME: 'SMALLDATETIME'>, <TokenType.EXECUTE: 'EXECUTE'>, <TokenType.ISNULL: 'ISNULL'>, <TokenType.DESC: 'DESC'>, <TokenType.UNPIVOT: 'UNPIVOT'>, <TokenType.BOOLEAN: 'BOOLEAN'>, <TokenType.CURRENT_TIME: 'CURRENT_TIME'>, <TokenType.END: 'END'>, <TokenType.AUTO_INCREMENT: 'AUTO_INCREMENT'>, <TokenType.SEQUENCE: 'SEQUENCE'>, <TokenType.VAR: 'VAR'>, <TokenType.RENAME: 'RENAME'>, <TokenType.FIXEDSTRING: 'FIXEDSTRING'>, <TokenType.LIST: 'LIST'>, <TokenType.ATTACH: 'ATTACH'>, <TokenType.COMMENT: 'COMMENT'>, <TokenType.USMALLINT: 'USMALLINT'>, <TokenType.TIME_NS: 'TIME_NS'>, <TokenType.OPERATOR: 'OPERATOR'>, <TokenType.UINT: 'UINT'>, <TokenType.UUID: 'UUID'>, <TokenType.TIMESTAMP_NS: 'TIMESTAMP_NS'>, <TokenType.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, <TokenType.CURRENT_USER: 'CURRENT_USER'>, <TokenType.NCHAR: 'NCHAR'>, <TokenType.INT256: 'INT256'>, <TokenType.TOP: 'TOP'>, <TokenType.LOCALTIME: 'LOCALTIME'>, <TokenType.DYNAMIC: 'DYNAMIC'>, <TokenType.SEMI: 'SEMI'>, <TokenType.TEXT: 'TEXT'>, <TokenType.EXPORT: 'EXPORT'>, <TokenType.TSTZRANGE: 'TSTZRANGE'>, <TokenType.JSONB: 'JSONB'>, <TokenType.STREAMLIT: 'STREAMLIT'>, <TokenType.MEDIUMBLOB: 'MEDIUMBLOB'>, <TokenType.CURRENT_DATETIME: 'CURRENT_DATETIME'>, <TokenType.IS: 'IS'>, <TokenType.VIEW: 'VIEW'>, <TokenType.FORMAT: 'FORMAT'>, <TokenType.TIMETZ: 'TIMETZ'>, <TokenType.TSMULTIRANGE: 'TSMULTIRANGE'>, <TokenType.NOTHING: 'NOTHING'>, <TokenType.SMALLSERIAL: 'SMALLSERIAL'>, <TokenType.FOREIGN_KEY: 'FOREIGN_KEY'>, <TokenType.TIMESTAMPTZ: 'TIMESTAMPTZ'>, <TokenType.REFERENCES: 'REFERENCES'>, <TokenType.DETACH: 'DETACH'>, <TokenType.BIGNUM: 'BIGNUM'>, <TokenType.VECTOR: 'VECTOR'>, <TokenType.LOCALTIMESTAMP: 'LOCALTIMESTAMP'>, <TokenType.TAG: 'TAG'>, <TokenType.TRUE: 'TRUE'>, <TokenType.TIMESTAMP_S: 'TIMESTAMP_S'>, <TokenType.DICTIONARY: 'DICTIONARY'>, <TokenType.KILL: 'KILL'>, <TokenType.INDEX: 'INDEX'>, <TokenType.IPV4: 'IPV4'>, <TokenType.TSRANGE: 'TSRANGE'>, <TokenType.OFFSET: 'OFFSET'>, <TokenType.PIVOT: 'PIVOT'>, <TokenType.ANY: 'ANY'>, <TokenType.MONEY: 'MONEY'>, <TokenType.INOUT: 'INOUT'>, <TokenType.REPLACE: 'REPLACE'>, <TokenType.ENUM16: 'ENUM16'>, <TokenType.SET: 'SET'>, <TokenType.BLOB: 'BLOB'>, <TokenType.FULL: 'FULL'>, <TokenType.WAREHOUSE: 'WAREHOUSE'>, <TokenType.PROCEDURE: 'PROCEDURE'>, <TokenType.OBJECT: 'OBJECT'>, <TokenType.ARRAY: 'ARRAY'>, <TokenType.COPY: 'COPY'>, <TokenType.CUBE: 'CUBE'>, <TokenType.VARIANT: 'VARIANT'>, <TokenType.SINK: 'SINK'>, <TokenType.CHAR: 'CHAR'>, <TokenType.SOME: 'SOME'>, <TokenType.ANALYZE: 'ANALYZE'>, <TokenType.NAMESPACE: 'NAMESPACE'>, <TokenType.LEFT: 'LEFT'>, <TokenType.FLOAT: 'FLOAT'>, <TokenType.UNNEST: 'UNNEST'>, <TokenType.LONGTEXT: 'LONGTEXT'>, <TokenType.MULTILINESTRING: 'MULTILINESTRING'>, <TokenType.LOWCARDINALITY: 'LOWCARDINALITY'>, <TokenType.BIGSERIAL: 'BIGSERIAL'>, <TokenType.PERCENT: 'PERCENT'>, <TokenType.FILTER: 'FILTER'>, <TokenType.DATERANGE: 'DATERANGE'>, <TokenType.VARCHAR: 'VARCHAR'>, <TokenType.DESCRIBE: 'DESCRIBE'>, <TokenType.APPLY: 'APPLY'>, <TokenType.IDENTIFIER: 'IDENTIFIER'>, <TokenType.STORAGE_INTEGRATION: 'STORAGE_INTEGRATION'>, <TokenType.ROWVERSION: 'ROWVERSION'>, <TokenType.TIMESTAMP: 'TIMESTAMP'>, <TokenType.TINYTEXT: 'TINYTEXT'>, <TokenType.DATABASE: 'DATABASE'>, <TokenType.SIMPLEAGGREGATEFUNCTION: 'SIMPLEAGGREGATEFUNCTION'>, <TokenType.AGGREGATEFUNCTION: 'AGGREGATEFUNCTION'>, <TokenType.TABLE: 'TABLE'>, <TokenType.UMEDIUMINT: 'UMEDIUMINT'>, <TokenType.GEOGRAPHY: 'GEOGRAPHY'>, <TokenType.INT128: 'INT128'>, <TokenType.NUMMULTIRANGE: 'NUMMULTIRANGE'>, <TokenType.STAGE: 'STAGE'>, <TokenType.POINT: 'POINT'>, <TokenType.MATCH: 'MATCH'>, <TokenType.DATE: 'DATE'>, <TokenType.LONGBLOB: 'LONGBLOB'>, <TokenType.CURRENT_SCHEMA: 'CURRENT_SCHEMA'>, <TokenType.INET: 'INET'>, <TokenType.FALSE: 'FALSE'>, <TokenType.CASE: 'CASE'>, <TokenType.LIMIT: 'LIMIT'>, <TokenType.CURRENT_CATALOG: 'CURRENT_CATALOG'>, <TokenType.LOAD: 'LOAD'>, <TokenType.UINT128: 'UINT128'>, <TokenType.UBIGINT: 'UBIGINT'>, <TokenType.TEMPORARY: 'TEMPORARY'>, <TokenType.ROWS: 'ROWS'>, <TokenType.DECIMAL32: 'DECIMAL32'>, <TokenType.SCHEMA: 'SCHEMA'>, <TokenType.MEDIUMTEXT: 'MEDIUMTEXT'>, <TokenType.TIMESTAMPNTZ: 'TIMESTAMPNTZ'>, <TokenType.ENUM: 'ENUM'>, <TokenType.INT8MULTIRANGE: 'INT8MULTIRANGE'>, <TokenType.NULLABLE: 'NULLABLE'>, <TokenType.SESSION_USER: 'SESSION_USER'>, <TokenType.DATETIME2: 'DATETIME2'>, <TokenType.COMMIT: 'COMMIT'>, <TokenType.DELETE: 'DELETE'>, <TokenType.IMAGE: 'IMAGE'>, <TokenType.GET: 'GET'>, <TokenType.IPV6: 'IPV6'>, <TokenType.ROW: 'ROW'>, <TokenType.ENUM8: 'ENUM8'>, <TokenType.POLYGON: 'POLYGON'>, <TokenType.PARTITION: 'PARTITION'>, <TokenType.NEXT: 'NEXT'>, <TokenType.TINYINT: 'TINYINT'>, <TokenType.DECIMAL: 'DECIMAL'>, <TokenType.SMALLINT: 'SMALLINT'>, <TokenType.SMALLMONEY: 'SMALLMONEY'>, <TokenType.KEEP: 'KEEP'>, <TokenType.EXISTS: 'EXISTS'>, <TokenType.RANGE: 'RANGE'>, <TokenType.PSEUDO_TYPE: 'PSEUDO_TYPE'>, <TokenType.INT: 'INT'>, <TokenType.VOLATILE: 'VOLATILE'>, <TokenType.NVARCHAR: 'NVARCHAR'>, <TokenType.OVERWRITE: 'OVERWRITE'>, <TokenType.DOUBLE: 'DOUBLE'>, <TokenType.VOID: 'VOID'>, <TokenType.SOURCE: 'SOURCE'>, <TokenType.ORDINALITY: 'ORDINALITY'>, <TokenType.BIGINT: 'BIGINT'>, <TokenType.DECIMAL64: 'DECIMAL64'>, <TokenType.DATETIME64: 'DATETIME64'>, <TokenType.SUPER: 'SUPER'>, <TokenType.NUMRANGE: 'NUMRANGE'>, <TokenType.USERDEFINED: 'USERDEFINED'>, <TokenType.IPADDRESS: 'IPADDRESS'>, <TokenType.NULL: 'NULL'>, <TokenType.FILE: 'FILE'>, <TokenType.NESTED: 'NESTED'>, <TokenType.CONSTRAINT: 'CONSTRAINT'>, <TokenType.CURRENT_ROLE: 'CURRENT_ROLE'>, <TokenType.ASOF: 'ASOF'>, <TokenType.FIRST: 'FIRST'>, <TokenType.SESSION: 'SESSION'>, <TokenType.SEMANTIC_VIEW: 'SEMANTIC_VIEW'>, <TokenType.ROLLUP: 'ROLLUP'>, <TokenType.OVER: 'OVER'>, <TokenType.DATEMULTIRANGE: 'DATEMULTIRANGE'>, <TokenType.USE: 'USE'>, <TokenType.TDIGEST: 'TDIGEST'>, <TokenType.COLUMN: 'COLUMN'>, <TokenType.REFRESH: 'REFRESH'>, <TokenType.HLLSKETCH: 'HLLSKETCH'>, <TokenType.YEAR: 'YEAR'>, <TokenType.COMMAND: 'COMMAND'>, <TokenType.UNIQUE: 'UNIQUE'>, <TokenType.BEGIN: 'BEGIN'>, <TokenType.FUNCTION: 'FUNCTION'>, <TokenType.TIMESTAMP_MS: 'TIMESTAMP_MS'>, <TokenType.OVERLAPS: 'OVERLAPS'>, <TokenType.PRAGMA: 'PRAGMA'>, <TokenType.DECFLOAT: 'DECFLOAT'>, <TokenType.PUT: 'PUT'>, <TokenType.GEOGRAPHYPOINT: 'GEOGRAPHYPOINT'>, <TokenType.MODEL: 'MODEL'>, <TokenType.LINESTRING: 'LINESTRING'>, <TokenType.RING: 'RING'>, <TokenType.ASC: 'ASC'>, <TokenType.WINDOW: 'WINDOW'>, <TokenType.HSTORE: 'HSTORE'>, <TokenType.CACHE: 'CACHE'>, <TokenType.FINAL: 'FINAL'>, <TokenType.ALL: 'ALL'>, <TokenType.DEFAULT: 'DEFAULT'>, <TokenType.MULTIPOLYGON: 'MULTIPOLYGON'>, <TokenType.SERIAL: 'SERIAL'>, <TokenType.XML: 'XML'>, <TokenType.DECIMAL128: 'DECIMAL128'>, <TokenType.OBJECT_IDENTIFIER: 'OBJECT_IDENTIFIER'>, <TokenType.UPDATE: 'UPDATE'>, <TokenType.IPPREFIX: 'IPPREFIX'>, <TokenType.CURRENT_DATE: 'CURRENT_DATE'>, <TokenType.RIGHT: 'RIGHT'>, <TokenType.MAP: 'MAP'>, <TokenType.TINYBLOB: 'TINYBLOB'>, <TokenType.TIME: 'TIME'>, <TokenType.BIT: 'BIT'>, <TokenType.FILE_FORMAT: 'FILE_FORMAT'>, <TokenType.GEOMETRY: 'GEOMETRY'>, <TokenType.MERGE: 'MERGE'>, <TokenType.NATURAL: 'NATURAL'>, <TokenType.BINARY: 'BINARY'>, <TokenType.INT4MULTIRANGE: 'INT4MULTIRANGE'>, <TokenType.RECURSIVE: 'RECURSIVE'>, <TokenType.STRUCT: 'STRUCT'>, <TokenType.DATETIME: 'DATETIME'>, <TokenType.ANTI: 'ANTI'>, <TokenType.TSTZMULTIRANGE: 'TSTZMULTIRANGE'>}
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
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
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
error_level
error_message_context
max_errors
dialect
reset
parse
parse_into
check_errors
raise_error
expression
validate_expression
parse_set_operation
build_cast
errors
sql
class MySQL.Generator(sqlglot.generator.Generator):
 794    class Generator(generator.Generator):
 795        INTERVAL_ALLOWS_PLURAL_FORM = False
 796        LOCKING_READS_SUPPORTED = True
 797        NULL_ORDERING_SUPPORTED: t.Optional[bool] = None
 798        JOIN_HINTS = False
 799        TABLE_HINTS = True
 800        DUPLICATE_KEY_UPDATE_WITH_SET = False
 801        QUERY_HINT_SEP = " "
 802        VALUES_AS_TABLE = False
 803        NVL2_SUPPORTED = False
 804        LAST_DAY_SUPPORTS_DATE_PART = False
 805        JSON_TYPE_REQUIRED_FOR_EXTRACTION = True
 806        JSON_PATH_BRACKETED_KEY_SUPPORTED = False
 807        JSON_KEY_VALUE_PAIR_SEP = ","
 808        SUPPORTS_TO_NUMBER = False
 809        PARSE_JSON_NAME: t.Optional[str] = None
 810        PAD_FILL_PATTERN_IS_REQUIRED = True
 811        WRAP_DERIVED_VALUES = False
 812        VARCHAR_REQUIRES_SIZE = True
 813        SUPPORTS_MEDIAN = False
 814        UPDATE_STATEMENT_SUPPORTS_FROM = False
 815
 816        TRANSFORMS = {
 817            **generator.Generator.TRANSFORMS,
 818            exp.ArrayAgg: rename_func("GROUP_CONCAT"),
 819            exp.BitwiseAndAgg: rename_func("BIT_AND"),
 820            exp.BitwiseOrAgg: rename_func("BIT_OR"),
 821            exp.BitwiseXorAgg: rename_func("BIT_XOR"),
 822            exp.BitwiseCount: rename_func("BIT_COUNT"),
 823            exp.Chr: lambda self, e: self.chr_sql(e, "CHAR"),
 824            exp.CurrentDate: no_paren_current_date_sql,
 825            exp.DateDiff: _remove_ts_or_ds_to_date(
 826                lambda self, e: self.func("DATEDIFF", e.this, e.expression), ("this", "expression")
 827            ),
 828            exp.DateAdd: _remove_ts_or_ds_to_date(date_add_sql("ADD")),
 829            exp.DateStrToDate: datestrtodate_sql,
 830            exp.DateSub: _remove_ts_or_ds_to_date(date_add_sql("SUB")),
 831            exp.DateTrunc: _date_trunc_sql,
 832            exp.Day: _remove_ts_or_ds_to_date(),
 833            exp.DayOfMonth: _remove_ts_or_ds_to_date(rename_func("DAYOFMONTH")),
 834            exp.DayOfWeek: _remove_ts_or_ds_to_date(rename_func("DAYOFWEEK")),
 835            exp.DayOfYear: _remove_ts_or_ds_to_date(rename_func("DAYOFYEAR")),
 836            exp.GroupConcat: lambda self,
 837            e: f"""GROUP_CONCAT({self.sql(e, "this")} SEPARATOR {self.sql(e, "separator") or "','"})""",
 838            exp.ILike: no_ilike_sql,
 839            exp.JSONExtractScalar: arrow_json_extract_sql,
 840            exp.Length: length_or_char_length_sql,
 841            exp.LogicalOr: rename_func("MAX"),
 842            exp.LogicalAnd: rename_func("MIN"),
 843            exp.Max: max_or_greatest,
 844            exp.Min: min_or_least,
 845            exp.Month: _remove_ts_or_ds_to_date(),
 846            exp.NullSafeEQ: lambda self, e: self.binary(e, "<=>"),
 847            exp.NullSafeNEQ: lambda self, e: f"NOT {self.binary(e, '<=>')}",
 848            exp.NumberToStr: rename_func("FORMAT"),
 849            exp.Pivot: no_pivot_sql,
 850            exp.Select: transforms.preprocess(
 851                [
 852                    transforms.eliminate_distinct_on,
 853                    transforms.eliminate_semi_and_anti_joins,
 854                    transforms.eliminate_qualify,
 855                    transforms.eliminate_full_outer_join,
 856                    transforms.unnest_generate_date_array_using_recursive_cte,
 857                ]
 858            ),
 859            exp.StrPosition: lambda self, e: strposition_sql(
 860                self, e, func_name="LOCATE", supports_position=True
 861            ),
 862            exp.StrToDate: _str_to_date_sql,
 863            exp.StrToTime: _str_to_date_sql,
 864            exp.Stuff: rename_func("INSERT"),
 865            exp.SessionUser: lambda *_: "SESSION_USER()",
 866            exp.TableSample: no_tablesample_sql,
 867            exp.TimeFromParts: rename_func("MAKETIME"),
 868            exp.TimestampAdd: date_add_interval_sql("DATE", "ADD"),
 869            exp.TimestampDiff: lambda self, e: self.func(
 870                "TIMESTAMPDIFF", unit_to_var(e), e.expression, e.this
 871            ),
 872            exp.TimestampSub: date_add_interval_sql("DATE", "SUB"),
 873            exp.TimeStrToUnix: rename_func("UNIX_TIMESTAMP"),
 874            exp.TimeStrToTime: lambda self, e: timestrtotime_sql(
 875                self,
 876                e,
 877                include_precision=not e.args.get("zone"),
 878            ),
 879            exp.TimeToStr: _remove_ts_or_ds_to_date(
 880                lambda self, e: self.func("DATE_FORMAT", e.this, self.format_time(e))
 881            ),
 882            exp.Trim: trim_sql,
 883            exp.TryCast: no_trycast_sql,
 884            exp.TsOrDsAdd: date_add_sql("ADD"),
 885            exp.TsOrDsDiff: lambda self, e: self.func("DATEDIFF", e.this, e.expression),
 886            exp.TsOrDsToDate: _ts_or_ds_to_date_sql,
 887            exp.Unicode: lambda self, e: f"ORD(CONVERT({self.sql(e.this)} USING utf32))",
 888            exp.UnixToTime: _unix_to_time_sql,
 889            exp.Week: _remove_ts_or_ds_to_date(),
 890            exp.WeekOfYear: _remove_ts_or_ds_to_date(rename_func("WEEKOFYEAR")),
 891            exp.Year: _remove_ts_or_ds_to_date(),
 892            exp.UtcTimestamp: rename_func("UTC_TIMESTAMP"),
 893            exp.UtcTime: rename_func("UTC_TIME"),
 894        }
 895
 896        UNSIGNED_TYPE_MAPPING = {
 897            exp.DataType.Type.UBIGINT: "BIGINT",
 898            exp.DataType.Type.UINT: "INT",
 899            exp.DataType.Type.UMEDIUMINT: "MEDIUMINT",
 900            exp.DataType.Type.USMALLINT: "SMALLINT",
 901            exp.DataType.Type.UTINYINT: "TINYINT",
 902            exp.DataType.Type.UDECIMAL: "DECIMAL",
 903            exp.DataType.Type.UDOUBLE: "DOUBLE",
 904        }
 905
 906        TIMESTAMP_TYPE_MAPPING = {
 907            exp.DataType.Type.DATETIME2: "DATETIME",
 908            exp.DataType.Type.SMALLDATETIME: "DATETIME",
 909            exp.DataType.Type.TIMESTAMP: "DATETIME",
 910            exp.DataType.Type.TIMESTAMPNTZ: "DATETIME",
 911            exp.DataType.Type.TIMESTAMPTZ: "TIMESTAMP",
 912            exp.DataType.Type.TIMESTAMPLTZ: "TIMESTAMP",
 913        }
 914
 915        TYPE_MAPPING = {
 916            **generator.Generator.TYPE_MAPPING,
 917            **UNSIGNED_TYPE_MAPPING,
 918            **TIMESTAMP_TYPE_MAPPING,
 919        }
 920
 921        TYPE_MAPPING.pop(exp.DataType.Type.MEDIUMTEXT)
 922        TYPE_MAPPING.pop(exp.DataType.Type.LONGTEXT)
 923        TYPE_MAPPING.pop(exp.DataType.Type.TINYTEXT)
 924        TYPE_MAPPING.pop(exp.DataType.Type.BLOB)
 925        TYPE_MAPPING.pop(exp.DataType.Type.MEDIUMBLOB)
 926        TYPE_MAPPING.pop(exp.DataType.Type.LONGBLOB)
 927        TYPE_MAPPING.pop(exp.DataType.Type.TINYBLOB)
 928
 929        PROPERTIES_LOCATION = {
 930            **generator.Generator.PROPERTIES_LOCATION,
 931            exp.TransientProperty: exp.Properties.Location.UNSUPPORTED,
 932            exp.VolatileProperty: exp.Properties.Location.UNSUPPORTED,
 933            exp.PartitionedByProperty: exp.Properties.Location.UNSUPPORTED,
 934            exp.PartitionByRangeProperty: exp.Properties.Location.POST_SCHEMA,
 935            exp.PartitionByListProperty: exp.Properties.Location.POST_SCHEMA,
 936        }
 937
 938        LIMIT_FETCH = "LIMIT"
 939
 940        LIMIT_ONLY_LITERALS = True
 941
 942        CHAR_CAST_MAPPING = dict.fromkeys(
 943            (
 944                exp.DataType.Type.LONGTEXT,
 945                exp.DataType.Type.LONGBLOB,
 946                exp.DataType.Type.MEDIUMBLOB,
 947                exp.DataType.Type.MEDIUMTEXT,
 948                exp.DataType.Type.TEXT,
 949                exp.DataType.Type.TINYBLOB,
 950                exp.DataType.Type.TINYTEXT,
 951                exp.DataType.Type.VARCHAR,
 952            ),
 953            "CHAR",
 954        )
 955        SIGNED_CAST_MAPPING = dict.fromkeys(
 956            (
 957                exp.DataType.Type.BIGINT,
 958                exp.DataType.Type.BOOLEAN,
 959                exp.DataType.Type.INT,
 960                exp.DataType.Type.SMALLINT,
 961                exp.DataType.Type.TINYINT,
 962                exp.DataType.Type.MEDIUMINT,
 963            ),
 964            "SIGNED",
 965        )
 966
 967        # MySQL doesn't support many datatypes in cast.
 968        # https://dev.mysql.com/doc/refman/8.0/en/cast-functions.html#function_cast
 969        CAST_MAPPING = {
 970            **CHAR_CAST_MAPPING,
 971            **SIGNED_CAST_MAPPING,
 972            exp.DataType.Type.UBIGINT: "UNSIGNED",
 973        }
 974
 975        TIMESTAMP_FUNC_TYPES = {
 976            exp.DataType.Type.TIMESTAMPTZ,
 977            exp.DataType.Type.TIMESTAMPLTZ,
 978        }
 979
 980        # https://dev.mysql.com/doc/refman/8.0/en/keywords.html
 981        RESERVED_KEYWORDS = {
 982            "accessible",
 983            "add",
 984            "all",
 985            "alter",
 986            "analyze",
 987            "and",
 988            "as",
 989            "asc",
 990            "asensitive",
 991            "before",
 992            "between",
 993            "bigint",
 994            "binary",
 995            "blob",
 996            "both",
 997            "by",
 998            "call",
 999            "cascade",
1000            "case",
1001            "change",
1002            "char",
1003            "character",
1004            "check",
1005            "collate",
1006            "column",
1007            "condition",
1008            "constraint",
1009            "continue",
1010            "convert",
1011            "create",
1012            "cross",
1013            "cube",
1014            "cume_dist",
1015            "current_date",
1016            "current_time",
1017            "current_timestamp",
1018            "current_user",
1019            "cursor",
1020            "database",
1021            "databases",
1022            "day_hour",
1023            "day_microsecond",
1024            "day_minute",
1025            "day_second",
1026            "dec",
1027            "decimal",
1028            "declare",
1029            "default",
1030            "delayed",
1031            "delete",
1032            "dense_rank",
1033            "desc",
1034            "describe",
1035            "deterministic",
1036            "distinct",
1037            "distinctrow",
1038            "div",
1039            "double",
1040            "drop",
1041            "dual",
1042            "each",
1043            "else",
1044            "elseif",
1045            "empty",
1046            "enclosed",
1047            "escaped",
1048            "except",
1049            "exists",
1050            "exit",
1051            "explain",
1052            "false",
1053            "fetch",
1054            "first_value",
1055            "float",
1056            "float4",
1057            "float8",
1058            "for",
1059            "force",
1060            "foreign",
1061            "from",
1062            "fulltext",
1063            "function",
1064            "generated",
1065            "get",
1066            "grant",
1067            "group",
1068            "grouping",
1069            "groups",
1070            "having",
1071            "high_priority",
1072            "hour_microsecond",
1073            "hour_minute",
1074            "hour_second",
1075            "if",
1076            "ignore",
1077            "in",
1078            "index",
1079            "infile",
1080            "inner",
1081            "inout",
1082            "insensitive",
1083            "insert",
1084            "int",
1085            "int1",
1086            "int2",
1087            "int3",
1088            "int4",
1089            "int8",
1090            "integer",
1091            "intersect",
1092            "interval",
1093            "into",
1094            "io_after_gtids",
1095            "io_before_gtids",
1096            "is",
1097            "iterate",
1098            "join",
1099            "json_table",
1100            "key",
1101            "keys",
1102            "kill",
1103            "lag",
1104            "last_value",
1105            "lateral",
1106            "lead",
1107            "leading",
1108            "leave",
1109            "left",
1110            "like",
1111            "limit",
1112            "linear",
1113            "lines",
1114            "load",
1115            "localtime",
1116            "localtimestamp",
1117            "lock",
1118            "long",
1119            "longblob",
1120            "longtext",
1121            "loop",
1122            "low_priority",
1123            "master_bind",
1124            "master_ssl_verify_server_cert",
1125            "match",
1126            "maxvalue",
1127            "mediumblob",
1128            "mediumint",
1129            "mediumtext",
1130            "middleint",
1131            "minute_microsecond",
1132            "minute_second",
1133            "mod",
1134            "modifies",
1135            "natural",
1136            "not",
1137            "no_write_to_binlog",
1138            "nth_value",
1139            "ntile",
1140            "null",
1141            "numeric",
1142            "of",
1143            "on",
1144            "optimize",
1145            "optimizer_costs",
1146            "option",
1147            "optionally",
1148            "or",
1149            "order",
1150            "out",
1151            "outer",
1152            "outfile",
1153            "over",
1154            "partition",
1155            "percent_rank",
1156            "precision",
1157            "primary",
1158            "procedure",
1159            "purge",
1160            "range",
1161            "rank",
1162            "read",
1163            "reads",
1164            "read_write",
1165            "real",
1166            "recursive",
1167            "references",
1168            "regexp",
1169            "release",
1170            "rename",
1171            "repeat",
1172            "replace",
1173            "require",
1174            "resignal",
1175            "restrict",
1176            "return",
1177            "revoke",
1178            "right",
1179            "rlike",
1180            "row",
1181            "rows",
1182            "row_number",
1183            "schema",
1184            "schemas",
1185            "second_microsecond",
1186            "select",
1187            "sensitive",
1188            "separator",
1189            "set",
1190            "show",
1191            "signal",
1192            "smallint",
1193            "spatial",
1194            "specific",
1195            "sql",
1196            "sqlexception",
1197            "sqlstate",
1198            "sqlwarning",
1199            "sql_big_result",
1200            "sql_calc_found_rows",
1201            "sql_small_result",
1202            "ssl",
1203            "starting",
1204            "stored",
1205            "straight_join",
1206            "system",
1207            "table",
1208            "terminated",
1209            "then",
1210            "tinyblob",
1211            "tinyint",
1212            "tinytext",
1213            "to",
1214            "trailing",
1215            "trigger",
1216            "true",
1217            "undo",
1218            "union",
1219            "unique",
1220            "unlock",
1221            "unsigned",
1222            "update",
1223            "usage",
1224            "use",
1225            "using",
1226            "utc_date",
1227            "utc_time",
1228            "utc_timestamp",
1229            "values",
1230            "varbinary",
1231            "varchar",
1232            "varcharacter",
1233            "varying",
1234            "virtual",
1235            "when",
1236            "where",
1237            "while",
1238            "window",
1239            "with",
1240            "write",
1241            "xor",
1242            "year_month",
1243            "zerofill",
1244        }
1245
1246        def computedcolumnconstraint_sql(self, expression: exp.ComputedColumnConstraint) -> str:
1247            persisted = "STORED" if expression.args.get("persisted") else "VIRTUAL"
1248            return f"GENERATED ALWAYS AS ({self.sql(expression.this.unnest())}) {persisted}"
1249
1250        def array_sql(self, expression: exp.Array) -> str:
1251            self.unsupported("Arrays are not supported by MySQL")
1252            return self.function_fallback_sql(expression)
1253
1254        def arraycontainsall_sql(self, expression: exp.ArrayContainsAll) -> str:
1255            self.unsupported("Array operations are not supported by MySQL")
1256            return self.function_fallback_sql(expression)
1257
1258        def dpipe_sql(self, expression: exp.DPipe) -> str:
1259            return self.func("CONCAT", *expression.flatten())
1260
1261        def extract_sql(self, expression: exp.Extract) -> str:
1262            unit = expression.name
1263            if unit and unit.lower() == "epoch":
1264                return self.func("UNIX_TIMESTAMP", expression.expression)
1265
1266            return super().extract_sql(expression)
1267
1268        def datatype_sql(self, expression: exp.DataType) -> str:
1269            if (
1270                self.VARCHAR_REQUIRES_SIZE
1271                and expression.is_type(exp.DataType.Type.VARCHAR)
1272                and not expression.expressions
1273            ):
1274                # `VARCHAR` must always have a size - if it doesn't, we always generate `TEXT`
1275                return "TEXT"
1276
1277            # https://dev.mysql.com/doc/refman/8.0/en/numeric-type-syntax.html
1278            result = super().datatype_sql(expression)
1279            if expression.this in self.UNSIGNED_TYPE_MAPPING:
1280                result = f"{result} UNSIGNED"
1281
1282            return result
1283
1284        def jsonarraycontains_sql(self, expression: exp.JSONArrayContains) -> str:
1285            return f"{self.sql(expression, 'this')} MEMBER OF({self.sql(expression, 'expression')})"
1286
1287        def cast_sql(self, expression: exp.Cast, safe_prefix: t.Optional[str] = None) -> str:
1288            if expression.to.this in self.TIMESTAMP_FUNC_TYPES:
1289                return self.func("TIMESTAMP", expression.this)
1290
1291            to = self.CAST_MAPPING.get(expression.to.this)
1292
1293            if to:
1294                expression.to.set("this", to)
1295            return super().cast_sql(expression)
1296
1297        def show_sql(self, expression: exp.Show) -> str:
1298            this = f" {expression.name}"
1299            full = " FULL" if expression.args.get("full") else ""
1300            global_ = " GLOBAL" if expression.args.get("global_") else ""
1301
1302            target = self.sql(expression, "target")
1303            target = f" {target}" if target else ""
1304            if expression.name in ("COLUMNS", "INDEX"):
1305                target = f" FROM{target}"
1306            elif expression.name == "GRANTS":
1307                target = f" FOR{target}"
1308            elif expression.name in ("LINKS", "PARTITIONS"):
1309                target = f" ON{target}" if target else ""
1310            elif expression.name == "PROJECTIONS":
1311                target = f" ON TABLE{target}" if target else ""
1312
1313            db = self._prefixed_sql("FROM", expression, "db")
1314
1315            like = self._prefixed_sql("LIKE", expression, "like")
1316            where = self.sql(expression, "where")
1317
1318            types = self.expressions(expression, key="types")
1319            types = f" {types}" if types else types
1320            query = self._prefixed_sql("FOR QUERY", expression, "query")
1321
1322            if expression.name == "PROFILE":
1323                offset = self._prefixed_sql("OFFSET", expression, "offset")
1324                limit = self._prefixed_sql("LIMIT", expression, "limit")
1325            else:
1326                offset = ""
1327                limit = self._oldstyle_limit_sql(expression)
1328
1329            log = self._prefixed_sql("IN", expression, "log")
1330            position = self._prefixed_sql("FROM", expression, "position")
1331
1332            channel = self._prefixed_sql("FOR CHANNEL", expression, "channel")
1333
1334            if expression.name == "ENGINE":
1335                mutex_or_status = " MUTEX" if expression.args.get("mutex") else " STATUS"
1336            else:
1337                mutex_or_status = ""
1338
1339            for_table = self._prefixed_sql("FOR TABLE", expression, "for_table")
1340            for_group = self._prefixed_sql("FOR GROUP", expression, "for_group")
1341            for_user = self._prefixed_sql("FOR USER", expression, "for_user")
1342            for_role = self._prefixed_sql("FOR ROLE", expression, "for_role")
1343            into_outfile = self._prefixed_sql("INTO OUTFILE", expression, "into_outfile")
1344            json = " JSON" if expression.args.get("json") else ""
1345
1346            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}"
1347
1348        def alterrename_sql(self, expression: exp.AlterRename, include_to: bool = True) -> str:
1349            """To avoid TO keyword in ALTER ... RENAME statements.
1350            It's moved from Doris, because it's the same for all MySQL, Doris, and StarRocks.
1351            """
1352            return super().alterrename_sql(expression, include_to=False)
1353
1354        def altercolumn_sql(self, expression: exp.AlterColumn) -> str:
1355            dtype = self.sql(expression, "dtype")
1356            if not dtype:
1357                return super().altercolumn_sql(expression)
1358
1359            this = self.sql(expression, "this")
1360            return f"MODIFY COLUMN {this} {dtype}"
1361
1362        def _prefixed_sql(self, prefix: str, expression: exp.Expression, arg: str) -> str:
1363            sql = self.sql(expression, arg)
1364            return f" {prefix} {sql}" if sql else ""
1365
1366        def _oldstyle_limit_sql(self, expression: exp.Show) -> str:
1367            limit = self.sql(expression, "limit")
1368            offset = self.sql(expression, "offset")
1369            if limit:
1370                limit_offset = f"{offset}, {limit}" if offset else limit
1371                return f" LIMIT {limit_offset}"
1372            return ""
1373
1374        def timestamptrunc_sql(self, expression: exp.TimestampTrunc) -> str:
1375            unit = expression.args.get("unit")
1376
1377            # Pick an old-enough date to avoid negative timestamp diffs
1378            start_ts = "'0000-01-01 00:00:00'"
1379
1380            # Source: https://stackoverflow.com/a/32955740
1381            timestamp_diff = build_date_delta(exp.TimestampDiff)([unit, start_ts, expression.this])
1382            interval = exp.Interval(this=timestamp_diff, unit=unit)
1383            dateadd = build_date_delta_with_interval(exp.DateAdd)([start_ts, interval])
1384
1385            return self.sql(dateadd)
1386
1387        def converttimezone_sql(self, expression: exp.ConvertTimezone) -> str:
1388            from_tz = expression.args.get("source_tz")
1389            to_tz = expression.args.get("target_tz")
1390            dt = expression.args.get("timestamp")
1391
1392            return self.func("CONVERT_TZ", dt, from_tz, to_tz)
1393
1394        def attimezone_sql(self, expression: exp.AtTimeZone) -> str:
1395            self.unsupported("AT TIME ZONE is not supported by MySQL")
1396            return self.sql(expression.this)
1397
1398        def isascii_sql(self, expression: exp.IsAscii) -> str:
1399            return f"REGEXP_LIKE({self.sql(expression.this)}, '^[[:ascii:]]*$')"
1400
1401        def ignorenulls_sql(self, expression: exp.IgnoreNulls) -> str:
1402            # https://dev.mysql.com/doc/refman/8.4/en/window-function-descriptions.html
1403            self.unsupported("MySQL does not support IGNORE NULLS.")
1404            return self.sql(expression.this)
1405
1406        @unsupported_args("this")
1407        def currentschema_sql(self, expression: exp.CurrentSchema) -> str:
1408            return self.func("SCHEMA")
1409
1410        def partition_sql(self, expression: exp.Partition) -> str:
1411            parent = expression.parent
1412            if isinstance(parent, (exp.PartitionByRangeProperty, exp.PartitionByListProperty)):
1413                return self.expressions(expression, flat=True)
1414            return super().partition_sql(expression)
1415
1416        def _partition_by_sql(
1417            self, expression: exp.PartitionByRangeProperty | exp.PartitionByListProperty, kind: str
1418        ) -> str:
1419            partitions = self.expressions(expression, key="partition_expressions", flat=True)
1420            create = self.expressions(expression, key="create_expressions", flat=True)
1421            return f"PARTITION BY {kind} ({partitions}) ({create})"
1422
1423        def partitionbyrangeproperty_sql(self, expression: exp.PartitionByRangeProperty) -> str:
1424            return self._partition_by_sql(expression, "RANGE")
1425
1426        def partitionbylistproperty_sql(self, expression: exp.PartitionByListProperty) -> str:
1427            return self._partition_by_sql(expression, "LIST")
1428
1429        def partitionlist_sql(self, expression: exp.PartitionList) -> str:
1430            name = self.sql(expression, "this")
1431            values = self.expressions(expression, flat=True)
1432            return f"PARTITION {name} VALUES IN ({values})"
1433
1434        def partitionrange_sql(self, expression: exp.PartitionRange) -> str:
1435            name = self.sql(expression, "this")
1436            values = self.expressions(expression, flat=True)
1437            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.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.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.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.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.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 = {'double', 'group', 'schemas', 'mediumblob', 'localtime', 'float4', 'xor', 'enclosed', 'char', 'function', 'load', 'straight_join', 'cube', 'database', 'procedure', 'grouping', 'first_value', 'false', 'inner', 'keys', 'regexp', 'both', 'current_time', 'having', 'force', 'in', 'analyze', 'day_hour', 'long', 'rename', 'as', 'resignal', 'escaped', 'case', 'except', 'select', 'trigger', 'update', 'values', 'grant', 'varchar', 'float', 'distinct', 'of', 'iterate', 'restrict', 'cascade', 'to', 'ntile', 'no_write_to_binlog', 'current_date', 'read', 'dec', 'signal', 'longblob', 'sql_small_result', 'column', 'tinyblob', 'json_table', 'cross', 'change', 'binary', 'match', 'ssl', 'leading', 'day_minute', 'tinytext', 'range', 'window', 'elseif', 'minute_microsecond', 'outer', 'int8', 'if', 'blob', 'join', 'inout', 'get', 'groups', 'else', 'schema', 'localtimestamp', 'starting', 'create', 'key', 'when', 'foreign', 'optionally', 'low_priority', 'rlike', 'call', 'release', 'rank', 'insert', 'float8', 'sql_big_result', 'specific', 'primary', 'int3', 'utc_date', 'drop', 'loop', 'unique', 'day_second', 'out', 'kill', 'precision', 'collate', 'or', 'describe', 'decimal', 'varcharacter', 'insensitive', 'between', 'revoke', 'row', 'optimizer_costs', 'unlock', 'with', 'before', 'dense_rank', 'system', 'like', 'maxvalue', 'write', 'then', 'asc', 'fulltext', 'undo', 'middleint', 'sqlwarning', 'year_month', 'percent_rank', 'optimize', 'int', 'databases', 'character', 'union', 'over', 'read_write', 'table', 'linear', 'continue', 'by', 'int1', 'right', 'exists', 'sensitive', 'leave', 'mediumint', 'numeric', 'second_microsecond', 'condition', 'virtual', 'sql_calc_found_rows', 'current_timestamp', 'mediumtext', 'stored', 'natural', 'references', 'rows', 'replace', 'cursor', 'limit', 'unsigned', 'empty', 'sqlstate', 'use', 'cume_dist', 'show', 'spatial', 'div', 'return', 'tinyint', 'order', 'true', 'hour_second', 'purge', 'current_user', 'while', 'reads', 'dual', 'from', 'int2', 'is', 'deterministic', 'constraint', 'interval', 'last_value', 'bigint', 'exit', 'utc_time', 'io_after_gtids', 'lateral', 'sql', 'smallint', 'varying', 'outfile', 'terminated', 'not', 'io_before_gtids', 'zerofill', 'fetch', 'alter', 'modifies', 'hour_minute', 'separator', 'lead', 'require', 'hour_microsecond', 'longtext', 'master_ssl_verify_server_cert', 'infile', 'add', 'utc_timestamp', 'row_number', 'check', 'using', 'distinctrow', 'lag', 'varbinary', 'set', 'high_priority', 'minute_second', 'where', 'sqlexception', 'null', 'ignore', 'recursive', 'index', 'partition', 'lock', 'into', 'each', 'generated', 'left', 'option', 'declare', 'usage', 'convert', 'master_bind', 'explain', 'mod', 'default', 'and', 'real', 'delete', 'intersect', 'delayed', 'nth_value', 'trailing', 'lines', 'integer', 'all', 'accessible', 'for', 'day_microsecond', 'desc', 'int4', 'asensitive', 'on', 'repeat'}
def computedcolumnconstraint_sql(self, expression: sqlglot.expressions.ComputedColumnConstraint) -> str:
1246        def computedcolumnconstraint_sql(self, expression: exp.ComputedColumnConstraint) -> str:
1247            persisted = "STORED" if expression.args.get("persisted") else "VIRTUAL"
1248            return f"GENERATED ALWAYS AS ({self.sql(expression.this.unnest())}) {persisted}"
def array_sql(self, expression: sqlglot.expressions.Array) -> str:
1250        def array_sql(self, expression: exp.Array) -> str:
1251            self.unsupported("Arrays are not supported by MySQL")
1252            return self.function_fallback_sql(expression)
def arraycontainsall_sql(self, expression: sqlglot.expressions.ArrayContainsAll) -> str:
1254        def arraycontainsall_sql(self, expression: exp.ArrayContainsAll) -> str:
1255            self.unsupported("Array operations are not supported by MySQL")
1256            return self.function_fallback_sql(expression)
def dpipe_sql(self, expression: sqlglot.expressions.DPipe) -> str:
1258        def dpipe_sql(self, expression: exp.DPipe) -> str:
1259            return self.func("CONCAT", *expression.flatten())
def extract_sql(self, expression: sqlglot.expressions.Extract) -> str:
1261        def extract_sql(self, expression: exp.Extract) -> str:
1262            unit = expression.name
1263            if unit and unit.lower() == "epoch":
1264                return self.func("UNIX_TIMESTAMP", expression.expression)
1265
1266            return super().extract_sql(expression)
def datatype_sql(self, expression: sqlglot.expressions.DataType) -> str:
1268        def datatype_sql(self, expression: exp.DataType) -> str:
1269            if (
1270                self.VARCHAR_REQUIRES_SIZE
1271                and expression.is_type(exp.DataType.Type.VARCHAR)
1272                and not expression.expressions
1273            ):
1274                # `VARCHAR` must always have a size - if it doesn't, we always generate `TEXT`
1275                return "TEXT"
1276
1277            # https://dev.mysql.com/doc/refman/8.0/en/numeric-type-syntax.html
1278            result = super().datatype_sql(expression)
1279            if expression.this in self.UNSIGNED_TYPE_MAPPING:
1280                result = f"{result} UNSIGNED"
1281
1282            return result
def jsonarraycontains_sql(self, expression: sqlglot.expressions.JSONArrayContains) -> str:
1284        def jsonarraycontains_sql(self, expression: exp.JSONArrayContains) -> str:
1285            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:
1287        def cast_sql(self, expression: exp.Cast, safe_prefix: t.Optional[str] = None) -> str:
1288            if expression.to.this in self.TIMESTAMP_FUNC_TYPES:
1289                return self.func("TIMESTAMP", expression.this)
1290
1291            to = self.CAST_MAPPING.get(expression.to.this)
1292
1293            if to:
1294                expression.to.set("this", to)
1295            return super().cast_sql(expression)
def show_sql(self, expression: sqlglot.expressions.Show) -> str:
1297        def show_sql(self, expression: exp.Show) -> str:
1298            this = f" {expression.name}"
1299            full = " FULL" if expression.args.get("full") else ""
1300            global_ = " GLOBAL" if expression.args.get("global_") else ""
1301
1302            target = self.sql(expression, "target")
1303            target = f" {target}" if target else ""
1304            if expression.name in ("COLUMNS", "INDEX"):
1305                target = f" FROM{target}"
1306            elif expression.name == "GRANTS":
1307                target = f" FOR{target}"
1308            elif expression.name in ("LINKS", "PARTITIONS"):
1309                target = f" ON{target}" if target else ""
1310            elif expression.name == "PROJECTIONS":
1311                target = f" ON TABLE{target}" if target else ""
1312
1313            db = self._prefixed_sql("FROM", expression, "db")
1314
1315            like = self._prefixed_sql("LIKE", expression, "like")
1316            where = self.sql(expression, "where")
1317
1318            types = self.expressions(expression, key="types")
1319            types = f" {types}" if types else types
1320            query = self._prefixed_sql("FOR QUERY", expression, "query")
1321
1322            if expression.name == "PROFILE":
1323                offset = self._prefixed_sql("OFFSET", expression, "offset")
1324                limit = self._prefixed_sql("LIMIT", expression, "limit")
1325            else:
1326                offset = ""
1327                limit = self._oldstyle_limit_sql(expression)
1328
1329            log = self._prefixed_sql("IN", expression, "log")
1330            position = self._prefixed_sql("FROM", expression, "position")
1331
1332            channel = self._prefixed_sql("FOR CHANNEL", expression, "channel")
1333
1334            if expression.name == "ENGINE":
1335                mutex_or_status = " MUTEX" if expression.args.get("mutex") else " STATUS"
1336            else:
1337                mutex_or_status = ""
1338
1339            for_table = self._prefixed_sql("FOR TABLE", expression, "for_table")
1340            for_group = self._prefixed_sql("FOR GROUP", expression, "for_group")
1341            for_user = self._prefixed_sql("FOR USER", expression, "for_user")
1342            for_role = self._prefixed_sql("FOR ROLE", expression, "for_role")
1343            into_outfile = self._prefixed_sql("INTO OUTFILE", expression, "into_outfile")
1344            json = " JSON" if expression.args.get("json") else ""
1345
1346            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:
1348        def alterrename_sql(self, expression: exp.AlterRename, include_to: bool = True) -> str:
1349            """To avoid TO keyword in ALTER ... RENAME statements.
1350            It's moved from Doris, because it's the same for all MySQL, Doris, and StarRocks.
1351            """
1352            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:
1354        def altercolumn_sql(self, expression: exp.AlterColumn) -> str:
1355            dtype = self.sql(expression, "dtype")
1356            if not dtype:
1357                return super().altercolumn_sql(expression)
1358
1359            this = self.sql(expression, "this")
1360            return f"MODIFY COLUMN {this} {dtype}"
def timestamptrunc_sql(self, expression: sqlglot.expressions.TimestampTrunc) -> str:
1374        def timestamptrunc_sql(self, expression: exp.TimestampTrunc) -> str:
1375            unit = expression.args.get("unit")
1376
1377            # Pick an old-enough date to avoid negative timestamp diffs
1378            start_ts = "'0000-01-01 00:00:00'"
1379
1380            # Source: https://stackoverflow.com/a/32955740
1381            timestamp_diff = build_date_delta(exp.TimestampDiff)([unit, start_ts, expression.this])
1382            interval = exp.Interval(this=timestamp_diff, unit=unit)
1383            dateadd = build_date_delta_with_interval(exp.DateAdd)([start_ts, interval])
1384
1385            return self.sql(dateadd)
def converttimezone_sql(self, expression: sqlglot.expressions.ConvertTimezone) -> str:
1387        def converttimezone_sql(self, expression: exp.ConvertTimezone) -> str:
1388            from_tz = expression.args.get("source_tz")
1389            to_tz = expression.args.get("target_tz")
1390            dt = expression.args.get("timestamp")
1391
1392            return self.func("CONVERT_TZ", dt, from_tz, to_tz)
def attimezone_sql(self, expression: sqlglot.expressions.AtTimeZone) -> str:
1394        def attimezone_sql(self, expression: exp.AtTimeZone) -> str:
1395            self.unsupported("AT TIME ZONE is not supported by MySQL")
1396            return self.sql(expression.this)
def isascii_sql(self, expression: sqlglot.expressions.IsAscii) -> str:
1398        def isascii_sql(self, expression: exp.IsAscii) -> str:
1399            return f"REGEXP_LIKE({self.sql(expression.this)}, '^[[:ascii:]]*$')"
def ignorenulls_sql(self, expression: sqlglot.expressions.IgnoreNulls) -> str:
1401        def ignorenulls_sql(self, expression: exp.IgnoreNulls) -> str:
1402            # https://dev.mysql.com/doc/refman/8.4/en/window-function-descriptions.html
1403            self.unsupported("MySQL does not support IGNORE NULLS.")
1404            return self.sql(expression.this)
@unsupported_args('this')
def currentschema_sql(self, expression: sqlglot.expressions.CurrentSchema) -> str:
1406        @unsupported_args("this")
1407        def currentschema_sql(self, expression: exp.CurrentSchema) -> str:
1408            return self.func("SCHEMA")
def partition_sql(self, expression: sqlglot.expressions.Partition) -> str:
1410        def partition_sql(self, expression: exp.Partition) -> str:
1411            parent = expression.parent
1412            if isinstance(parent, (exp.PartitionByRangeProperty, exp.PartitionByListProperty)):
1413                return self.expressions(expression, flat=True)
1414            return super().partition_sql(expression)
def partitionbyrangeproperty_sql(self, expression: sqlglot.expressions.PartitionByRangeProperty) -> str:
1423        def partitionbyrangeproperty_sql(self, expression: exp.PartitionByRangeProperty) -> str:
1424            return self._partition_by_sql(expression, "RANGE")
def partitionbylistproperty_sql(self, expression: sqlglot.expressions.PartitionByListProperty) -> str:
1426        def partitionbylistproperty_sql(self, expression: exp.PartitionByListProperty) -> str:
1427            return self._partition_by_sql(expression, "LIST")
def partitionlist_sql(self, expression: sqlglot.expressions.PartitionList) -> str:
1429        def partitionlist_sql(self, expression: exp.PartitionList) -> str:
1430            name = self.sql(expression, "this")
1431            values = self.expressions(expression, flat=True)
1432            return f"PARTITION {name} VALUES IN ({values})"
def partitionrange_sql(self, expression: sqlglot.expressions.PartitionRange) -> str:
1434        def partitionrange_sql(self, expression: exp.PartitionRange) -> str:
1435            name = self.sql(expression, "this")
1436            values = self.expressions(expression, flat=True)
1437            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
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
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