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

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.

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 ( ).

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
class MySQL.Tokenizer(sqlglot.tokens.Tokenizer):
179    class Tokenizer(tokens.Tokenizer):
180        QUOTES = ["'", '"']
181        COMMENTS = ["--", "#", ("/*", "*/")]
182        IDENTIFIERS = ["`"]
183        STRING_ESCAPES = ["'", '"', "\\"]
184        BIT_STRINGS = [("b'", "'"), ("B'", "'"), ("0b", "")]
185        HEX_STRINGS = [("x'", "'"), ("X'", "'"), ("0x", "")]
186
187        KEYWORDS = {
188            **tokens.Tokenizer.KEYWORDS,
189            "CHARSET": TokenType.CHARACTER_SET,
190            "FORCE": TokenType.FORCE,
191            "IGNORE": TokenType.IGNORE,
192            "KEY": TokenType.KEY,
193            "LOCK TABLES": TokenType.COMMAND,
194            "LONGBLOB": TokenType.LONGBLOB,
195            "LONGTEXT": TokenType.LONGTEXT,
196            "MEDIUMBLOB": TokenType.MEDIUMBLOB,
197            "TINYBLOB": TokenType.TINYBLOB,
198            "TINYTEXT": TokenType.TINYTEXT,
199            "MEDIUMTEXT": TokenType.MEDIUMTEXT,
200            "MEDIUMINT": TokenType.MEDIUMINT,
201            "MEMBER OF": TokenType.MEMBER_OF,
202            "SEPARATOR": TokenType.SEPARATOR,
203            "START": TokenType.BEGIN,
204            "SIGNED": TokenType.BIGINT,
205            "SIGNED INTEGER": TokenType.BIGINT,
206            "UNLOCK TABLES": TokenType.COMMAND,
207            "UNSIGNED": TokenType.UBIGINT,
208            "UNSIGNED INTEGER": TokenType.UBIGINT,
209            "YEAR": TokenType.YEAR,
210            "_ARMSCII8": TokenType.INTRODUCER,
211            "_ASCII": TokenType.INTRODUCER,
212            "_BIG5": TokenType.INTRODUCER,
213            "_BINARY": TokenType.INTRODUCER,
214            "_CP1250": TokenType.INTRODUCER,
215            "_CP1251": TokenType.INTRODUCER,
216            "_CP1256": TokenType.INTRODUCER,
217            "_CP1257": TokenType.INTRODUCER,
218            "_CP850": TokenType.INTRODUCER,
219            "_CP852": TokenType.INTRODUCER,
220            "_CP866": TokenType.INTRODUCER,
221            "_CP932": TokenType.INTRODUCER,
222            "_DEC8": TokenType.INTRODUCER,
223            "_EUCJPMS": TokenType.INTRODUCER,
224            "_EUCKR": TokenType.INTRODUCER,
225            "_GB18030": TokenType.INTRODUCER,
226            "_GB2312": TokenType.INTRODUCER,
227            "_GBK": TokenType.INTRODUCER,
228            "_GEOSTD8": TokenType.INTRODUCER,
229            "_GREEK": TokenType.INTRODUCER,
230            "_HEBREW": TokenType.INTRODUCER,
231            "_HP8": TokenType.INTRODUCER,
232            "_KEYBCS2": TokenType.INTRODUCER,
233            "_KOI8R": TokenType.INTRODUCER,
234            "_KOI8U": TokenType.INTRODUCER,
235            "_LATIN1": TokenType.INTRODUCER,
236            "_LATIN2": TokenType.INTRODUCER,
237            "_LATIN5": TokenType.INTRODUCER,
238            "_LATIN7": TokenType.INTRODUCER,
239            "_MACCE": TokenType.INTRODUCER,
240            "_MACROMAN": TokenType.INTRODUCER,
241            "_SJIS": TokenType.INTRODUCER,
242            "_SWE7": TokenType.INTRODUCER,
243            "_TIS620": TokenType.INTRODUCER,
244            "_UCS2": TokenType.INTRODUCER,
245            "_UJIS": TokenType.INTRODUCER,
246            # https://dev.mysql.com/doc/refman/8.0/en/string-literals.html
247            "_UTF8": TokenType.INTRODUCER,
248            "_UTF16": TokenType.INTRODUCER,
249            "_UTF16LE": TokenType.INTRODUCER,
250            "_UTF32": TokenType.INTRODUCER,
251            "_UTF8MB3": TokenType.INTRODUCER,
252            "_UTF8MB4": TokenType.INTRODUCER,
253            "@@": TokenType.SESSION_PARAMETER,
254        }
255
256        COMMANDS = {*tokens.Tokenizer.COMMANDS, TokenType.REPLACE} - {TokenType.SHOW}
QUOTES = ["'", '"']
COMMENTS = ['--', '#', ('/*', '*/')]
IDENTIFIERS = ['`']
STRING_ESCAPES = ["'", '"', '\\']
BIT_STRINGS = [("b'", "'"), ("B'", "'"), ('0b', '')]
HEX_STRINGS = [("x'", "'"), ("X'", "'"), ('0x', '')]
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.EQ: 'EQ'>, '::': <TokenType.DCOLON: 'DCOLON'>, '||': <TokenType.DPIPE: 'DPIPE'>, '>=': <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'>, 'ALL': <TokenType.ALL: 'ALL'>, 'ALWAYS': <TokenType.ALWAYS: 'ALWAYS'>, '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_TIME': <TokenType.CURRENT_TIME: 'CURRENT_TIME'>, 'CURRENT_TIMESTAMP': <TokenType.CURRENT_TIMESTAMP: 'CURRENT_TIMESTAMP'>, 'CURRENT_USER': <TokenType.CURRENT_USER: 'CURRENT_USER'>, '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'>, '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'>, 'LOCK': <TokenType.LOCK: 'LOCK'>, 'MERGE': <TokenType.MERGE: 'MERGE'>, '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'>, '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'>, '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'>, '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'>, 'INT128': <TokenType.INT128: 'INT128'>, 'HUGEINT': <TokenType.INT128: 'INT128'>, 'INT2': <TokenType.SMALLINT: 'SMALLINT'>, 'INTEGER': <TokenType.INT: 'INT'>, 'INT': <TokenType.INT: 'INT'>, 'INT4': <TokenType.INT: 'INT'>, 'INT32': <TokenType.INT: 'INT'>, 'INT64': <TokenType.BIGINT: 'BIGINT'>, 'LONG': <TokenType.BIGINT: 'BIGINT'>, 'BIGINT': <TokenType.BIGINT: 'BIGINT'>, 'INT8': <TokenType.TINYINT: 'TINYINT'>, 'UINT': <TokenType.UINT: 'UINT'>, 'DEC': <TokenType.DECIMAL: 'DECIMAL'>, 'DECIMAL': <TokenType.DECIMAL: 'DECIMAL'>, 'BIGDECIMAL': <TokenType.BIGDECIMAL: 'BIGDECIMAL'>, 'BIGNUMERIC': <TokenType.BIGDECIMAL: 'BIGDECIMAL'>, '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'>, '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.VARBINARY: 'VARBINARY'>, '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'>, 'TIMESTAMP': <TokenType.TIMESTAMP: 'TIMESTAMP'>, '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.COMMAND: 'COMMAND'>, 'CALL': <TokenType.COMMAND: 'COMMAND'>, 'COMMENT': <TokenType.COMMENT: 'COMMENT'>, 'EXPLAIN': <TokenType.COMMAND: 'COMMAND'>, 'GRANT': <TokenType.COMMAND: 'COMMAND'>, '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'>, 'FORCE': <TokenType.FORCE: 'FORCE'>, 'IGNORE': <TokenType.IGNORE: 'IGNORE'>, 'KEY': <TokenType.KEY: 'KEY'>, 'LOCK TABLES': <TokenType.COMMAND: 'COMMAND'>, 'MEMBER OF': <TokenType.MEMBER_OF: 'MEMBER_OF'>, 'SEPARATOR': <TokenType.SEPARATOR: 'SEPARATOR'>, 'START': <TokenType.BEGIN: 'BEGIN'>, 'SIGNED': <TokenType.BIGINT: 'BIGINT'>, 'SIGNED INTEGER': <TokenType.BIGINT: 'BIGINT'>, '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.EXECUTE: 'EXECUTE'>, <TokenType.REPLACE: 'REPLACE'>, <TokenType.COMMAND: 'COMMAND'>, <TokenType.FETCH: 'FETCH'>, <TokenType.RENAME: 'RENAME'>}
class MySQL.Parser(sqlglot.parser.Parser):
258    class Parser(parser.Parser):
259        FUNC_TOKENS = {
260            *parser.Parser.FUNC_TOKENS,
261            TokenType.DATABASE,
262            TokenType.SCHEMA,
263            TokenType.VALUES,
264        }
265
266        CONJUNCTION = {
267            **parser.Parser.CONJUNCTION,
268            TokenType.DAMP: exp.And,
269            TokenType.XOR: exp.Xor,
270        }
271
272        DISJUNCTION = {
273            **parser.Parser.DISJUNCTION,
274            TokenType.DPIPE: exp.Or,
275        }
276
277        TABLE_ALIAS_TOKENS = (
278            parser.Parser.TABLE_ALIAS_TOKENS - parser.Parser.TABLE_INDEX_HINT_TOKENS
279        )
280
281        RANGE_PARSERS = {
282            **parser.Parser.RANGE_PARSERS,
283            TokenType.MEMBER_OF: lambda self, this: self.expression(
284                exp.JSONArrayContains,
285                this=this,
286                expression=self._parse_wrapped(self._parse_expression),
287            ),
288        }
289
290        FUNCTIONS = {
291            **parser.Parser.FUNCTIONS,
292            "CONVERT_TZ": lambda args: exp.ConvertTimezone(
293                source_tz=seq_get(args, 1), target_tz=seq_get(args, 2), timestamp=seq_get(args, 0)
294            ),
295            "DATE": lambda args: exp.TsOrDsToDate(this=seq_get(args, 0)),
296            "DATE_ADD": build_date_delta_with_interval(exp.DateAdd),
297            "DATE_FORMAT": build_formatted_time(exp.TimeToStr, "mysql"),
298            "DATE_SUB": build_date_delta_with_interval(exp.DateSub),
299            "DAY": lambda args: exp.Day(this=exp.TsOrDsToDate(this=seq_get(args, 0))),
300            "DAYOFMONTH": lambda args: exp.DayOfMonth(this=exp.TsOrDsToDate(this=seq_get(args, 0))),
301            "DAYOFWEEK": lambda args: exp.DayOfWeek(this=exp.TsOrDsToDate(this=seq_get(args, 0))),
302            "DAYOFYEAR": lambda args: exp.DayOfYear(this=exp.TsOrDsToDate(this=seq_get(args, 0))),
303            "INSTR": lambda args: exp.StrPosition(substr=seq_get(args, 1), this=seq_get(args, 0)),
304            "FROM_UNIXTIME": build_formatted_time(exp.UnixToTime, "mysql"),
305            "ISNULL": isnull_to_is_null,
306            "LOCATE": locate_to_strposition,
307            "MAKETIME": exp.TimeFromParts.from_arg_list,
308            "MONTH": lambda args: exp.Month(this=exp.TsOrDsToDate(this=seq_get(args, 0))),
309            "MONTHNAME": lambda args: exp.TimeToStr(
310                this=exp.TsOrDsToDate(this=seq_get(args, 0)),
311                format=exp.Literal.string("%B"),
312            ),
313            "STR_TO_DATE": _str_to_date,
314            "TIMESTAMPDIFF": build_date_delta(exp.TimestampDiff),
315            "TO_DAYS": lambda args: exp.paren(
316                exp.DateDiff(
317                    this=exp.TsOrDsToDate(this=seq_get(args, 0)),
318                    expression=exp.TsOrDsToDate(this=exp.Literal.string("0000-01-01")),
319                    unit=exp.var("DAY"),
320                )
321                + 1
322            ),
323            "WEEK": lambda args: exp.Week(
324                this=exp.TsOrDsToDate(this=seq_get(args, 0)), mode=seq_get(args, 1)
325            ),
326            "WEEKOFYEAR": lambda args: exp.WeekOfYear(this=exp.TsOrDsToDate(this=seq_get(args, 0))),
327            "YEAR": lambda args: exp.Year(this=exp.TsOrDsToDate(this=seq_get(args, 0))),
328        }
329
330        FUNCTION_PARSERS = {
331            **parser.Parser.FUNCTION_PARSERS,
332            "CHAR": lambda self: self._parse_chr(),
333            "GROUP_CONCAT": lambda self: self._parse_group_concat(),
334            # https://dev.mysql.com/doc/refman/5.7/en/miscellaneous-functions.html#function_values
335            "VALUES": lambda self: self.expression(
336                exp.Anonymous, this="VALUES", expressions=[self._parse_id_var()]
337            ),
338        }
339
340        STATEMENT_PARSERS = {
341            **parser.Parser.STATEMENT_PARSERS,
342            TokenType.SHOW: lambda self: self._parse_show(),
343        }
344
345        SHOW_PARSERS = {
346            "BINARY LOGS": _show_parser("BINARY LOGS"),
347            "MASTER LOGS": _show_parser("BINARY LOGS"),
348            "BINLOG EVENTS": _show_parser("BINLOG EVENTS"),
349            "CHARACTER SET": _show_parser("CHARACTER SET"),
350            "CHARSET": _show_parser("CHARACTER SET"),
351            "COLLATION": _show_parser("COLLATION"),
352            "FULL COLUMNS": _show_parser("COLUMNS", target="FROM", full=True),
353            "COLUMNS": _show_parser("COLUMNS", target="FROM"),
354            "CREATE DATABASE": _show_parser("CREATE DATABASE", target=True),
355            "CREATE EVENT": _show_parser("CREATE EVENT", target=True),
356            "CREATE FUNCTION": _show_parser("CREATE FUNCTION", target=True),
357            "CREATE PROCEDURE": _show_parser("CREATE PROCEDURE", target=True),
358            "CREATE TABLE": _show_parser("CREATE TABLE", target=True),
359            "CREATE TRIGGER": _show_parser("CREATE TRIGGER", target=True),
360            "CREATE VIEW": _show_parser("CREATE VIEW", target=True),
361            "DATABASES": _show_parser("DATABASES"),
362            "SCHEMAS": _show_parser("DATABASES"),
363            "ENGINE": _show_parser("ENGINE", target=True),
364            "STORAGE ENGINES": _show_parser("ENGINES"),
365            "ENGINES": _show_parser("ENGINES"),
366            "ERRORS": _show_parser("ERRORS"),
367            "EVENTS": _show_parser("EVENTS"),
368            "FUNCTION CODE": _show_parser("FUNCTION CODE", target=True),
369            "FUNCTION STATUS": _show_parser("FUNCTION STATUS"),
370            "GRANTS": _show_parser("GRANTS", target="FOR"),
371            "INDEX": _show_parser("INDEX", target="FROM"),
372            "MASTER STATUS": _show_parser("MASTER STATUS"),
373            "OPEN TABLES": _show_parser("OPEN TABLES"),
374            "PLUGINS": _show_parser("PLUGINS"),
375            "PROCEDURE CODE": _show_parser("PROCEDURE CODE", target=True),
376            "PROCEDURE STATUS": _show_parser("PROCEDURE STATUS"),
377            "PRIVILEGES": _show_parser("PRIVILEGES"),
378            "FULL PROCESSLIST": _show_parser("PROCESSLIST", full=True),
379            "PROCESSLIST": _show_parser("PROCESSLIST"),
380            "PROFILE": _show_parser("PROFILE"),
381            "PROFILES": _show_parser("PROFILES"),
382            "RELAYLOG EVENTS": _show_parser("RELAYLOG EVENTS"),
383            "REPLICAS": _show_parser("REPLICAS"),
384            "SLAVE HOSTS": _show_parser("REPLICAS"),
385            "REPLICA STATUS": _show_parser("REPLICA STATUS"),
386            "SLAVE STATUS": _show_parser("REPLICA STATUS"),
387            "GLOBAL STATUS": _show_parser("STATUS", global_=True),
388            "SESSION STATUS": _show_parser("STATUS"),
389            "STATUS": _show_parser("STATUS"),
390            "TABLE STATUS": _show_parser("TABLE STATUS"),
391            "FULL TABLES": _show_parser("TABLES", full=True),
392            "TABLES": _show_parser("TABLES"),
393            "TRIGGERS": _show_parser("TRIGGERS"),
394            "GLOBAL VARIABLES": _show_parser("VARIABLES", global_=True),
395            "SESSION VARIABLES": _show_parser("VARIABLES"),
396            "VARIABLES": _show_parser("VARIABLES"),
397            "WARNINGS": _show_parser("WARNINGS"),
398        }
399
400        PROPERTY_PARSERS = {
401            **parser.Parser.PROPERTY_PARSERS,
402            "LOCK": lambda self: self._parse_property_assignment(exp.LockProperty),
403        }
404
405        SET_PARSERS = {
406            **parser.Parser.SET_PARSERS,
407            "PERSIST": lambda self: self._parse_set_item_assignment("PERSIST"),
408            "PERSIST_ONLY": lambda self: self._parse_set_item_assignment("PERSIST_ONLY"),
409            "CHARACTER SET": lambda self: self._parse_set_item_charset("CHARACTER SET"),
410            "CHARSET": lambda self: self._parse_set_item_charset("CHARACTER SET"),
411            "NAMES": lambda self: self._parse_set_item_names(),
412        }
413
414        CONSTRAINT_PARSERS = {
415            **parser.Parser.CONSTRAINT_PARSERS,
416            "FULLTEXT": lambda self: self._parse_index_constraint(kind="FULLTEXT"),
417            "INDEX": lambda self: self._parse_index_constraint(),
418            "KEY": lambda self: self._parse_index_constraint(),
419            "SPATIAL": lambda self: self._parse_index_constraint(kind="SPATIAL"),
420        }
421
422        ALTER_PARSERS = {
423            **parser.Parser.ALTER_PARSERS,
424            "MODIFY": lambda self: self._parse_alter_table_alter(),
425        }
426
427        SCHEMA_UNNAMED_CONSTRAINTS = {
428            *parser.Parser.SCHEMA_UNNAMED_CONSTRAINTS,
429            "FULLTEXT",
430            "INDEX",
431            "KEY",
432            "SPATIAL",
433        }
434
435        PROFILE_TYPES: parser.OPTIONS_TYPE = {
436            **dict.fromkeys(("ALL", "CPU", "IPC", "MEMORY", "SOURCE", "SWAPS"), tuple()),
437            "BLOCK": ("IO",),
438            "CONTEXT": ("SWITCHES",),
439            "PAGE": ("FAULTS",),
440        }
441
442        TYPE_TOKENS = {
443            *parser.Parser.TYPE_TOKENS,
444            TokenType.SET,
445        }
446
447        ENUM_TYPE_TOKENS = {
448            *parser.Parser.ENUM_TYPE_TOKENS,
449            TokenType.SET,
450        }
451
452        LOG_DEFAULTS_TO_LN = True
453        STRING_ALIASES = True
454        VALUES_FOLLOWED_BY_PAREN = False
455        SUPPORTS_PARTITION_SELECTION = True
456
457        def _parse_primary_key_part(self) -> t.Optional[exp.Expression]:
458            this = self._parse_id_var()
459            if not self._match(TokenType.L_PAREN):
460                return this
461
462            expression = self._parse_number()
463            self._match_r_paren()
464            return self.expression(exp.ColumnPrefix, this=this, expression=expression)
465
466        def _parse_index_constraint(
467            self, kind: t.Optional[str] = None
468        ) -> exp.IndexColumnConstraint:
469            if kind:
470                self._match_texts(("INDEX", "KEY"))
471
472            this = self._parse_id_var(any_token=False)
473            index_type = self._match(TokenType.USING) and self._advance_any() and self._prev.text
474            expressions = self._parse_wrapped_csv(self._parse_ordered)
475
476            options = []
477            while True:
478                if self._match_text_seq("KEY_BLOCK_SIZE"):
479                    self._match(TokenType.EQ)
480                    opt = exp.IndexConstraintOption(key_block_size=self._parse_number())
481                elif self._match(TokenType.USING):
482                    opt = exp.IndexConstraintOption(using=self._advance_any() and self._prev.text)
483                elif self._match_text_seq("WITH", "PARSER"):
484                    opt = exp.IndexConstraintOption(parser=self._parse_var(any_token=True))
485                elif self._match(TokenType.COMMENT):
486                    opt = exp.IndexConstraintOption(comment=self._parse_string())
487                elif self._match_text_seq("VISIBLE"):
488                    opt = exp.IndexConstraintOption(visible=True)
489                elif self._match_text_seq("INVISIBLE"):
490                    opt = exp.IndexConstraintOption(visible=False)
491                elif self._match_text_seq("ENGINE_ATTRIBUTE"):
492                    self._match(TokenType.EQ)
493                    opt = exp.IndexConstraintOption(engine_attr=self._parse_string())
494                elif self._match_text_seq("SECONDARY_ENGINE_ATTRIBUTE"):
495                    self._match(TokenType.EQ)
496                    opt = exp.IndexConstraintOption(secondary_engine_attr=self._parse_string())
497                else:
498                    opt = None
499
500                if not opt:
501                    break
502
503                options.append(opt)
504
505            return self.expression(
506                exp.IndexColumnConstraint,
507                this=this,
508                expressions=expressions,
509                kind=kind,
510                index_type=index_type,
511                options=options,
512            )
513
514        def _parse_show_mysql(
515            self,
516            this: str,
517            target: bool | str = False,
518            full: t.Optional[bool] = None,
519            global_: t.Optional[bool] = None,
520        ) -> exp.Show:
521            if target:
522                if isinstance(target, str):
523                    self._match_text_seq(target)
524                target_id = self._parse_id_var()
525            else:
526                target_id = None
527
528            log = self._parse_string() if self._match_text_seq("IN") else None
529
530            if this in ("BINLOG EVENTS", "RELAYLOG EVENTS"):
531                position = self._parse_number() if self._match_text_seq("FROM") else None
532                db = None
533            else:
534                position = None
535                db = None
536
537                if self._match(TokenType.FROM):
538                    db = self._parse_id_var()
539                elif self._match(TokenType.DOT):
540                    db = target_id
541                    target_id = self._parse_id_var()
542
543            channel = self._parse_id_var() if self._match_text_seq("FOR", "CHANNEL") else None
544
545            like = self._parse_string() if self._match_text_seq("LIKE") else None
546            where = self._parse_where()
547
548            if this == "PROFILE":
549                types = self._parse_csv(lambda: self._parse_var_from_options(self.PROFILE_TYPES))
550                query = self._parse_number() if self._match_text_seq("FOR", "QUERY") else None
551                offset = self._parse_number() if self._match_text_seq("OFFSET") else None
552                limit = self._parse_number() if self._match_text_seq("LIMIT") else None
553            else:
554                types, query = None, None
555                offset, limit = self._parse_oldstyle_limit()
556
557            mutex = True if self._match_text_seq("MUTEX") else None
558            mutex = False if self._match_text_seq("STATUS") else mutex
559
560            return self.expression(
561                exp.Show,
562                this=this,
563                target=target_id,
564                full=full,
565                log=log,
566                position=position,
567                db=db,
568                channel=channel,
569                like=like,
570                where=where,
571                types=types,
572                query=query,
573                offset=offset,
574                limit=limit,
575                mutex=mutex,
576                **{"global": global_},  # type: ignore
577            )
578
579        def _parse_oldstyle_limit(
580            self,
581        ) -> t.Tuple[t.Optional[exp.Expression], t.Optional[exp.Expression]]:
582            limit = None
583            offset = None
584            if self._match_text_seq("LIMIT"):
585                parts = self._parse_csv(self._parse_number)
586                if len(parts) == 1:
587                    limit = parts[0]
588                elif len(parts) == 2:
589                    limit = parts[1]
590                    offset = parts[0]
591
592            return offset, limit
593
594        def _parse_set_item_charset(self, kind: str) -> exp.Expression:
595            this = self._parse_string() or self._parse_unquoted_field()
596            return self.expression(exp.SetItem, this=this, kind=kind)
597
598        def _parse_set_item_names(self) -> exp.Expression:
599            charset = self._parse_string() or self._parse_unquoted_field()
600            if self._match_text_seq("COLLATE"):
601                collate = self._parse_string() or self._parse_unquoted_field()
602            else:
603                collate = None
604
605            return self.expression(exp.SetItem, this=charset, collate=collate, kind="NAMES")
606
607        def _parse_type(
608            self, parse_interval: bool = True, fallback_to_identifier: bool = False
609        ) -> t.Optional[exp.Expression]:
610            # mysql binary is special and can work anywhere, even in order by operations
611            # it operates like a no paren func
612            if self._match(TokenType.BINARY, advance=False):
613                data_type = self._parse_types(check_func=True, allow_identifiers=False)
614
615                if isinstance(data_type, exp.DataType):
616                    return self.expression(exp.Cast, this=self._parse_column(), to=data_type)
617
618            return super()._parse_type(
619                parse_interval=parse_interval, fallback_to_identifier=fallback_to_identifier
620            )
621
622        def _parse_chr(self) -> t.Optional[exp.Expression]:
623            expressions = self._parse_csv(self._parse_assignment)
624            kwargs: t.Dict[str, t.Any] = {"this": seq_get(expressions, 0)}
625
626            if len(expressions) > 1:
627                kwargs["expressions"] = expressions[1:]
628
629            if self._match(TokenType.USING):
630                kwargs["charset"] = self._parse_var()
631
632            return self.expression(exp.Chr, **kwargs)
633
634        def _parse_group_concat(self) -> t.Optional[exp.Expression]:
635            def concat_exprs(
636                node: t.Optional[exp.Expression], exprs: t.List[exp.Expression]
637            ) -> exp.Expression:
638                if isinstance(node, exp.Distinct) and len(node.expressions) > 1:
639                    concat_exprs = [
640                        self.expression(exp.Concat, expressions=node.expressions, safe=True)
641                    ]
642                    node.set("expressions", concat_exprs)
643                    return node
644                if len(exprs) == 1:
645                    return exprs[0]
646                return self.expression(exp.Concat, expressions=args, safe=True)
647
648            args = self._parse_csv(self._parse_lambda)
649
650            if args:
651                order = args[-1] if isinstance(args[-1], exp.Order) else None
652
653                if order:
654                    # Order By is the last (or only) expression in the list and has consumed the 'expr' before it,
655                    # remove 'expr' from exp.Order and add it back to args
656                    args[-1] = order.this
657                    order.set("this", concat_exprs(order.this, args))
658
659                this = order or concat_exprs(args[0], args)
660            else:
661                this = None
662
663            separator = self._parse_field() if self._match(TokenType.SEPARATOR) else None
664
665            return self.expression(exp.GroupConcat, this=this, separator=separator)

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.UMEDIUMINT: 'UMEDIUMINT'>, <TokenType.GEOGRAPHY: 'GEOGRAPHY'>, <TokenType.IPV6: 'IPV6'>, <TokenType.BIT: 'BIT'>, <TokenType.PSEUDO_TYPE: 'PSEUDO_TYPE'>, <TokenType.IMAGE: 'IMAGE'>, <TokenType.DATEMULTIRANGE: 'DATEMULTIRANGE'>, <TokenType.ENUM: 'ENUM'>, <TokenType.UDECIMAL: 'UDECIMAL'>, <TokenType.TIMESTAMPTZ: 'TIMESTAMPTZ'>, <TokenType.ENUM8: 'ENUM8'>, <TokenType.MEDIUMINT: 'MEDIUMINT'>, <TokenType.SOME: 'SOME'>, <TokenType.DOUBLE: 'DOUBLE'>, <TokenType.INDEX: 'INDEX'>, <TokenType.CURRENT_TIME: 'CURRENT_TIME'>, <TokenType.FLOAT: 'FLOAT'>, <TokenType.USMALLINT: 'USMALLINT'>, <TokenType.UINT128: 'UINT128'>, <TokenType.VAR: 'VAR'>, <TokenType.TIMESTAMP_MS: 'TIMESTAMP_MS'>, <TokenType.LIST: 'LIST'>, <TokenType.UUID: 'UUID'>, <TokenType.JSON: 'JSON'>, <TokenType.COLLATE: 'COLLATE'>, <TokenType.BINARY: 'BINARY'>, <TokenType.BIGDECIMAL: 'BIGDECIMAL'>, <TokenType.SERIAL: 'SERIAL'>, <TokenType.OBJECT: 'OBJECT'>, <TokenType.VARIANT: 'VARIANT'>, <TokenType.FIRST: 'FIRST'>, <TokenType.LEFT: 'LEFT'>, <TokenType.VARCHAR: 'VARCHAR'>, <TokenType.RANGE: 'RANGE'>, <TokenType.ILIKE: 'ILIKE'>, <TokenType.TABLE: 'TABLE'>, <TokenType.TINYBLOB: 'TINYBLOB'>, <TokenType.IPPREFIX: 'IPPREFIX'>, <TokenType.BIGINT: 'BIGINT'>, <TokenType.LOWCARDINALITY: 'LOWCARDINALITY'>, <TokenType.INT8MULTIRANGE: 'INT8MULTIRANGE'>, <TokenType.CHAR: 'CHAR'>, <TokenType.ENUM16: 'ENUM16'>, <TokenType.YEAR: 'YEAR'>, <TokenType.TIMESTAMP_S: 'TIMESTAMP_S'>, <TokenType.CURRENT_DATE: 'CURRENT_DATE'>, <TokenType.NESTED: 'NESTED'>, <TokenType.INT4RANGE: 'INT4RANGE'>, <TokenType.JSONB: 'JSONB'>, <TokenType.GEOMETRY: 'GEOMETRY'>, <TokenType.HLLSKETCH: 'HLLSKETCH'>, <TokenType.GLOB: 'GLOB'>, <TokenType.ANY: 'ANY'>, <TokenType.INT: 'INT'>, <TokenType.INSERT: 'INSERT'>, <TokenType.USERDEFINED: 'USERDEFINED'>, <TokenType.TSRANGE: 'TSRANGE'>, <TokenType.TIMESTAMPNTZ: 'TIMESTAMPNTZ'>, <TokenType.DATETIME64: 'DATETIME64'>, <TokenType.UNKNOWN: 'UNKNOWN'>, <TokenType.MEDIUMTEXT: 'MEDIUMTEXT'>, <TokenType.MAP: 'MAP'>, <TokenType.FILTER: 'FILTER'>, <TokenType.AGGREGATEFUNCTION: 'AGGREGATEFUNCTION'>, <TokenType.UINT256: 'UINT256'>, <TokenType.BPCHAR: 'BPCHAR'>, <TokenType.TSTZMULTIRANGE: 'TSTZMULTIRANGE'>, <TokenType.SUPER: 'SUPER'>, <TokenType.RIGHT: 'RIGHT'>, <TokenType.SCHEMA: 'SCHEMA'>, <TokenType.EXISTS: 'EXISTS'>, <TokenType.TDIGEST: 'TDIGEST'>, <TokenType.COMMAND: 'COMMAND'>, <TokenType.DATETIME: 'DATETIME'>, <TokenType.NVARCHAR: 'NVARCHAR'>, <TokenType.REPLACE: 'REPLACE'>, <TokenType.CURRENT_TIMESTAMP: 'CURRENT_TIMESTAMP'>, <TokenType.FIXEDSTRING: 'FIXEDSTRING'>, <TokenType.MEDIUMBLOB: 'MEDIUMBLOB'>, <TokenType.UNNEST: 'UNNEST'>, <TokenType.TIME: 'TIME'>, <TokenType.NULLABLE: 'NULLABLE'>, <TokenType.UINT: 'UINT'>, <TokenType.SMALLSERIAL: 'SMALLSERIAL'>, <TokenType.LIKE: 'LIKE'>, <TokenType.INT8RANGE: 'INT8RANGE'>, <TokenType.TIMESTAMP: 'TIMESTAMP'>, <TokenType.RLIKE: 'RLIKE'>, <TokenType.INT128: 'INT128'>, <TokenType.CURRENT_DATETIME: 'CURRENT_DATETIME'>, <TokenType.BIGSERIAL: 'BIGSERIAL'>, <TokenType.VECTOR: 'VECTOR'>, <TokenType.HSTORE: 'HSTORE'>, <TokenType.OFFSET: 'OFFSET'>, <TokenType.STRUCT: 'STRUCT'>, <TokenType.INT256: 'INT256'>, <TokenType.MERGE: 'MERGE'>, <TokenType.UTINYINT: 'UTINYINT'>, <TokenType.NAME: 'NAME'>, <TokenType.INTERVAL: 'INTERVAL'>, <TokenType.MONEY: 'MONEY'>, <TokenType.NCHAR: 'NCHAR'>, <TokenType.XML: 'XML'>, <TokenType.NUMMULTIRANGE: 'NUMMULTIRANGE'>, <TokenType.VALUES: 'VALUES'>, <TokenType.OBJECT_IDENTIFIER: 'OBJECT_IDENTIFIER'>, <TokenType.DATE: 'DATE'>, <TokenType.LONGBLOB: 'LONGBLOB'>, <TokenType.BOOLEAN: 'BOOLEAN'>, <TokenType.NUMRANGE: 'NUMRANGE'>, <TokenType.SMALLMONEY: 'SMALLMONEY'>, <TokenType.UBIGINT: 'UBIGINT'>, <TokenType.NULL: 'NULL'>, <TokenType.TSTZRANGE: 'TSTZRANGE'>, <TokenType.IPV4: 'IPV4'>, <TokenType.TIMETZ: 'TIMETZ'>, <TokenType.LONGTEXT: 'LONGTEXT'>, <TokenType.SMALLINT: 'SMALLINT'>, <TokenType.XOR: 'XOR'>, <TokenType.ARRAY: 'ARRAY'>, <TokenType.UNIQUEIDENTIFIER: 'UNIQUEIDENTIFIER'>, <TokenType.ROWVERSION: 'ROWVERSION'>, <TokenType.TEXT: 'TEXT'>, <TokenType.TINYTEXT: 'TINYTEXT'>, <TokenType.TINYINT: 'TINYINT'>, <TokenType.ROW: 'ROW'>, <TokenType.ISNULL: 'ISNULL'>, <TokenType.VARBINARY: 'VARBINARY'>, <TokenType.TSMULTIRANGE: 'TSMULTIRANGE'>, <TokenType.DATE32: 'DATE32'>, <TokenType.DATABASE: 'DATABASE'>, <TokenType.ALL: 'ALL'>, <TokenType.WINDOW: 'WINDOW'>, <TokenType.INET: 'INET'>, <TokenType.INT4MULTIRANGE: 'INT4MULTIRANGE'>, <TokenType.SEQUENCE: 'SEQUENCE'>, <TokenType.IPADDRESS: 'IPADDRESS'>, <TokenType.DECIMAL: 'DECIMAL'>, <TokenType.DATERANGE: 'DATERANGE'>, <TokenType.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, <TokenType.TIMESTAMP_NS: 'TIMESTAMP_NS'>, <TokenType.SIMPLEAGGREGATEFUNCTION: 'SIMPLEAGGREGATEFUNCTION'>, <TokenType.IDENTIFIER: 'IDENTIFIER'>, <TokenType.FORMAT: 'FORMAT'>, <TokenType.CURRENT_USER: 'CURRENT_USER'>, <TokenType.TRUNCATE: 'TRUNCATE'>, <TokenType.PRIMARY_KEY: 'PRIMARY_KEY'>}
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.UPDATE: 'UPDATE'>, <TokenType.UMEDIUMINT: 'UMEDIUMINT'>, <TokenType.GEOGRAPHY: 'GEOGRAPHY'>, <TokenType.IPV6: 'IPV6'>, <TokenType.BIT: 'BIT'>, <TokenType.VIEW: 'VIEW'>, <TokenType.PSEUDO_TYPE: 'PSEUDO_TYPE'>, <TokenType.EXECUTE: 'EXECUTE'>, <TokenType.IMAGE: 'IMAGE'>, <TokenType.TOP: 'TOP'>, <TokenType.STORAGE_INTEGRATION: 'STORAGE_INTEGRATION'>, <TokenType.DATEMULTIRANGE: 'DATEMULTIRANGE'>, <TokenType.ENUM: 'ENUM'>, <TokenType.UDECIMAL: 'UDECIMAL'>, <TokenType.TIMESTAMPTZ: 'TIMESTAMPTZ'>, <TokenType.ENUM8: 'ENUM8'>, <TokenType.FALSE: 'FALSE'>, <TokenType.MEDIUMINT: 'MEDIUMINT'>, <TokenType.SOME: 'SOME'>, <TokenType.DOUBLE: 'DOUBLE'>, <TokenType.INDEX: 'INDEX'>, <TokenType.CURRENT_TIME: 'CURRENT_TIME'>, <TokenType.PRAGMA: 'PRAGMA'>, <TokenType.RECURSIVE: 'RECURSIVE'>, <TokenType.FLOAT: 'FLOAT'>, <TokenType.USMALLINT: 'USMALLINT'>, <TokenType.UINT128: 'UINT128'>, <TokenType.VAR: 'VAR'>, <TokenType.TIMESTAMP_MS: 'TIMESTAMP_MS'>, <TokenType.BEGIN: 'BEGIN'>, <TokenType.CONSTRAINT: 'CONSTRAINT'>, <TokenType.PIVOT: 'PIVOT'>, <TokenType.LIST: 'LIST'>, <TokenType.UUID: 'UUID'>, <TokenType.JSON: 'JSON'>, <TokenType.COLLATE: 'COLLATE'>, <TokenType.OVERWRITE: 'OVERWRITE'>, <TokenType.BINARY: 'BINARY'>, <TokenType.BIGDECIMAL: 'BIGDECIMAL'>, <TokenType.SERIAL: 'SERIAL'>, <TokenType.MODEL: 'MODEL'>, <TokenType.REFRESH: 'REFRESH'>, <TokenType.OBJECT: 'OBJECT'>, <TokenType.UNIQUE: 'UNIQUE'>, <TokenType.COPY: 'COPY'>, <TokenType.FIRST: 'FIRST'>, <TokenType.VARIANT: 'VARIANT'>, <TokenType.VARCHAR: 'VARCHAR'>, <TokenType.RANGE: 'RANGE'>, <TokenType.TABLE: 'TABLE'>, <TokenType.KEEP: 'KEEP'>, <TokenType.TAG: 'TAG'>, <TokenType.TINYBLOB: 'TINYBLOB'>, <TokenType.SEMI: 'SEMI'>, <TokenType.IPPREFIX: 'IPPREFIX'>, <TokenType.ORDINALITY: 'ORDINALITY'>, <TokenType.BIGINT: 'BIGINT'>, <TokenType.LOWCARDINALITY: 'LOWCARDINALITY'>, <TokenType.FUNCTION: 'FUNCTION'>, <TokenType.INT8MULTIRANGE: 'INT8MULTIRANGE'>, <TokenType.CHAR: 'CHAR'>, <TokenType.ENUM16: 'ENUM16'>, <TokenType.YEAR: 'YEAR'>, <TokenType.TIMESTAMP_S: 'TIMESTAMP_S'>, <TokenType.NESTED: 'NESTED'>, <TokenType.CURRENT_DATE: 'CURRENT_DATE'>, <TokenType.TEMPORARY: 'TEMPORARY'>, <TokenType.NEXT: 'NEXT'>, <TokenType.INT4RANGE: 'INT4RANGE'>, <TokenType.END: 'END'>, <TokenType.JSONB: 'JSONB'>, <TokenType.GEOMETRY: 'GEOMETRY'>, <TokenType.HLLSKETCH: 'HLLSKETCH'>, <TokenType.AUTO_INCREMENT: 'AUTO_INCREMENT'>, <TokenType.ANY: 'ANY'>, <TokenType.INT: 'INT'>, <TokenType.USERDEFINED: 'USERDEFINED'>, <TokenType.TSRANGE: 'TSRANGE'>, <TokenType.TIMESTAMPNTZ: 'TIMESTAMPNTZ'>, <TokenType.DATETIME64: 'DATETIME64'>, <TokenType.UNKNOWN: 'UNKNOWN'>, <TokenType.MEDIUMTEXT: 'MEDIUMTEXT'>, <TokenType.MAP: 'MAP'>, <TokenType.FILTER: 'FILTER'>, <TokenType.AGGREGATEFUNCTION: 'AGGREGATEFUNCTION'>, <TokenType.ASC: 'ASC'>, <TokenType.REFERENCES: 'REFERENCES'>, <TokenType.UINT256: 'UINT256'>, <TokenType.BPCHAR: 'BPCHAR'>, <TokenType.TSTZMULTIRANGE: 'TSTZMULTIRANGE'>, <TokenType.SUPER: 'SUPER'>, <TokenType.PERCENT: 'PERCENT'>, <TokenType.DESCRIBE: 'DESCRIBE'>, <TokenType.SCHEMA: 'SCHEMA'>, <TokenType.EXISTS: 'EXISTS'>, <TokenType.IS: 'IS'>, <TokenType.TDIGEST: 'TDIGEST'>, <TokenType.COMMAND: 'COMMAND'>, <TokenType.DATETIME: 'DATETIME'>, <TokenType.NVARCHAR: 'NVARCHAR'>, <TokenType.REPLACE: 'REPLACE'>, <TokenType.KILL: 'KILL'>, <TokenType.FIXEDSTRING: 'FIXEDSTRING'>, <TokenType.MEDIUMBLOB: 'MEDIUMBLOB'>, <TokenType.UNNEST: 'UNNEST'>, <TokenType.TIME: 'TIME'>, <TokenType.COLUMN: 'COLUMN'>, <TokenType.NULLABLE: 'NULLABLE'>, <TokenType.FINAL: 'FINAL'>, <TokenType.UINT: 'UINT'>, <TokenType.CURRENT_TIMESTAMP: 'CURRENT_TIMESTAMP'>, <TokenType.PROCEDURE: 'PROCEDURE'>, <TokenType.SMALLSERIAL: 'SMALLSERIAL'>, <TokenType.INT8RANGE: 'INT8RANGE'>, <TokenType.TIMESTAMP: 'TIMESTAMP'>, <TokenType.OVERLAPS: 'OVERLAPS'>, <TokenType.INT128: 'INT128'>, <TokenType.STREAMLIT: 'STREAMLIT'>, <TokenType.BIGSERIAL: 'BIGSERIAL'>, <TokenType.VECTOR: 'VECTOR'>, <TokenType.CURRENT_DATETIME: 'CURRENT_DATETIME'>, <TokenType.HSTORE: 'HSTORE'>, <TokenType.OPERATOR: 'OPERATOR'>, <TokenType.ROWS: 'ROWS'>, <TokenType.STRUCT: 'STRUCT'>, <TokenType.INT256: 'INT256'>, <TokenType.MERGE: 'MERGE'>, <TokenType.LOAD: 'LOAD'>, <TokenType.FOREIGN_KEY: 'FOREIGN_KEY'>, <TokenType.UTINYINT: 'UTINYINT'>, <TokenType.NAME: 'NAME'>, <TokenType.INTERVAL: 'INTERVAL'>, <TokenType.ROLLUP: 'ROLLUP'>, <TokenType.MONEY: 'MONEY'>, <TokenType.NCHAR: 'NCHAR'>, <TokenType.WAREHOUSE: 'WAREHOUSE'>, <TokenType.XML: 'XML'>, <TokenType.COMMENT: 'COMMENT'>, <TokenType.DIV: 'DIV'>, <TokenType.NUMMULTIRANGE: 'NUMMULTIRANGE'>, <TokenType.OBJECT_IDENTIFIER: 'OBJECT_IDENTIFIER'>, <TokenType.DATE: 'DATE'>, <TokenType.LONGBLOB: 'LONGBLOB'>, <TokenType.BOOLEAN: 'BOOLEAN'>, <TokenType.NUMRANGE: 'NUMRANGE'>, <TokenType.PARTITION: 'PARTITION'>, <TokenType.CASE: 'CASE'>, <TokenType.SMALLMONEY: 'SMALLMONEY'>, <TokenType.UBIGINT: 'UBIGINT'>, <TokenType.NULL: 'NULL'>, <TokenType.TSTZRANGE: 'TSTZRANGE'>, <TokenType.IPV4: 'IPV4'>, <TokenType.ANTI: 'ANTI'>, <TokenType.DEFAULT: 'DEFAULT'>, <TokenType.TIMETZ: 'TIMETZ'>, <TokenType.ESCAPE: 'ESCAPE'>, <TokenType.LONGTEXT: 'LONGTEXT'>, <TokenType.SMALLINT: 'SMALLINT'>, <TokenType.ARRAY: 'ARRAY'>, <TokenType.UNIQUEIDENTIFIER: 'UNIQUEIDENTIFIER'>, <TokenType.ROWVERSION: 'ROWVERSION'>, <TokenType.TEXT: 'TEXT'>, <TokenType.DESC: 'DESC'>, <TokenType.DELETE: 'DELETE'>, <TokenType.TINYTEXT: 'TINYTEXT'>, <TokenType.COMMIT: 'COMMIT'>, <TokenType.TINYINT: 'TINYINT'>, <TokenType.ROW: 'ROW'>, <TokenType.ISNULL: 'ISNULL'>, <TokenType.VARBINARY: 'VARBINARY'>, <TokenType.TSMULTIRANGE: 'TSMULTIRANGE'>, <TokenType.DATE32: 'DATE32'>, <TokenType.DATABASE: 'DATABASE'>, <TokenType.ALL: 'ALL'>, <TokenType.INET: 'INET'>, <TokenType.INT4MULTIRANGE: 'INT4MULTIRANGE'>, <TokenType.CUBE: 'CUBE'>, <TokenType.SET: 'SET'>, <TokenType.SEQUENCE: 'SEQUENCE'>, <TokenType.SHOW: 'SHOW'>, <TokenType.IPADDRESS: 'IPADDRESS'>, <TokenType.CACHE: 'CACHE'>, <TokenType.UNPIVOT: 'UNPIVOT'>, <TokenType.DECIMAL: 'DECIMAL'>, <TokenType.DATERANGE: 'DATERANGE'>, <TokenType.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, <TokenType.TIMESTAMP_NS: 'TIMESTAMP_NS'>, <TokenType.TRUE: 'TRUE'>, <TokenType.SIMPLEAGGREGATEFUNCTION: 'SIMPLEAGGREGATEFUNCTION'>, <TokenType.IDENTIFIER: 'IDENTIFIER'>, <TokenType.FORMAT: 'FORMAT'>, <TokenType.DICTIONARY: 'DICTIONARY'>, <TokenType.CURRENT_USER: 'CURRENT_USER'>, <TokenType.TRUNCATE: 'TRUNCATE'>, <TokenType.RENAME: 'RENAME'>, <TokenType.SETTINGS: 'SETTINGS'>, <TokenType.VOLATILE: 'VOLATILE'>}
RANGE_PARSERS = {<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.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.MEMBER_OF: 'MEMBER_OF'>: <function MySQL.Parser.<lambda>>}
FUNCTIONS = {'ABS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Abs'>>, 'ADD_MONTHS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.AddMonths'>>, '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'>>, '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_QUANTILE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ApproxQuantile'>>, 'APPROX_TOP_K': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ApproxTopK'>>, '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': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArrayAgg'>>, '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_CONCAT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArrayConcat'>>, 'ARRAY_CAT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArrayConcat'>>, '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_OVERLAPS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArrayOverlaps'>>, '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_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'>>, 'AVG': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Avg'>>, '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'>>, '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 Parser.<lambda>>, 'IFNULL': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Coalesce'>>, 'NVL': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Coalesce'>>, 'COLLATE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Collate'>>, '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'>>, 'CONCAT': <function Parser.<lambda>>, 'CONCAT_WS': <function Parser.<lambda>>, 'CONNECT_BY_ROOT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ConnectByRoot'>>, 'CONVERT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Convert'>>, 'CONVERT_TIMEZONE': <function build_convert_timezone>, 'CORR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Corr'>>, 'COUNT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Count'>>, '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'>>, '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_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_USER': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CurrentUser'>>, 'DATE': <function MySQL.Parser.<lambda>>, 'DATE_ADD': <function build_date_delta_with_interval.<locals>._builder>, '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_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>>, 'DAY_OF_YEAR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DayOfYear'>>, 'DAYOFYEAR': <function MySQL.Parser.<lambda>>, 'DECODE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Decode'>>, 'DI_TO_DATE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DiToDate'>>, 'ENCODE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Encode'>>, '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'>>, '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'>>, 'FLOOR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Floor'>>, 'FROM_BASE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.FromBase'>>, '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_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'>>, 'GREATEST': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Greatest'>>, 'GROUP_CONCAT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.GroupConcat'>>, 'HEX': <function build_hex>, 'HLL': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Hll'>>, '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'>>, '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'>>, '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_CONTAINS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONArrayContains'>>, 'JSONB_CONTAINS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONBContains'>>, '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'>>, 'JSON_EXTRACT': <function build_extract_json_with_path.<locals>._builder>, 'JSON_EXTRACT_SCALAR': <function build_extract_json_with_path.<locals>._builder>, 'JSON_FORMAT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONFormat'>>, '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'>>, 'J_S_O_N_TABLE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONTable'>>, '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'>>, 'LEAD': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Lead'>>, 'LEAST': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Least'>>, 'LEFT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Left'>>, 'LENGTH': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Length'>>, 'LEN': <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'>>, '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'>>, 'MAP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Map'>>, 'MAP_FROM_ENTRIES': <bound method Func.from_arg_list of <class 'sqlglot.expressions.MapFromEntries'>>, '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'>>, 'MIN': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Min'>>, 'MONTH': <function MySQL.Parser.<lambda>>, 'MONTHS_BETWEEN': <bound method Func.from_arg_list of <class 'sqlglot.expressions.MonthsBetween'>>, 'NEXT_VALUE_FOR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.NextValueFor'>>, 'NTH_VALUE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.NthValue'>>, '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_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'>>, '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_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'>>, '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'>>, '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'>>, 'QUANTILE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Quantile'>>, 'QUARTER': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Quarter'>>, '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'>>, 'RANGE_N': <bound method Func.from_arg_list of <class 'sqlglot.expressions.RangeN'>>, 'READ_CSV': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ReadCSV'>>, 'REDUCE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Reduce'>>, 'REGEXP_EXTRACT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.RegexpExtract'>>, 'REGEXP_I_LIKE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.RegexpILike'>>, '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'>>, 'REPEAT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Repeat'>>, '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'>>, 'SHA': <bound method Func.from_arg_list of <class 'sqlglot.expressions.SHA'>>, 'SHA1': <bound method Func.from_arg_list of <class 'sqlglot.expressions.SHA'>>, 'SHA2': <bound method Func.from_arg_list of <class 'sqlglot.expressions.SHA2'>>, 'SAFE_DIVIDE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.SafeDivide'>>, 'SIGN': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Sign'>>, 'SIGNUM': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Sign'>>, 'SORT_ARRAY': <bound method Func.from_arg_list of <class 'sqlglot.expressions.SortArray'>>, 'SPLIT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Split'>>, 'SQRT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Sqrt'>>, '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_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'>>, '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'>>, 'SUM': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Sum'>>, '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_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_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'>>, 'TO_ARRAY': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ToArray'>>, 'TO_BASE64': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ToBase64'>>, 'TO_CHAR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ToChar'>>, 'TO_DAYS': <function MySQL.Parser.<lambda>>, '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'>>, '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_CAST': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TryCast'>>, '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_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'>>, 'UNHEX': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Unhex'>>, 'UNIX_DATE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.UnixDate'>>, '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'>>, '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'>>, 'WEEK': <function MySQL.Parser.<lambda>>, 'WEEK_OF_YEAR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.WeekOfYear'>>, 'WEEKOFYEAR': <function MySQL.Parser.<lambda>>, 'WHEN': <bound method Func.from_arg_list of <class 'sqlglot.expressions.When'>>, '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>>, '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>>, 'TO_HEX': <function build_hex>, 'CONVERT_TZ': <function MySQL.Parser.<lambda>>, 'DATE_FORMAT': <function build_formatted_time.<locals>._builder>, 'INSTR': <function MySQL.Parser.<lambda>>, 'FROM_UNIXTIME': <function build_formatted_time.<locals>._builder>, 'ISNULL': <function isnull_to_is_null>, 'LOCATE': <function locate_to_strposition>, 'MAKETIME': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimeFromParts'>>, 'MONTHNAME': <function MySQL.Parser.<lambda>>}
FUNCTION_PARSERS = {'CAST': <function Parser.<lambda>>, 'CONVERT': <function Parser.<lambda>>, 'DECODE': <function Parser.<lambda>>, 'EXTRACT': <function Parser.<lambda>>, 'GAP_FILL': <function Parser.<lambda>>, 'JSON_OBJECT': <function Parser.<lambda>>, 'JSON_OBJECTAGG': <function Parser.<lambda>>, 'JSON_TABLE': <function Parser.<lambda>>, 'MATCH': <function Parser.<lambda>>, 'OPENJSON': <function Parser.<lambda>>, 'POSITION': <function Parser.<lambda>>, 'PREDICT': <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>>, 'CHAR': <function MySQL.Parser.<lambda>>, 'GROUP_CONCAT': <function MySQL.Parser.<lambda>>, 'VALUES': <function MySQL.Parser.<lambda>>}
STATEMENT_PARSERS = {<TokenType.ALTER: 'ALTER'>: <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.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.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>>, 'DYNAMIC': <function Parser.<lambda>>, 'DISTKEY': <function Parser.<lambda>>, 'DISTSTYLE': <function Parser.<lambda>>, 'EMPTY': <function Parser.<lambda>>, 'ENGINE': <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 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>>, '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>>, 'FULLTEXT': <function MySQL.Parser.<lambda>>, 'INDEX': <function MySQL.Parser.<lambda>>, 'KEY': <function MySQL.Parser.<lambda>>, 'SPATIAL': <function MySQL.Parser.<lambda>>}
ALTER_PARSERS = {'ADD': <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>>, 'AS': <function Parser.<lambda>>, 'MODIFY': <function MySQL.Parser.<lambda>>}
SCHEMA_UNNAMED_CONSTRAINTS = {'PRIMARY KEY', 'PERIOD', 'KEY', 'FULLTEXT', 'FOREIGN KEY', 'EXCLUDE', 'LIKE', 'INDEX', 'UNIQUE', 'CHECK', 'SPATIAL'}
PROFILE_TYPES: Dict[str, Sequence[Union[Sequence[str], str]]] = {'ALL': (), 'CPU': (), 'IPC': (), 'MEMORY': (), 'SOURCE': (), 'SWAPS': (), 'BLOCK': ('IO',), 'CONTEXT': ('SWITCHES',), 'PAGE': ('FAULTS',)}
TYPE_TOKENS = {<TokenType.UMEDIUMINT: 'UMEDIUMINT'>, <TokenType.GEOGRAPHY: 'GEOGRAPHY'>, <TokenType.IPV6: 'IPV6'>, <TokenType.BIT: 'BIT'>, <TokenType.TDIGEST: 'TDIGEST'>, <TokenType.DATETIME: 'DATETIME'>, <TokenType.NVARCHAR: 'NVARCHAR'>, <TokenType.FIXEDSTRING: 'FIXEDSTRING'>, <TokenType.MEDIUMBLOB: 'MEDIUMBLOB'>, <TokenType.TIME: 'TIME'>, <TokenType.NULLABLE: 'NULLABLE'>, <TokenType.PSEUDO_TYPE: 'PSEUDO_TYPE'>, <TokenType.IMAGE: 'IMAGE'>, <TokenType.DATEMULTIRANGE: 'DATEMULTIRANGE'>, <TokenType.ENUM: 'ENUM'>, <TokenType.UINT: 'UINT'>, <TokenType.UDECIMAL: 'UDECIMAL'>, <TokenType.TIMESTAMPTZ: 'TIMESTAMPTZ'>, <TokenType.ENUM8: 'ENUM8'>, <TokenType.MEDIUMINT: 'MEDIUMINT'>, <TokenType.SMALLSERIAL: 'SMALLSERIAL'>, <TokenType.DOUBLE: 'DOUBLE'>, <TokenType.INT8RANGE: 'INT8RANGE'>, <TokenType.TIMESTAMP: 'TIMESTAMP'>, <TokenType.INT128: 'INT128'>, <TokenType.FLOAT: 'FLOAT'>, <TokenType.USMALLINT: 'USMALLINT'>, <TokenType.BIGSERIAL: 'BIGSERIAL'>, <TokenType.VECTOR: 'VECTOR'>, <TokenType.HSTORE: 'HSTORE'>, <TokenType.STRUCT: 'STRUCT'>, <TokenType.UINT128: 'UINT128'>, <TokenType.INT256: 'INT256'>, <TokenType.UTINYINT: 'UTINYINT'>, <TokenType.NAME: 'NAME'>, <TokenType.TIMESTAMP_MS: 'TIMESTAMP_MS'>, <TokenType.INTERVAL: 'INTERVAL'>, <TokenType.MONEY: 'MONEY'>, <TokenType.LIST: 'LIST'>, <TokenType.NCHAR: 'NCHAR'>, <TokenType.XML: 'XML'>, <TokenType.UUID: 'UUID'>, <TokenType.NUMMULTIRANGE: 'NUMMULTIRANGE'>, <TokenType.OBJECT_IDENTIFIER: 'OBJECT_IDENTIFIER'>, <TokenType.JSON: 'JSON'>, <TokenType.DATE: 'DATE'>, <TokenType.BINARY: 'BINARY'>, <TokenType.BIGDECIMAL: 'BIGDECIMAL'>, <TokenType.SERIAL: 'SERIAL'>, <TokenType.LONGBLOB: 'LONGBLOB'>, <TokenType.OBJECT: 'OBJECT'>, <TokenType.BOOLEAN: 'BOOLEAN'>, <TokenType.NUMRANGE: 'NUMRANGE'>, <TokenType.VARIANT: 'VARIANT'>, <TokenType.SMALLMONEY: 'SMALLMONEY'>, <TokenType.UBIGINT: 'UBIGINT'>, <TokenType.NULL: 'NULL'>, <TokenType.VARCHAR: 'VARCHAR'>, <TokenType.TSTZRANGE: 'TSTZRANGE'>, <TokenType.IPV4: 'IPV4'>, <TokenType.TINYBLOB: 'TINYBLOB'>, <TokenType.TIMETZ: 'TIMETZ'>, <TokenType.LONGTEXT: 'LONGTEXT'>, <TokenType.SMALLINT: 'SMALLINT'>, <TokenType.ARRAY: 'ARRAY'>, <TokenType.IPPREFIX: 'IPPREFIX'>, <TokenType.UNIQUEIDENTIFIER: 'UNIQUEIDENTIFIER'>, <TokenType.ROWVERSION: 'ROWVERSION'>, <TokenType.TEXT: 'TEXT'>, <TokenType.BIGINT: 'BIGINT'>, <TokenType.TINYTEXT: 'TINYTEXT'>, <TokenType.LOWCARDINALITY: 'LOWCARDINALITY'>, <TokenType.INT8MULTIRANGE: 'INT8MULTIRANGE'>, <TokenType.CHAR: 'CHAR'>, <TokenType.ENUM16: 'ENUM16'>, <TokenType.TINYINT: 'TINYINT'>, <TokenType.YEAR: 'YEAR'>, <TokenType.TIMESTAMP_S: 'TIMESTAMP_S'>, <TokenType.NESTED: 'NESTED'>, <TokenType.VARBINARY: 'VARBINARY'>, <TokenType.TSMULTIRANGE: 'TSMULTIRANGE'>, <TokenType.INT4RANGE: 'INT4RANGE'>, <TokenType.JSONB: 'JSONB'>, <TokenType.GEOMETRY: 'GEOMETRY'>, <TokenType.DATE32: 'DATE32'>, <TokenType.HLLSKETCH: 'HLLSKETCH'>, <TokenType.INET: 'INET'>, <TokenType.INT4MULTIRANGE: 'INT4MULTIRANGE'>, <TokenType.SET: 'SET'>, <TokenType.USERDEFINED: 'USERDEFINED'>, <TokenType.TSRANGE: 'TSRANGE'>, <TokenType.TIMESTAMPNTZ: 'TIMESTAMPNTZ'>, <TokenType.DATETIME64: 'DATETIME64'>, <TokenType.IPADDRESS: 'IPADDRESS'>, <TokenType.UNKNOWN: 'UNKNOWN'>, <TokenType.DECIMAL: 'DECIMAL'>, <TokenType.MEDIUMTEXT: 'MEDIUMTEXT'>, <TokenType.MAP: 'MAP'>, <TokenType.DATERANGE: 'DATERANGE'>, <TokenType.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, <TokenType.TIMESTAMP_NS: 'TIMESTAMP_NS'>, <TokenType.AGGREGATEFUNCTION: 'AGGREGATEFUNCTION'>, <TokenType.SIMPLEAGGREGATEFUNCTION: 'SIMPLEAGGREGATEFUNCTION'>, <TokenType.UINT256: 'UINT256'>, <TokenType.BPCHAR: 'BPCHAR'>, <TokenType.TSTZMULTIRANGE: 'TSTZMULTIRANGE'>, <TokenType.INT: 'INT'>, <TokenType.SUPER: 'SUPER'>}
ENUM_TYPE_TOKENS = {<TokenType.ENUM: 'ENUM'>, <TokenType.ENUM16: 'ENUM16'>, <TokenType.ENUM8: 'ENUM8'>, <TokenType.SET: 'SET'>}
LOG_DEFAULTS_TO_LN = True
STRING_ALIASES = True
VALUES_FOLLOWED_BY_PAREN = False
SUPPORTS_PARTITION_SELECTION = True
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
ID_VAR_TOKENS
INTERVAL_VARS
ALIAS_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
EXPRESSION_PARSERS
UNARY_PARSERS
STRING_PARSERS
NUMERIC_PARSERS
PRIMARY_PARSERS
PLACEHOLDER_PARSERS
ALTER_ALTER_PARSERS
NO_PAREN_FUNCTION_PARSERS
INVALID_FUNC_NAME_TOKENS
FUNCTIONS_WITH_ALIASED_ARGS
KEY_VALUE_DEFINITIONS
QUERY_MODIFIER_PARSERS
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
KEY_CONSTRAINT_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
NULL_TOKENS
UNNEST_OFFSET_ALIAS_TOKENS
SELECT_START_TOKENS
COPY_INTO_VARLEN_OPTIONS
STRICT_CAST
PREFIXED_PIVOT_COLUMNS
IDENTIFY_PIVOT_STRINGS
ALTER_TABLE_ADD_REQUIRED_FOR_EACH_COLUMN
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
error_level
error_message_context
max_errors
dialect
reset
parse
parse_into
check_errors
raise_error
expression
validate_expression
errors
sql
class MySQL.Generator(sqlglot.generator.Generator):
 667    class Generator(generator.Generator):
 668        INTERVAL_ALLOWS_PLURAL_FORM = False
 669        LOCKING_READS_SUPPORTED = True
 670        NULL_ORDERING_SUPPORTED = None
 671        JOIN_HINTS = False
 672        TABLE_HINTS = True
 673        DUPLICATE_KEY_UPDATE_WITH_SET = False
 674        QUERY_HINT_SEP = " "
 675        VALUES_AS_TABLE = False
 676        NVL2_SUPPORTED = False
 677        LAST_DAY_SUPPORTS_DATE_PART = False
 678        JSON_TYPE_REQUIRED_FOR_EXTRACTION = True
 679        JSON_PATH_BRACKETED_KEY_SUPPORTED = False
 680        JSON_KEY_VALUE_PAIR_SEP = ","
 681        SUPPORTS_TO_NUMBER = False
 682        PARSE_JSON_NAME = None
 683        PAD_FILL_PATTERN_IS_REQUIRED = True
 684        WRAP_DERIVED_VALUES = False
 685
 686        TRANSFORMS = {
 687            **generator.Generator.TRANSFORMS,
 688            exp.ArrayAgg: rename_func("GROUP_CONCAT"),
 689            exp.CurrentDate: no_paren_current_date_sql,
 690            exp.DateDiff: _remove_ts_or_ds_to_date(
 691                lambda self, e: self.func("DATEDIFF", e.this, e.expression), ("this", "expression")
 692            ),
 693            exp.DateAdd: _remove_ts_or_ds_to_date(date_add_sql("ADD")),
 694            exp.DateStrToDate: datestrtodate_sql,
 695            exp.DateSub: _remove_ts_or_ds_to_date(date_add_sql("SUB")),
 696            exp.DateTrunc: _date_trunc_sql,
 697            exp.Day: _remove_ts_or_ds_to_date(),
 698            exp.DayOfMonth: _remove_ts_or_ds_to_date(rename_func("DAYOFMONTH")),
 699            exp.DayOfWeek: _remove_ts_or_ds_to_date(rename_func("DAYOFWEEK")),
 700            exp.DayOfYear: _remove_ts_or_ds_to_date(rename_func("DAYOFYEAR")),
 701            exp.GroupConcat: lambda self,
 702            e: f"""GROUP_CONCAT({self.sql(e, "this")} SEPARATOR {self.sql(e, "separator") or "','"})""",
 703            exp.ILike: no_ilike_sql,
 704            exp.JSONExtractScalar: arrow_json_extract_sql,
 705            exp.Max: max_or_greatest,
 706            exp.Min: min_or_least,
 707            exp.Month: _remove_ts_or_ds_to_date(),
 708            exp.NullSafeEQ: lambda self, e: self.binary(e, "<=>"),
 709            exp.NullSafeNEQ: lambda self, e: f"NOT {self.binary(e, '<=>')}",
 710            exp.Pivot: no_pivot_sql,
 711            exp.Select: transforms.preprocess(
 712                [
 713                    transforms.eliminate_distinct_on,
 714                    transforms.eliminate_semi_and_anti_joins,
 715                    transforms.eliminate_qualify,
 716                    transforms.eliminate_full_outer_join,
 717                    transforms.unnest_generate_date_array_using_recursive_cte,
 718                ]
 719            ),
 720            exp.StrPosition: strposition_to_locate_sql,
 721            exp.StrToDate: _str_to_date_sql,
 722            exp.StrToTime: _str_to_date_sql,
 723            exp.Stuff: rename_func("INSERT"),
 724            exp.TableSample: no_tablesample_sql,
 725            exp.TimeFromParts: rename_func("MAKETIME"),
 726            exp.TimestampAdd: date_add_interval_sql("DATE", "ADD"),
 727            exp.TimestampDiff: lambda self, e: self.func(
 728                "TIMESTAMPDIFF", unit_to_var(e), e.expression, e.this
 729            ),
 730            exp.TimestampSub: date_add_interval_sql("DATE", "SUB"),
 731            exp.TimeStrToUnix: rename_func("UNIX_TIMESTAMP"),
 732            exp.TimeStrToTime: lambda self, e: self.sql(
 733                exp.cast(e.this, exp.DataType.Type.DATETIME, copy=True)
 734            ),
 735            exp.TimeToStr: _remove_ts_or_ds_to_date(
 736                lambda self, e: self.func("DATE_FORMAT", e.this, self.format_time(e))
 737            ),
 738            exp.Trim: trim_sql,
 739            exp.TryCast: no_trycast_sql,
 740            exp.TsOrDsAdd: date_add_sql("ADD"),
 741            exp.TsOrDsDiff: lambda self, e: self.func("DATEDIFF", e.this, e.expression),
 742            exp.TsOrDsToDate: _ts_or_ds_to_date_sql,
 743            exp.UnixToTime: _unix_to_time_sql,
 744            exp.Week: _remove_ts_or_ds_to_date(),
 745            exp.WeekOfYear: _remove_ts_or_ds_to_date(rename_func("WEEKOFYEAR")),
 746            exp.Year: _remove_ts_or_ds_to_date(),
 747        }
 748
 749        UNSIGNED_TYPE_MAPPING = {
 750            exp.DataType.Type.UBIGINT: "BIGINT",
 751            exp.DataType.Type.UINT: "INT",
 752            exp.DataType.Type.UMEDIUMINT: "MEDIUMINT",
 753            exp.DataType.Type.USMALLINT: "SMALLINT",
 754            exp.DataType.Type.UTINYINT: "TINYINT",
 755            exp.DataType.Type.UDECIMAL: "DECIMAL",
 756        }
 757
 758        TIMESTAMP_TYPE_MAPPING = {
 759            exp.DataType.Type.TIMESTAMP: "DATETIME",
 760            exp.DataType.Type.TIMESTAMPTZ: "TIMESTAMP",
 761            exp.DataType.Type.TIMESTAMPLTZ: "TIMESTAMP",
 762        }
 763
 764        TYPE_MAPPING = {
 765            **generator.Generator.TYPE_MAPPING,
 766            **UNSIGNED_TYPE_MAPPING,
 767            **TIMESTAMP_TYPE_MAPPING,
 768        }
 769
 770        TYPE_MAPPING.pop(exp.DataType.Type.MEDIUMTEXT)
 771        TYPE_MAPPING.pop(exp.DataType.Type.LONGTEXT)
 772        TYPE_MAPPING.pop(exp.DataType.Type.TINYTEXT)
 773        TYPE_MAPPING.pop(exp.DataType.Type.MEDIUMBLOB)
 774        TYPE_MAPPING.pop(exp.DataType.Type.LONGBLOB)
 775        TYPE_MAPPING.pop(exp.DataType.Type.TINYBLOB)
 776
 777        PROPERTIES_LOCATION = {
 778            **generator.Generator.PROPERTIES_LOCATION,
 779            exp.TransientProperty: exp.Properties.Location.UNSUPPORTED,
 780            exp.VolatileProperty: exp.Properties.Location.UNSUPPORTED,
 781        }
 782
 783        LIMIT_FETCH = "LIMIT"
 784
 785        LIMIT_ONLY_LITERALS = True
 786
 787        CHAR_CAST_MAPPING = dict.fromkeys(
 788            (
 789                exp.DataType.Type.LONGTEXT,
 790                exp.DataType.Type.LONGBLOB,
 791                exp.DataType.Type.MEDIUMBLOB,
 792                exp.DataType.Type.MEDIUMTEXT,
 793                exp.DataType.Type.TEXT,
 794                exp.DataType.Type.TINYBLOB,
 795                exp.DataType.Type.TINYTEXT,
 796                exp.DataType.Type.VARCHAR,
 797            ),
 798            "CHAR",
 799        )
 800        SIGNED_CAST_MAPPING = dict.fromkeys(
 801            (
 802                exp.DataType.Type.BIGINT,
 803                exp.DataType.Type.BOOLEAN,
 804                exp.DataType.Type.INT,
 805                exp.DataType.Type.SMALLINT,
 806                exp.DataType.Type.TINYINT,
 807                exp.DataType.Type.MEDIUMINT,
 808            ),
 809            "SIGNED",
 810        )
 811
 812        # MySQL doesn't support many datatypes in cast.
 813        # https://dev.mysql.com/doc/refman/8.0/en/cast-functions.html#function_cast
 814        CAST_MAPPING = {
 815            **CHAR_CAST_MAPPING,
 816            **SIGNED_CAST_MAPPING,
 817            exp.DataType.Type.UBIGINT: "UNSIGNED",
 818        }
 819
 820        TIMESTAMP_FUNC_TYPES = {
 821            exp.DataType.Type.TIMESTAMPTZ,
 822            exp.DataType.Type.TIMESTAMPLTZ,
 823        }
 824
 825        # https://dev.mysql.com/doc/refman/8.0/en/keywords.html
 826        RESERVED_KEYWORDS = {
 827            "accessible",
 828            "add",
 829            "all",
 830            "alter",
 831            "analyze",
 832            "and",
 833            "as",
 834            "asc",
 835            "asensitive",
 836            "before",
 837            "between",
 838            "bigint",
 839            "binary",
 840            "blob",
 841            "both",
 842            "by",
 843            "call",
 844            "cascade",
 845            "case",
 846            "change",
 847            "char",
 848            "character",
 849            "check",
 850            "collate",
 851            "column",
 852            "condition",
 853            "constraint",
 854            "continue",
 855            "convert",
 856            "create",
 857            "cross",
 858            "cube",
 859            "cume_dist",
 860            "current_date",
 861            "current_time",
 862            "current_timestamp",
 863            "current_user",
 864            "cursor",
 865            "database",
 866            "databases",
 867            "day_hour",
 868            "day_microsecond",
 869            "day_minute",
 870            "day_second",
 871            "dec",
 872            "decimal",
 873            "declare",
 874            "default",
 875            "delayed",
 876            "delete",
 877            "dense_rank",
 878            "desc",
 879            "describe",
 880            "deterministic",
 881            "distinct",
 882            "distinctrow",
 883            "div",
 884            "double",
 885            "drop",
 886            "dual",
 887            "each",
 888            "else",
 889            "elseif",
 890            "empty",
 891            "enclosed",
 892            "escaped",
 893            "except",
 894            "exists",
 895            "exit",
 896            "explain",
 897            "false",
 898            "fetch",
 899            "first_value",
 900            "float",
 901            "float4",
 902            "float8",
 903            "for",
 904            "force",
 905            "foreign",
 906            "from",
 907            "fulltext",
 908            "function",
 909            "generated",
 910            "get",
 911            "grant",
 912            "group",
 913            "grouping",
 914            "groups",
 915            "having",
 916            "high_priority",
 917            "hour_microsecond",
 918            "hour_minute",
 919            "hour_second",
 920            "if",
 921            "ignore",
 922            "in",
 923            "index",
 924            "infile",
 925            "inner",
 926            "inout",
 927            "insensitive",
 928            "insert",
 929            "int",
 930            "int1",
 931            "int2",
 932            "int3",
 933            "int4",
 934            "int8",
 935            "integer",
 936            "intersect",
 937            "interval",
 938            "into",
 939            "io_after_gtids",
 940            "io_before_gtids",
 941            "is",
 942            "iterate",
 943            "join",
 944            "json_table",
 945            "key",
 946            "keys",
 947            "kill",
 948            "lag",
 949            "last_value",
 950            "lateral",
 951            "lead",
 952            "leading",
 953            "leave",
 954            "left",
 955            "like",
 956            "limit",
 957            "linear",
 958            "lines",
 959            "load",
 960            "localtime",
 961            "localtimestamp",
 962            "lock",
 963            "long",
 964            "longblob",
 965            "longtext",
 966            "loop",
 967            "low_priority",
 968            "master_bind",
 969            "master_ssl_verify_server_cert",
 970            "match",
 971            "maxvalue",
 972            "mediumblob",
 973            "mediumint",
 974            "mediumtext",
 975            "middleint",
 976            "minute_microsecond",
 977            "minute_second",
 978            "mod",
 979            "modifies",
 980            "natural",
 981            "not",
 982            "no_write_to_binlog",
 983            "nth_value",
 984            "ntile",
 985            "null",
 986            "numeric",
 987            "of",
 988            "on",
 989            "optimize",
 990            "optimizer_costs",
 991            "option",
 992            "optionally",
 993            "or",
 994            "order",
 995            "out",
 996            "outer",
 997            "outfile",
 998            "over",
 999            "partition",
1000            "percent_rank",
1001            "precision",
1002            "primary",
1003            "procedure",
1004            "purge",
1005            "range",
1006            "rank",
1007            "read",
1008            "reads",
1009            "read_write",
1010            "real",
1011            "recursive",
1012            "references",
1013            "regexp",
1014            "release",
1015            "rename",
1016            "repeat",
1017            "replace",
1018            "require",
1019            "resignal",
1020            "restrict",
1021            "return",
1022            "revoke",
1023            "right",
1024            "rlike",
1025            "row",
1026            "rows",
1027            "row_number",
1028            "schema",
1029            "schemas",
1030            "second_microsecond",
1031            "select",
1032            "sensitive",
1033            "separator",
1034            "set",
1035            "show",
1036            "signal",
1037            "smallint",
1038            "spatial",
1039            "specific",
1040            "sql",
1041            "sqlexception",
1042            "sqlstate",
1043            "sqlwarning",
1044            "sql_big_result",
1045            "sql_calc_found_rows",
1046            "sql_small_result",
1047            "ssl",
1048            "starting",
1049            "stored",
1050            "straight_join",
1051            "system",
1052            "table",
1053            "terminated",
1054            "then",
1055            "tinyblob",
1056            "tinyint",
1057            "tinytext",
1058            "to",
1059            "trailing",
1060            "trigger",
1061            "true",
1062            "undo",
1063            "union",
1064            "unique",
1065            "unlock",
1066            "unsigned",
1067            "update",
1068            "usage",
1069            "use",
1070            "using",
1071            "utc_date",
1072            "utc_time",
1073            "utc_timestamp",
1074            "values",
1075            "varbinary",
1076            "varchar",
1077            "varcharacter",
1078            "varying",
1079            "virtual",
1080            "when",
1081            "where",
1082            "while",
1083            "window",
1084            "with",
1085            "write",
1086            "xor",
1087            "year_month",
1088            "zerofill",
1089        }
1090
1091        def array_sql(self, expression: exp.Array) -> str:
1092            self.unsupported("Arrays are not supported by MySQL")
1093            return self.function_fallback_sql(expression)
1094
1095        def arraycontainsall_sql(self, expression: exp.ArrayContainsAll) -> str:
1096            self.unsupported("Array operations are not supported by MySQL")
1097            return self.function_fallback_sql(expression)
1098
1099        def dpipe_sql(self, expression: exp.DPipe) -> str:
1100            return self.func("CONCAT", *expression.flatten())
1101
1102        def extract_sql(self, expression: exp.Extract) -> str:
1103            unit = expression.name
1104            if unit and unit.lower() == "epoch":
1105                return self.func("UNIX_TIMESTAMP", expression.expression)
1106
1107            return super().extract_sql(expression)
1108
1109        def datatype_sql(self, expression: exp.DataType) -> str:
1110            # https://dev.mysql.com/doc/refman/8.0/en/numeric-type-syntax.html
1111            result = super().datatype_sql(expression)
1112            if expression.this in self.UNSIGNED_TYPE_MAPPING:
1113                result = f"{result} UNSIGNED"
1114            return result
1115
1116        def jsonarraycontains_sql(self, expression: exp.JSONArrayContains) -> str:
1117            return f"{self.sql(expression, 'this')} MEMBER OF({self.sql(expression, 'expression')})"
1118
1119        def cast_sql(self, expression: exp.Cast, safe_prefix: t.Optional[str] = None) -> str:
1120            if expression.to.this in self.TIMESTAMP_FUNC_TYPES:
1121                return self.func("TIMESTAMP", expression.this)
1122
1123            to = self.CAST_MAPPING.get(expression.to.this)
1124
1125            if to:
1126                expression.to.set("this", to)
1127            return super().cast_sql(expression)
1128
1129        def show_sql(self, expression: exp.Show) -> str:
1130            this = f" {expression.name}"
1131            full = " FULL" if expression.args.get("full") else ""
1132            global_ = " GLOBAL" if expression.args.get("global") else ""
1133
1134            target = self.sql(expression, "target")
1135            target = f" {target}" if target else ""
1136            if expression.name in ("COLUMNS", "INDEX"):
1137                target = f" FROM{target}"
1138            elif expression.name == "GRANTS":
1139                target = f" FOR{target}"
1140
1141            db = self._prefixed_sql("FROM", expression, "db")
1142
1143            like = self._prefixed_sql("LIKE", expression, "like")
1144            where = self.sql(expression, "where")
1145
1146            types = self.expressions(expression, key="types")
1147            types = f" {types}" if types else types
1148            query = self._prefixed_sql("FOR QUERY", expression, "query")
1149
1150            if expression.name == "PROFILE":
1151                offset = self._prefixed_sql("OFFSET", expression, "offset")
1152                limit = self._prefixed_sql("LIMIT", expression, "limit")
1153            else:
1154                offset = ""
1155                limit = self._oldstyle_limit_sql(expression)
1156
1157            log = self._prefixed_sql("IN", expression, "log")
1158            position = self._prefixed_sql("FROM", expression, "position")
1159
1160            channel = self._prefixed_sql("FOR CHANNEL", expression, "channel")
1161
1162            if expression.name == "ENGINE":
1163                mutex_or_status = " MUTEX" if expression.args.get("mutex") else " STATUS"
1164            else:
1165                mutex_or_status = ""
1166
1167            return f"SHOW{full}{global_}{this}{target}{types}{db}{query}{log}{position}{channel}{mutex_or_status}{like}{where}{offset}{limit}"
1168
1169        def altercolumn_sql(self, expression: exp.AlterColumn) -> str:
1170            dtype = self.sql(expression, "dtype")
1171            if not dtype:
1172                return super().altercolumn_sql(expression)
1173
1174            this = self.sql(expression, "this")
1175            return f"MODIFY COLUMN {this} {dtype}"
1176
1177        def _prefixed_sql(self, prefix: str, expression: exp.Expression, arg: str) -> str:
1178            sql = self.sql(expression, arg)
1179            return f" {prefix} {sql}" if sql else ""
1180
1181        def _oldstyle_limit_sql(self, expression: exp.Show) -> str:
1182            limit = self.sql(expression, "limit")
1183            offset = self.sql(expression, "offset")
1184            if limit:
1185                limit_offset = f"{offset}, {limit}" if offset else limit
1186                return f" LIMIT {limit_offset}"
1187            return ""
1188
1189        def chr_sql(self, expression: exp.Chr) -> str:
1190            this = self.expressions(sqls=[expression.this] + expression.expressions)
1191            charset = expression.args.get("charset")
1192            using = f" USING {self.sql(charset)}" if charset else ""
1193            return f"CHAR({this}{using})"
1194
1195        def timestamptrunc_sql(self, expression: exp.TimestampTrunc) -> str:
1196            unit = expression.args.get("unit")
1197
1198            # Pick an old-enough date to avoid negative timestamp diffs
1199            start_ts = "'0000-01-01 00:00:00'"
1200
1201            # Source: https://stackoverflow.com/a/32955740
1202            timestamp_diff = build_date_delta(exp.TimestampDiff)([unit, start_ts, expression.this])
1203            interval = exp.Interval(this=timestamp_diff, unit=unit)
1204            dateadd = build_date_delta_with_interval(exp.DateAdd)([start_ts, interval])
1205
1206            return self.sql(dateadd)
1207
1208        def converttimezone_sql(self, expression: exp.ConvertTimezone) -> str:
1209            from_tz = expression.args.get("source_tz")
1210            to_tz = expression.args.get("target_tz")
1211            dt = expression.args.get("timestamp")
1212
1213            return self.func("CONVERT_TZ", dt, from_tz, to_tz)

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 or 'always': Always quote. '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 = 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 = None
PAD_FILL_PATTERN_IS_REQUIRED = True
WRAP_DERIVED_VALUES = 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.AllowedValuesProperty'>: <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.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.CopyGrantsProperty'>: <function 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.EphemeralColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.ExcludeColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.ExecuteAsProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.ExternalProperty'>: <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.IntervalSpan'>: <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.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.PathColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.PivotAny'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.ProjectionPolicyColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.RemoteWithConnectionModelProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.ReturnsProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.SampleProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.SecureProperty'>: <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.TemporaryProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.TagColumnConstraint'>: <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.UppercaseColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.UnloggedProperty'>: <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.WithSchemaBindingProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.WithOperator'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.ArrayAgg'>: <function rename_func.<locals>.<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.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.Pivot'>: <function no_pivot_sql>, <class 'sqlglot.expressions.Select'>: <function preprocess.<locals>._to_sql>, <class 'sqlglot.expressions.StrPosition'>: <function strposition_to_locate_sql>, <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.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'}
TIMESTAMP_TYPE_MAPPING = {<Type.TIMESTAMP: 'TIMESTAMP'>: 'DATETIME', <Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>: 'TIMESTAMP', <Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>: 'TIMESTAMP'}
TYPE_MAPPING = {<Type.NCHAR: 'NCHAR'>: 'CHAR', <Type.NVARCHAR: 'NVARCHAR'>: 'VARCHAR', <Type.INET: 'INET'>: 'INET', <Type.ROWVERSION: 'ROWVERSION'>: 'VARBINARY', <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.TIMESTAMP: 'TIMESTAMP'>: '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.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.EngineProperty'>: <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.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.POST_WITH: 'POST_WITH'>, <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.RemoteWithConnectionModelProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.ReturnsProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <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.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.StreamingTableProperty'>: <Location.POST_CREATE: 'POST_CREATE'>, <class 'sqlglot.expressions.StrictProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <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.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.WithSchemaBindingProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.WithSystemVersioningProperty'>: <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.TIMESTAMPTZ: 'TIMESTAMPTZ'>, <Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>}
RESERVED_KEYWORDS = {'drop', 'values', 'high_priority', 'ssl', 'signal', 'terminated', 'trigger', 'float8', 'condition', 'read', 'asensitive', 'range', 'generated', 'on', 'optimize', 'over', 'varchar', 'left', 'rename', 'null', 'minute_microsecond', 'rank', 'exit', 'low_priority', 'insensitive', 'asc', 'grant', 'dual', 'add', 'read_write', 'restrict', 'sqlwarning', 'show', 'precision', 'lock', 'int', 'integer', 'then', 'right', 'group', 'mod', 'sql_calc_found_rows', 'character', 'loop', 'to', 'hour_second', 'in', 'starting', 'cursor', 'localtimestamp', 'collate', 'with', 'current_timestamp', 'float', 'sensitive', 'bigint', 'explain', 'middleint', 'varbinary', 'union', 'if', 'leave', 'fulltext', 'cross', 'all', 'utc_time', 'dense_rank', 'call', 'outfile', 'analyze', 'function', 'tinyint', 'procedure', 'sql_small_result', 'require', 'int1', 'mediumtext', 'day_hour', 'sqlexception', 'alter', 'char', 'key', 'lead', 'longblob', 'modifies', 'constraint', 'outer', 'like', 'revoke', 'hour_minute', 'infile', 'real', 'references', 'sql', 'of', 'day_second', 'when', 'join', 'limit', 'table', 'unlock', 'spatial', 'is', 'distinct', 'nth_value', 'long', 'case', 'order', 'column', 'undo', 'utc_timestamp', 'schema', 'use', 'first_value', 'check', 'between', 'tinytext', 'foreign', 'option', 'separator', 'natural', 'describe', 'inout', 'virtual', 'lag', 'interval', 'into', 'recursive', 'maxvalue', 'release', 'system', 'window', 'elseif', 'or', 'reads', 'blob', 'row', 'not', 'out', 'stored', 'trailing', 'int8', 'from', 'current_user', 'optionally', 'each', 'sql_big_result', 'unique', 'load', 'declare', 'repeat', 'empty', 'hour_microsecond', 'usage', 'schemas', 'resignal', 'straight_join', 'second_microsecond', 'zerofill', 'as', 'cascade', 'cube', 'float4', 'regexp', 'write', 'optimizer_costs', 'sqlstate', 'get', 'return', 'delayed', 'before', 'mediumint', 'for', 'enclosed', 'json_table', 'xor', 'while', 'exists', 'specific', 'varcharacter', 'else', 'convert', 'groups', 'true', 'insert', 'change', 'by', 'distinctrow', 'utc_date', 'escaped', 'grouping', 'year_month', 'lateral', 'rlike', 'where', 'partition', 'row_number', 'day_minute', 'both', 'databases', 'match', 'cume_dist', 'update', 'mediumblob', 'and', 'force', 'inner', 'database', 'set', 'false', 'desc', 'fetch', 'rows', 'current_date', 'last_value', 'primary', 'numeric', 'longtext', 'day_microsecond', 'kill', 'continue', 'unsigned', 'using', 'localtime', 'master_ssl_verify_server_cert', 'ignore', 'div', 'dec', 'int2', 'io_before_gtids', 'lines', 'io_after_gtids', 'replace', 'intersect', 'keys', 'linear', 'iterate', 'int3', 'int4', 'smallint', 'default', 'binary', 'having', 'decimal', 'except', 'leading', 'no_write_to_binlog', 'purge', 'accessible', 'double', 'current_time', 'select', 'delete', 'varying', 'ntile', 'deterministic', 'tinyblob', 'percent_rank', 'index', 'create', 'minute_second', 'master_bind'}
def array_sql(self, expression: sqlglot.expressions.Array) -> str:
1091        def array_sql(self, expression: exp.Array) -> str:
1092            self.unsupported("Arrays are not supported by MySQL")
1093            return self.function_fallback_sql(expression)
def arraycontainsall_sql(self, expression: sqlglot.expressions.ArrayContainsAll) -> str:
1095        def arraycontainsall_sql(self, expression: exp.ArrayContainsAll) -> str:
1096            self.unsupported("Array operations are not supported by MySQL")
1097            return self.function_fallback_sql(expression)
def dpipe_sql(self, expression: sqlglot.expressions.DPipe) -> str:
1099        def dpipe_sql(self, expression: exp.DPipe) -> str:
1100            return self.func("CONCAT", *expression.flatten())
def extract_sql(self, expression: sqlglot.expressions.Extract) -> str:
1102        def extract_sql(self, expression: exp.Extract) -> str:
1103            unit = expression.name
1104            if unit and unit.lower() == "epoch":
1105                return self.func("UNIX_TIMESTAMP", expression.expression)
1106
1107            return super().extract_sql(expression)
def datatype_sql(self, expression: sqlglot.expressions.DataType) -> str:
1109        def datatype_sql(self, expression: exp.DataType) -> str:
1110            # https://dev.mysql.com/doc/refman/8.0/en/numeric-type-syntax.html
1111            result = super().datatype_sql(expression)
1112            if expression.this in self.UNSIGNED_TYPE_MAPPING:
1113                result = f"{result} UNSIGNED"
1114            return result
def jsonarraycontains_sql(self, expression: sqlglot.expressions.JSONArrayContains) -> str:
1116        def jsonarraycontains_sql(self, expression: exp.JSONArrayContains) -> str:
1117            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:
1119        def cast_sql(self, expression: exp.Cast, safe_prefix: t.Optional[str] = None) -> str:
1120            if expression.to.this in self.TIMESTAMP_FUNC_TYPES:
1121                return self.func("TIMESTAMP", expression.this)
1122
1123            to = self.CAST_MAPPING.get(expression.to.this)
1124
1125            if to:
1126                expression.to.set("this", to)
1127            return super().cast_sql(expression)
def show_sql(self, expression: sqlglot.expressions.Show) -> str:
1129        def show_sql(self, expression: exp.Show) -> str:
1130            this = f" {expression.name}"
1131            full = " FULL" if expression.args.get("full") else ""
1132            global_ = " GLOBAL" if expression.args.get("global") else ""
1133
1134            target = self.sql(expression, "target")
1135            target = f" {target}" if target else ""
1136            if expression.name in ("COLUMNS", "INDEX"):
1137                target = f" FROM{target}"
1138            elif expression.name == "GRANTS":
1139                target = f" FOR{target}"
1140
1141            db = self._prefixed_sql("FROM", expression, "db")
1142
1143            like = self._prefixed_sql("LIKE", expression, "like")
1144            where = self.sql(expression, "where")
1145
1146            types = self.expressions(expression, key="types")
1147            types = f" {types}" if types else types
1148            query = self._prefixed_sql("FOR QUERY", expression, "query")
1149
1150            if expression.name == "PROFILE":
1151                offset = self._prefixed_sql("OFFSET", expression, "offset")
1152                limit = self._prefixed_sql("LIMIT", expression, "limit")
1153            else:
1154                offset = ""
1155                limit = self._oldstyle_limit_sql(expression)
1156
1157            log = self._prefixed_sql("IN", expression, "log")
1158            position = self._prefixed_sql("FROM", expression, "position")
1159
1160            channel = self._prefixed_sql("FOR CHANNEL", expression, "channel")
1161
1162            if expression.name == "ENGINE":
1163                mutex_or_status = " MUTEX" if expression.args.get("mutex") else " STATUS"
1164            else:
1165                mutex_or_status = ""
1166
1167            return f"SHOW{full}{global_}{this}{target}{types}{db}{query}{log}{position}{channel}{mutex_or_status}{like}{where}{offset}{limit}"
def altercolumn_sql(self, expression: sqlglot.expressions.AlterColumn) -> str:
1169        def altercolumn_sql(self, expression: exp.AlterColumn) -> str:
1170            dtype = self.sql(expression, "dtype")
1171            if not dtype:
1172                return super().altercolumn_sql(expression)
1173
1174            this = self.sql(expression, "this")
1175            return f"MODIFY COLUMN {this} {dtype}"
def chr_sql(self, expression: sqlglot.expressions.Chr) -> str:
1189        def chr_sql(self, expression: exp.Chr) -> str:
1190            this = self.expressions(sqls=[expression.this] + expression.expressions)
1191            charset = expression.args.get("charset")
1192            using = f" USING {self.sql(charset)}" if charset else ""
1193            return f"CHAR({this}{using})"
def timestamptrunc_sql(self, expression: sqlglot.expressions.TimestampTrunc) -> str:
1195        def timestamptrunc_sql(self, expression: exp.TimestampTrunc) -> str:
1196            unit = expression.args.get("unit")
1197
1198            # Pick an old-enough date to avoid negative timestamp diffs
1199            start_ts = "'0000-01-01 00:00:00'"
1200
1201            # Source: https://stackoverflow.com/a/32955740
1202            timestamp_diff = build_date_delta(exp.TimestampDiff)([unit, start_ts, expression.this])
1203            interval = exp.Interval(this=timestamp_diff, unit=unit)
1204            dateadd = build_date_delta_with_interval(exp.DateAdd)([start_ts, interval])
1205
1206            return self.sql(dateadd)
def converttimezone_sql(self, expression: sqlglot.expressions.ConvertTimezone) -> str:
1208        def converttimezone_sql(self, expression: exp.ConvertTimezone) -> str:
1209            from_tz = expression.args.get("source_tz")
1210            to_tz = expression.args.get("target_tz")
1211            dt = expression.args.get("timestamp")
1212
1213            return self.func("CONVERT_TZ", dt, from_tz, to_tz)
SELECT_KINDS: Tuple[str, ...] = ()
TRY_SUPPORTED = False
SUPPORTS_UESCAPE = False
SUPPORTS_NULLABLE_TYPES = False
AFTER_HAVING_MODIFIER_TRANSFORMS = {'windows': <function Generator.<lambda>>, 'qualify': <function Generator.<lambda>>}
Inherited Members
sqlglot.generator.Generator
Generator
IGNORE_NULLS_IN_FUNC
EXPLICIT_SET_OP
CREATE_FUNCTION_RETURN_AS
MATCHED_BY_SOURCE
SINGLE_STRING_INTERVAL
RENAME_TABLE_WITH_DB
GROUPINGS_SEP
INDEX_ON
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
SET_OP_MODIFIERS
COPY_PARAMS_ARE_WRAPPED
COPY_PARAMS_EQ_REQUIRED
COPY_HAS_INTO_KEYWORD
STAR_EXCEPT
HEX_FUNC
WITH_PROPERTIES_PREFIX
QUOTE_JSON_PATH
SUPPORTS_EXPLODING_PROJECTIONS
ARRAY_CONCAT_IS_VAR_LEN
SUPPORTS_CONVERT_TIMEZONE
TIME_PART_SINGULARS
TOKEN_MAPPING
STRUCT_DELIMITER
PARAMETER_TOKEN
NAMED_PLACEHOLDER_TOKEN
WITH_SEPARATED_COMMENTS
EXCLUDE_COMMENTS
UNWRAPPED_INTERVAL_VALUES
PARAMETERIZABLE_TEXT_TYPES
EXPRESSIONS_WITHOUT_NESTED_CTES
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
pad_comment
maybe_comment
wrap
no_identify
normalize_func
indent
sql
uncache_sql
cache_sql
characterset_sql
column_parts
column_sql
columnposition_sql
columndef_sql
columnconstraint_sql
computedcolumnconstraint_sql
autoincrementcolumnconstraint_sql
compresscolumnconstraint_sql
generatedasidentitycolumnconstraint_sql
generatedasrowcolumnconstraint_sql
periodforsystemtimeconstraint_sql
notnullcolumnconstraint_sql
transformcolumnconstraint_sql
primarykeycolumnconstraint_sql
uniquecolumnconstraint_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
except_sql
except_op
fetch_sql
filter_sql
hint_sql
indexparameters_sql
index_sql
identifier_sql
hex_sql
lowerhex_sql
inputoutputformat_sql
national_sql
partition_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
intersect_sql
intersect_op
introducer_sql
kill_sql
pseudotype_sql
objectidentifier_sql
onconflict_sql
returning_sql
rowformatdelimitedproperty_sql
withtablehint_sql
indextablehint_sql
historicaldata_sql
table_parts
table_sql
tablesample_sql
pivot_sql
version_sql
tuple_sql
update_sql
values_sql
var_sql
into_sql
from_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
pragma_sql
lock_sql
literal_sql
escape_str
loaddata_sql
null_sql
boolean_sql
order_sql
withfill_sql
cluster_sql
distribute_sql
sort_sql
ordered_sql
matchrecognizemeasure_sql
matchrecognize_sql
query_modifiers
options_modifier
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
set_operations
union_sql
union_op
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
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
attimezone_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
currentdate_sql
collate_sql
command_sql
comment_sql
mergetreettlaction_sql
mergetreettl_sql
transaction_sql
commit_sql
rollback_sql
alterdiststyle_sql
altersortkey_sql
renametable_sql
renamecolumn_sql
alterset_sql
alter_sql
add_column_sql
droppartition_sql
addconstraint_sql
distinct_sql
ignorenulls_sql
respectnulls_sql
havingmax_sql
intdiv_sql
div_sql
overlaps_sql
distance_sql
dot_sql
eq_sql
propertyeq_sql
escape_sql
glob_sql
gt_sql
gte_sql
ilike_sql
ilikeany_sql
is_sql
like_sql
likeany_sql
similarto_sql
lt_sql
lte_sql
mod_sql
mul_sql
neq_sql
nullsafeeq_sql
nullsafeneq_sql
slice_sql
sub_sql
trycast_sql
try_sql
log_sql
use_sql
binary
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
merge_sql
tochar_sql
tonumber_sql
dictproperty_sql
dictrange_sql
dictsubproperty_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
forin_sql
refresh_sql
toarray_sql
tsordstotime_sql
tsordstotimestamp_sql
tsordstodate_sql
unixdate_sql
lastday_sql
dateadd_sql
arrayany_sql
struct_sql
partitionrange_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
arrayconcat_sql