sqlglot.dialects.mysql API documentation

Edit on GitHub

# sqlglot.dialects.mysql

View Source

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

TIME_SPECIFIERS = {'T', 'I', 'p', 'S', 'H', 'h', 'k', 'f', 'l', 'r', 'i', 's'}
def date_add_sql( kind: str) -> Callable[[sqlglot.generator.Generator, sqlglot.expressions.Expression], str]: View Source

    116def date_add_sql(
    117    kind: str,
    118) -> t.Callable[[generator.Generator, exp.Expression], str]:
    119    def func(self: generator.Generator, expression: exp.Expression) -> str:
    120        return self.func(
    121            f"DATE_{kind}",
    122            expression.this,
    123            exp.Interval(this=expression.expression, unit=unit_to_var(expression)),
    124        )
    125
    126    return func

class MySQL(sqlglot.dialects.dialect.Dialect): View Source

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

PROMOTE_TO_INFERRED_DATETIME_TYPE = True

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

IDENTIFIERS_CAN_START_WITH_DIGIT = True

Whether an unquoted identifier can start with a digit.

NORMALIZATION_STRATEGY = <NormalizationStrategy.CASE_SENSITIVE: 'CASE_SENSITIVE'>

Specifies the strategy according to which identifiers should be normalized.

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

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

SUPPORTS_USER_DEFINED_TYPES = False

Whether user-defined data types are supported.

SUPPORTS_SEMI_ANTI_JOIN = False

Whether `SEMI` or `ANTI` joins are supported.

SAFE_DIVISION = True

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

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): View Source

    183    class Tokenizer(tokens.Tokenizer):
    184        QUOTES = ["'", '"']
    185        COMMENTS = ["--", "#", ("/*", "*/")]
    186        IDENTIFIERS = ["`"]
    187        STRING_ESCAPES = ["'", '"', "\\"]
    188        BIT_STRINGS = [("b'", "'"), ("B'", "'"), ("0b", "")]
    189        HEX_STRINGS = [("x'", "'"), ("X'", "'"), ("0x", "")]
    190
    191        NESTED_COMMENTS = False
    192
    193        KEYWORDS = {
    194            **tokens.Tokenizer.KEYWORDS,
    195            "CHARSET": TokenType.CHARACTER_SET,
    196            # The DESCRIBE and EXPLAIN statements are synonyms.
    197            # https://dev.mysql.com/doc/refman/8.4/en/explain.html
    198            "BLOB": TokenType.BLOB,
    199            "EXPLAIN": TokenType.DESCRIBE,
    200            "FORCE": TokenType.FORCE,
    201            "IGNORE": TokenType.IGNORE,
    202            "KEY": TokenType.KEY,
    203            "LOCK TABLES": TokenType.COMMAND,
    204            "LONGBLOB": TokenType.LONGBLOB,
    205            "LONGTEXT": TokenType.LONGTEXT,
    206            "MEDIUMBLOB": TokenType.MEDIUMBLOB,
    207            "TINYBLOB": TokenType.TINYBLOB,
    208            "TINYTEXT": TokenType.TINYTEXT,
    209            "MEDIUMTEXT": TokenType.MEDIUMTEXT,
    210            "MEDIUMINT": TokenType.MEDIUMINT,
    211            "MEMBER OF": TokenType.MEMBER_OF,
    212            "SEPARATOR": TokenType.SEPARATOR,
    213            "SERIAL": TokenType.SERIAL,
    214            "START": TokenType.BEGIN,
    215            "SIGNED": TokenType.BIGINT,
    216            "SIGNED INTEGER": TokenType.BIGINT,
    217            "TIMESTAMP": TokenType.TIMESTAMPTZ,
    218            "UNLOCK TABLES": TokenType.COMMAND,
    219            "UNSIGNED": TokenType.UBIGINT,
    220            "UNSIGNED INTEGER": TokenType.UBIGINT,
    221            "YEAR": TokenType.YEAR,
    222            "_ARMSCII8": TokenType.INTRODUCER,
    223            "_ASCII": TokenType.INTRODUCER,
    224            "_BIG5": TokenType.INTRODUCER,
    225            "_BINARY": TokenType.INTRODUCER,
    226            "_CP1250": TokenType.INTRODUCER,
    227            "_CP1251": TokenType.INTRODUCER,
    228            "_CP1256": TokenType.INTRODUCER,
    229            "_CP1257": TokenType.INTRODUCER,
    230            "_CP850": TokenType.INTRODUCER,
    231            "_CP852": TokenType.INTRODUCER,
    232            "_CP866": TokenType.INTRODUCER,
    233            "_CP932": TokenType.INTRODUCER,
    234            "_DEC8": TokenType.INTRODUCER,
    235            "_EUCJPMS": TokenType.INTRODUCER,
    236            "_EUCKR": TokenType.INTRODUCER,
    237            "_GB18030": TokenType.INTRODUCER,
    238            "_GB2312": TokenType.INTRODUCER,
    239            "_GBK": TokenType.INTRODUCER,
    240            "_GEOSTD8": TokenType.INTRODUCER,
    241            "_GREEK": TokenType.INTRODUCER,
    242            "_HEBREW": TokenType.INTRODUCER,
    243            "_HP8": TokenType.INTRODUCER,
    244            "_KEYBCS2": TokenType.INTRODUCER,
    245            "_KOI8R": TokenType.INTRODUCER,
    246            "_KOI8U": TokenType.INTRODUCER,
    247            "_LATIN1": TokenType.INTRODUCER,
    248            "_LATIN2": TokenType.INTRODUCER,
    249            "_LATIN5": TokenType.INTRODUCER,
    250            "_LATIN7": TokenType.INTRODUCER,
    251            "_MACCE": TokenType.INTRODUCER,
    252            "_MACROMAN": TokenType.INTRODUCER,
    253            "_SJIS": TokenType.INTRODUCER,
    254            "_SWE7": TokenType.INTRODUCER,
    255            "_TIS620": TokenType.INTRODUCER,
    256            "_UCS2": TokenType.INTRODUCER,
    257            "_UJIS": TokenType.INTRODUCER,
    258            # https://dev.mysql.com/doc/refman/8.0/en/string-literals.html
    259            "_UTF8": TokenType.INTRODUCER,
    260            "_UTF16": TokenType.INTRODUCER,
    261            "_UTF16LE": TokenType.INTRODUCER,
    262            "_UTF32": TokenType.INTRODUCER,
    263            "_UTF8MB3": TokenType.INTRODUCER,
    264            "_UTF8MB4": TokenType.INTRODUCER,
    265            "@@": TokenType.SESSION_PARAMETER,
    266        }
    267
    268        COMMANDS = {*tokens.Tokenizer.COMMANDS, TokenType.REPLACE} - {TokenType.SHOW}

QUOTES = ["'", '"']
COMMENTS = ['--', '#', ('/*', '*/')]
IDENTIFIERS = ['`']
STRING_ESCAPES = ["'", '"', '\\']
BIT_STRINGS = [("b'", "'"), ("B'", "'"), ('0b', '')]
HEX_STRINGS = [("x'", "'"), ("X'", "'"), ('0x', '')]
NESTED_COMMENTS = False
KEYWORDS = {'{%': <TokenType.BLOCK_START: 'BLOCK_START'>, '{%+': <TokenType.BLOCK_START: 'BLOCK_START'>, '{%-': <TokenType.BLOCK_START: 'BLOCK_START'>, '%}': <TokenType.BLOCK_END: 'BLOCK_END'>, '+%}': <TokenType.BLOCK_END: 'BLOCK_END'>, '-%}': <TokenType.BLOCK_END: 'BLOCK_END'>, '{{+': <TokenType.BLOCK_START: 'BLOCK_START'>, '{{-': <TokenType.BLOCK_START: 'BLOCK_START'>, '+}}': <TokenType.BLOCK_END: 'BLOCK_END'>, '-}}': <TokenType.BLOCK_END: 'BLOCK_END'>, '/*+': <TokenType.HINT: 'HINT'>, '==': <TokenType.EQ: 'EQ'>, '::': <TokenType.DCOLON: 'DCOLON'>, '||': <TokenType.DPIPE: 'DPIPE'>, '|>': <TokenType.PIPE_GT: 'PIPE_GT'>, '>=': <TokenType.GTE: 'GTE'>, '<=': <TokenType.LTE: 'LTE'>, '<>': <TokenType.NEQ: 'NEQ'>, '!=': <TokenType.NEQ: 'NEQ'>, ':=': <TokenType.COLON_EQ: 'COLON_EQ'>, '<=>': <TokenType.NULLSAFE_EQ: 'NULLSAFE_EQ'>, '->': <TokenType.ARROW: 'ARROW'>, '->>': <TokenType.DARROW: 'DARROW'>, '=>': <TokenType.FARROW: 'FARROW'>, '#>': <TokenType.HASH_ARROW: 'HASH_ARROW'>, '#>>': <TokenType.DHASH_ARROW: 'DHASH_ARROW'>, '<->': <TokenType.LR_ARROW: 'LR_ARROW'>, '&&': <TokenType.DAMP: 'DAMP'>, '??': <TokenType.DQMARK: 'DQMARK'>, '~~~': <TokenType.GLOB: 'GLOB'>, '~~': <TokenType.LIKE: 'LIKE'>, '~~*': <TokenType.ILIKE: 'ILIKE'>, '~*': <TokenType.IRLIKE: 'IRLIKE'>, '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_SCHEMA': <TokenType.CURRENT_SCHEMA: 'CURRENT_SCHEMA'>, 'CURRENT_TIME': <TokenType.CURRENT_TIME: 'CURRENT_TIME'>, 'CURRENT_TIMESTAMP': <TokenType.CURRENT_TIMESTAMP: 'CURRENT_TIMESTAMP'>, 'CURRENT_USER': <TokenType.CURRENT_USER: 'CURRENT_USER'>, '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'>, 'NAMESPACE': <TokenType.NAMESPACE: 'NAMESPACE'>, 'NATURAL': <TokenType.NATURAL: 'NATURAL'>, 'NEXT': <TokenType.NEXT: 'NEXT'>, 'NOT': <TokenType.NOT: 'NOT'>, 'NOTNULL': <TokenType.NOTNULL: 'NOTNULL'>, 'NULL': <TokenType.NULL: 'NULL'>, 'OBJECT': <TokenType.OBJECT: 'OBJECT'>, 'OFFSET': <TokenType.OFFSET: 'OFFSET'>, 'ON': <TokenType.ON: 'ON'>, 'OR': <TokenType.OR: 'OR'>, 'XOR': <TokenType.XOR: 'XOR'>, 'ORDER BY': <TokenType.ORDER_BY: 'ORDER_BY'>, 'ORDINALITY': <TokenType.ORDINALITY: 'ORDINALITY'>, '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'>, 'HUGEINT': <TokenType.INT128: 'INT128'>, 'UHUGEINT': <TokenType.UINT128: 'UINT128'>, 'INT2': <TokenType.SMALLINT: 'SMALLINT'>, 'INTEGER': <TokenType.INT: 'INT'>, 'INT': <TokenType.INT: 'INT'>, 'INT4': <TokenType.INT: 'INT'>, 'INT32': <TokenType.INT: 'INT'>, 'INT64': <TokenType.BIGINT: 'BIGINT'>, 'INT128': <TokenType.INT128: 'INT128'>, 'INT256': <TokenType.INT256: 'INT256'>, 'LONG': <TokenType.BIGINT: 'BIGINT'>, 'BIGINT': <TokenType.BIGINT: 'BIGINT'>, 'INT8': <TokenType.TINYINT: 'TINYINT'>, 'UINT': <TokenType.UINT: 'UINT'>, 'UINT128': <TokenType.UINT128: 'UINT128'>, 'UINT256': <TokenType.UINT256: 'UINT256'>, 'DEC': <TokenType.DECIMAL: 'DECIMAL'>, 'DECIMAL': <TokenType.DECIMAL: 'DECIMAL'>, 'DECIMAL32': <TokenType.DECIMAL32: 'DECIMAL32'>, 'DECIMAL64': <TokenType.DECIMAL64: 'DECIMAL64'>, 'DECIMAL128': <TokenType.DECIMAL128: 'DECIMAL128'>, 'DECIMAL256': <TokenType.DECIMAL256: 'DECIMAL256'>, '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'>, 'CHAR VARYING': <TokenType.VARCHAR: 'VARCHAR'>, 'CHARACTER VARYING': <TokenType.VARCHAR: 'VARCHAR'>, 'NCHAR': <TokenType.NCHAR: 'NCHAR'>, 'VARCHAR': <TokenType.VARCHAR: 'VARCHAR'>, 'VARCHAR2': <TokenType.VARCHAR: 'VARCHAR'>, 'NVARCHAR': <TokenType.NVARCHAR: 'NVARCHAR'>, 'NVARCHAR2': <TokenType.NVARCHAR: 'NVARCHAR'>, 'BPCHAR': <TokenType.BPCHAR: 'BPCHAR'>, 'STR': <TokenType.TEXT: 'TEXT'>, 'STRING': <TokenType.TEXT: 'TEXT'>, 'TEXT': <TokenType.TEXT: 'TEXT'>, 'LONGTEXT': <TokenType.LONGTEXT: 'LONGTEXT'>, 'MEDIUMTEXT': <TokenType.MEDIUMTEXT: 'MEDIUMTEXT'>, 'TINYTEXT': <TokenType.TINYTEXT: 'TINYTEXT'>, 'CLOB': <TokenType.TEXT: 'TEXT'>, 'LONGVARCHAR': <TokenType.TEXT: 'TEXT'>, 'BINARY': <TokenType.BINARY: 'BINARY'>, 'BLOB': <TokenType.BLOB: 'BLOB'>, 'LONGBLOB': <TokenType.LONGBLOB: 'LONGBLOB'>, 'MEDIUMBLOB': <TokenType.MEDIUMBLOB: 'MEDIUMBLOB'>, 'TINYBLOB': <TokenType.TINYBLOB: 'TINYBLOB'>, 'BYTEA': <TokenType.VARBINARY: 'VARBINARY'>, 'VARBINARY': <TokenType.VARBINARY: 'VARBINARY'>, 'TIME': <TokenType.TIME: 'TIME'>, 'TIMETZ': <TokenType.TIMETZ: 'TIMETZ'>, 'TIMESTAMP': <TokenType.TIMESTAMPTZ: 'TIMESTAMPTZ'>, 'TIMESTAMPTZ': <TokenType.TIMESTAMPTZ: 'TIMESTAMPTZ'>, 'TIMESTAMPLTZ': <TokenType.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, 'TIMESTAMP_LTZ': <TokenType.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, 'TIMESTAMPNTZ': <TokenType.TIMESTAMPNTZ: 'TIMESTAMPNTZ'>, 'TIMESTAMP_NTZ': <TokenType.TIMESTAMPNTZ: 'TIMESTAMPNTZ'>, 'DATE': <TokenType.DATE: 'DATE'>, 'DATETIME': <TokenType.DATETIME: 'DATETIME'>, 'INT4RANGE': <TokenType.INT4RANGE: 'INT4RANGE'>, 'INT4MULTIRANGE': <TokenType.INT4MULTIRANGE: 'INT4MULTIRANGE'>, 'INT8RANGE': <TokenType.INT8RANGE: 'INT8RANGE'>, 'INT8MULTIRANGE': <TokenType.INT8MULTIRANGE: 'INT8MULTIRANGE'>, 'NUMRANGE': <TokenType.NUMRANGE: 'NUMRANGE'>, 'NUMMULTIRANGE': <TokenType.NUMMULTIRANGE: 'NUMMULTIRANGE'>, 'TSRANGE': <TokenType.TSRANGE: 'TSRANGE'>, 'TSMULTIRANGE': <TokenType.TSMULTIRANGE: 'TSMULTIRANGE'>, 'TSTZRANGE': <TokenType.TSTZRANGE: 'TSTZRANGE'>, 'TSTZMULTIRANGE': <TokenType.TSTZMULTIRANGE: 'TSTZMULTIRANGE'>, 'DATERANGE': <TokenType.DATERANGE: 'DATERANGE'>, 'DATEMULTIRANGE': <TokenType.DATEMULTIRANGE: 'DATEMULTIRANGE'>, 'UNIQUE': <TokenType.UNIQUE: 'UNIQUE'>, 'VECTOR': <TokenType.VECTOR: 'VECTOR'>, 'STRUCT': <TokenType.STRUCT: 'STRUCT'>, 'SEQUENCE': <TokenType.SEQUENCE: 'SEQUENCE'>, 'VARIANT': <TokenType.VARIANT: 'VARIANT'>, 'ALTER': <TokenType.ALTER: 'ALTER'>, 'ANALYZE': <TokenType.ANALYZE: 'ANALYZE'>, 'CALL': <TokenType.COMMAND: 'COMMAND'>, 'COMMENT': <TokenType.COMMENT: 'COMMENT'>, 'EXPLAIN': <TokenType.DESCRIBE: 'DESCRIBE'>, 'GRANT': <TokenType.GRANT: 'GRANT'>, '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'>, 'SERIAL': <TokenType.SERIAL: 'SERIAL'>, '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.COMMAND: 'COMMAND'>, <TokenType.REPLACE: 'REPLACE'>, <TokenType.EXECUTE: 'EXECUTE'>, <TokenType.RENAME: 'RENAME'>, <TokenType.FETCH: 'FETCH'>}

##### Inherited Members

sqlglot.tokens.Tokenizer
  Tokenizer
  SINGLE_TOKENS
  BYTE_STRINGS
  RAW_STRINGS
  HEREDOC_STRINGS
  UNICODE_STRINGS
  VAR_SINGLE_TOKENS
  IDENTIFIER_ESCAPES
  HEREDOC_TAG_IS_IDENTIFIER
  HEREDOC_STRING_ALTERNATIVE
  STRING_ESCAPES_ALLOWED_IN_RAW_STRINGS
  HINT_START
  TOKENS_PRECEDING_HINT
  WHITE_SPACE
  COMMAND_PREFIX_TOKENS
  NUMERIC_LITERALS
  dialect
  use_rs_tokenizer
  reset
  tokenize
  tokenize_rs
  size
  sql
  tokens

class MySQL.Parser(sqlglot.parser.Parser): View Source

    270    class Parser(parser.Parser):
    271        FUNC_TOKENS = {
    272            *parser.Parser.FUNC_TOKENS,
    273            TokenType.DATABASE,
    274            TokenType.SCHEMA,
    275            TokenType.VALUES,
    276        }
    277
    278        CONJUNCTION = {
    279            **parser.Parser.CONJUNCTION,
    280            TokenType.DAMP: exp.And,
    281            TokenType.XOR: exp.Xor,
    282        }
    283
    284        DISJUNCTION = {
    285            **parser.Parser.DISJUNCTION,
    286            TokenType.DPIPE: exp.Or,
    287        }
    288
    289        TABLE_ALIAS_TOKENS = (
    290            parser.Parser.TABLE_ALIAS_TOKENS - parser.Parser.TABLE_INDEX_HINT_TOKENS
    291        )
    292
    293        RANGE_PARSERS = {
    294            **parser.Parser.RANGE_PARSERS,
    295            TokenType.MEMBER_OF: lambda self, this: self.expression(
    296                exp.JSONArrayContains,
    297                this=this,
    298                expression=self._parse_wrapped(self._parse_expression),
    299            ),
    300        }
    301
    302        FUNCTIONS = {
    303            **parser.Parser.FUNCTIONS,
    304            "CONVERT_TZ": lambda args: exp.ConvertTimezone(
    305                source_tz=seq_get(args, 1), target_tz=seq_get(args, 2), timestamp=seq_get(args, 0)
    306            ),
    307            "CURDATE": exp.CurrentDate.from_arg_list,
    308            "DATE": lambda args: exp.TsOrDsToDate(this=seq_get(args, 0)),
    309            "DATE_ADD": build_date_delta_with_interval(exp.DateAdd),
    310            "DATE_FORMAT": build_formatted_time(exp.TimeToStr, "mysql"),
    311            "DATE_SUB": build_date_delta_with_interval(exp.DateSub),
    312            "DAY": lambda args: exp.Day(this=exp.TsOrDsToDate(this=seq_get(args, 0))),
    313            "DAYOFMONTH": lambda args: exp.DayOfMonth(this=exp.TsOrDsToDate(this=seq_get(args, 0))),
    314            "DAYOFWEEK": lambda args: exp.DayOfWeek(this=exp.TsOrDsToDate(this=seq_get(args, 0))),
    315            "DAYOFYEAR": lambda args: exp.DayOfYear(this=exp.TsOrDsToDate(this=seq_get(args, 0))),
    316            "FORMAT": exp.NumberToStr.from_arg_list,
    317            "FROM_UNIXTIME": build_formatted_time(exp.UnixToTime, "mysql"),
    318            "ISNULL": isnull_to_is_null,
    319            "LENGTH": lambda args: exp.Length(this=seq_get(args, 0), binary=True),
    320            "MAKETIME": exp.TimeFromParts.from_arg_list,
    321            "MONTH": lambda args: exp.Month(this=exp.TsOrDsToDate(this=seq_get(args, 0))),
    322            "MONTHNAME": lambda args: exp.TimeToStr(
    323                this=exp.TsOrDsToDate(this=seq_get(args, 0)),
    324                format=exp.Literal.string("%B"),
    325            ),
    326            "SCHEMA": exp.CurrentSchema.from_arg_list,
    327            "DATABASE": exp.CurrentSchema.from_arg_list,
    328            "STR_TO_DATE": _str_to_date,
    329            "TIMESTAMPDIFF": build_date_delta(exp.TimestampDiff),
    330            "TO_DAYS": lambda args: exp.paren(
    331                exp.DateDiff(
    332                    this=exp.TsOrDsToDate(this=seq_get(args, 0)),
    333                    expression=exp.TsOrDsToDate(this=exp.Literal.string("0000-01-01")),
    334                    unit=exp.var("DAY"),
    335                )
    336                + 1
    337            ),
    338            "WEEK": lambda args: exp.Week(
    339                this=exp.TsOrDsToDate(this=seq_get(args, 0)), mode=seq_get(args, 1)
    340            ),
    341            "WEEKOFYEAR": lambda args: exp.WeekOfYear(this=exp.TsOrDsToDate(this=seq_get(args, 0))),
    342            "YEAR": lambda args: exp.Year(this=exp.TsOrDsToDate(this=seq_get(args, 0))),
    343        }
    344
    345        FUNCTION_PARSERS = {
    346            **parser.Parser.FUNCTION_PARSERS,
    347            "CHAR": lambda self: self.expression(
    348                exp.Chr,
    349                expressions=self._parse_csv(self._parse_assignment),
    350                charset=self._match(TokenType.USING) and self._parse_var(),
    351            ),
    352            "GROUP_CONCAT": lambda self: self._parse_group_concat(),
    353            # https://dev.mysql.com/doc/refman/5.7/en/miscellaneous-functions.html#function_values
    354            "VALUES": lambda self: self.expression(
    355                exp.Anonymous, this="VALUES", expressions=[self._parse_id_var()]
    356            ),
    357            "JSON_VALUE": lambda self: self._parse_json_value(),
    358        }
    359
    360        STATEMENT_PARSERS = {
    361            **parser.Parser.STATEMENT_PARSERS,
    362            TokenType.SHOW: lambda self: self._parse_show(),
    363        }
    364
    365        SHOW_PARSERS = {
    366            "BINARY LOGS": _show_parser("BINARY LOGS"),
    367            "MASTER LOGS": _show_parser("BINARY LOGS"),
    368            "BINLOG EVENTS": _show_parser("BINLOG EVENTS"),
    369            "CHARACTER SET": _show_parser("CHARACTER SET"),
    370            "CHARSET": _show_parser("CHARACTER SET"),
    371            "COLLATION": _show_parser("COLLATION"),
    372            "FULL COLUMNS": _show_parser("COLUMNS", target="FROM", full=True),
    373            "COLUMNS": _show_parser("COLUMNS", target="FROM"),
    374            "CREATE DATABASE": _show_parser("CREATE DATABASE", target=True),
    375            "CREATE EVENT": _show_parser("CREATE EVENT", target=True),
    376            "CREATE FUNCTION": _show_parser("CREATE FUNCTION", target=True),
    377            "CREATE PROCEDURE": _show_parser("CREATE PROCEDURE", target=True),
    378            "CREATE TABLE": _show_parser("CREATE TABLE", target=True),
    379            "CREATE TRIGGER": _show_parser("CREATE TRIGGER", target=True),
    380            "CREATE VIEW": _show_parser("CREATE VIEW", target=True),
    381            "DATABASES": _show_parser("DATABASES"),
    382            "SCHEMAS": _show_parser("DATABASES"),
    383            "ENGINE": _show_parser("ENGINE", target=True),
    384            "STORAGE ENGINES": _show_parser("ENGINES"),
    385            "ENGINES": _show_parser("ENGINES"),
    386            "ERRORS": _show_parser("ERRORS"),
    387            "EVENTS": _show_parser("EVENTS"),
    388            "FUNCTION CODE": _show_parser("FUNCTION CODE", target=True),
    389            "FUNCTION STATUS": _show_parser("FUNCTION STATUS"),
    390            "GRANTS": _show_parser("GRANTS", target="FOR"),
    391            "INDEX": _show_parser("INDEX", target="FROM"),
    392            "MASTER STATUS": _show_parser("MASTER STATUS"),
    393            "OPEN TABLES": _show_parser("OPEN TABLES"),
    394            "PLUGINS": _show_parser("PLUGINS"),
    395            "PROCEDURE CODE": _show_parser("PROCEDURE CODE", target=True),
    396            "PROCEDURE STATUS": _show_parser("PROCEDURE STATUS"),
    397            "PRIVILEGES": _show_parser("PRIVILEGES"),
    398            "FULL PROCESSLIST": _show_parser("PROCESSLIST", full=True),
    399            "PROCESSLIST": _show_parser("PROCESSLIST"),
    400            "PROFILE": _show_parser("PROFILE"),
    401            "PROFILES": _show_parser("PROFILES"),
    402            "RELAYLOG EVENTS": _show_parser("RELAYLOG EVENTS"),
    403            "REPLICAS": _show_parser("REPLICAS"),
    404            "SLAVE HOSTS": _show_parser("REPLICAS"),
    405            "REPLICA STATUS": _show_parser("REPLICA STATUS"),
    406            "SLAVE STATUS": _show_parser("REPLICA STATUS"),
    407            "GLOBAL STATUS": _show_parser("STATUS", global_=True),
    408            "SESSION STATUS": _show_parser("STATUS"),
    409            "STATUS": _show_parser("STATUS"),
    410            "TABLE STATUS": _show_parser("TABLE STATUS"),
    411            "FULL TABLES": _show_parser("TABLES", full=True),
    412            "TABLES": _show_parser("TABLES"),
    413            "TRIGGERS": _show_parser("TRIGGERS"),
    414            "GLOBAL VARIABLES": _show_parser("VARIABLES", global_=True),
    415            "SESSION VARIABLES": _show_parser("VARIABLES"),
    416            "VARIABLES": _show_parser("VARIABLES"),
    417            "WARNINGS": _show_parser("WARNINGS"),
    418        }
    419
    420        PROPERTY_PARSERS = {
    421            **parser.Parser.PROPERTY_PARSERS,
    422            "LOCK": lambda self: self._parse_property_assignment(exp.LockProperty),
    423        }
    424
    425        SET_PARSERS = {
    426            **parser.Parser.SET_PARSERS,
    427            "PERSIST": lambda self: self._parse_set_item_assignment("PERSIST"),
    428            "PERSIST_ONLY": lambda self: self._parse_set_item_assignment("PERSIST_ONLY"),
    429            "CHARACTER SET": lambda self: self._parse_set_item_charset("CHARACTER SET"),
    430            "CHARSET": lambda self: self._parse_set_item_charset("CHARACTER SET"),
    431            "NAMES": lambda self: self._parse_set_item_names(),
    432        }
    433
    434        CONSTRAINT_PARSERS = {
    435            **parser.Parser.CONSTRAINT_PARSERS,
    436            "FULLTEXT": lambda self: self._parse_index_constraint(kind="FULLTEXT"),
    437            "INDEX": lambda self: self._parse_index_constraint(),
    438            "KEY": lambda self: self._parse_index_constraint(),
    439            "SPATIAL": lambda self: self._parse_index_constraint(kind="SPATIAL"),
    440        }
    441
    442        ALTER_PARSERS = {
    443            **parser.Parser.ALTER_PARSERS,
    444            "MODIFY": lambda self: self._parse_alter_table_alter(),
    445        }
    446
    447        ALTER_ALTER_PARSERS = {
    448            **parser.Parser.ALTER_ALTER_PARSERS,
    449            "INDEX": lambda self: self._parse_alter_table_alter_index(),
    450        }
    451
    452        SCHEMA_UNNAMED_CONSTRAINTS = {
    453            *parser.Parser.SCHEMA_UNNAMED_CONSTRAINTS,
    454            "FULLTEXT",
    455            "INDEX",
    456            "KEY",
    457            "SPATIAL",
    458        }
    459
    460        PROFILE_TYPES: parser.OPTIONS_TYPE = {
    461            **dict.fromkeys(("ALL", "CPU", "IPC", "MEMORY", "SOURCE", "SWAPS"), tuple()),
    462            "BLOCK": ("IO",),
    463            "CONTEXT": ("SWITCHES",),
    464            "PAGE": ("FAULTS",),
    465        }
    466
    467        TYPE_TOKENS = {
    468            *parser.Parser.TYPE_TOKENS,
    469            TokenType.SET,
    470        }
    471
    472        ENUM_TYPE_TOKENS = {
    473            *parser.Parser.ENUM_TYPE_TOKENS,
    474            TokenType.SET,
    475        }
    476
    477        # SELECT [ ALL | DISTINCT | DISTINCTROW ] [ <OPERATION_MODIFIERS> ]
    478        OPERATION_MODIFIERS = {
    479            "HIGH_PRIORITY",
    480            "STRAIGHT_JOIN",
    481            "SQL_SMALL_RESULT",
    482            "SQL_BIG_RESULT",
    483            "SQL_BUFFER_RESULT",
    484            "SQL_NO_CACHE",
    485            "SQL_CALC_FOUND_ROWS",
    486        }
    487
    488        LOG_DEFAULTS_TO_LN = True
    489        STRING_ALIASES = True
    490        VALUES_FOLLOWED_BY_PAREN = False
    491        SUPPORTS_PARTITION_SELECTION = True
    492
    493        def _parse_generated_as_identity(
    494            self,
    495        ) -> (
    496            exp.GeneratedAsIdentityColumnConstraint
    497            | exp.ComputedColumnConstraint
    498            | exp.GeneratedAsRowColumnConstraint
    499        ):
    500            this = super()._parse_generated_as_identity()
    501
    502            if self._match_texts(("STORED", "VIRTUAL")):
    503                persisted = self._prev.text.upper() == "STORED"
    504
    505                if isinstance(this, exp.ComputedColumnConstraint):
    506                    this.set("persisted", persisted)
    507                elif isinstance(this, exp.GeneratedAsIdentityColumnConstraint):
    508                    this = self.expression(
    509                        exp.ComputedColumnConstraint, this=this.expression, persisted=persisted
    510                    )
    511
    512            return this
    513
    514        def _parse_primary_key_part(self) -> t.Optional[exp.Expression]:
    515            this = self._parse_id_var()
    516            if not self._match(TokenType.L_PAREN):
    517                return this
    518
    519            expression = self._parse_number()
    520            self._match_r_paren()
    521            return self.expression(exp.ColumnPrefix, this=this, expression=expression)
    522
    523        def _parse_index_constraint(
    524            self, kind: t.Optional[str] = None
    525        ) -> exp.IndexColumnConstraint:
    526            if kind:
    527                self._match_texts(("INDEX", "KEY"))
    528
    529            this = self._parse_id_var(any_token=False)
    530            index_type = self._match(TokenType.USING) and self._advance_any() and self._prev.text
    531            expressions = self._parse_wrapped_csv(self._parse_ordered)
    532
    533            options = []
    534            while True:
    535                if self._match_text_seq("KEY_BLOCK_SIZE"):
    536                    self._match(TokenType.EQ)
    537                    opt = exp.IndexConstraintOption(key_block_size=self._parse_number())
    538                elif self._match(TokenType.USING):
    539                    opt = exp.IndexConstraintOption(using=self._advance_any() and self._prev.text)
    540                elif self._match_text_seq("WITH", "PARSER"):
    541                    opt = exp.IndexConstraintOption(parser=self._parse_var(any_token=True))
    542                elif self._match(TokenType.COMMENT):
    543                    opt = exp.IndexConstraintOption(comment=self._parse_string())
    544                elif self._match_text_seq("VISIBLE"):
    545                    opt = exp.IndexConstraintOption(visible=True)
    546                elif self._match_text_seq("INVISIBLE"):
    547                    opt = exp.IndexConstraintOption(visible=False)
    548                elif self._match_text_seq("ENGINE_ATTRIBUTE"):
    549                    self._match(TokenType.EQ)
    550                    opt = exp.IndexConstraintOption(engine_attr=self._parse_string())
    551                elif self._match_text_seq("SECONDARY_ENGINE_ATTRIBUTE"):
    552                    self._match(TokenType.EQ)
    553                    opt = exp.IndexConstraintOption(secondary_engine_attr=self._parse_string())
    554                else:
    555                    opt = None
    556
    557                if not opt:
    558                    break
    559
    560                options.append(opt)
    561
    562            return self.expression(
    563                exp.IndexColumnConstraint,
    564                this=this,
    565                expressions=expressions,
    566                kind=kind,
    567                index_type=index_type,
    568                options=options,
    569            )
    570
    571        def _parse_show_mysql(
    572            self,
    573            this: str,
    574            target: bool | str = False,
    575            full: t.Optional[bool] = None,
    576            global_: t.Optional[bool] = None,
    577        ) -> exp.Show:
    578            if target:
    579                if isinstance(target, str):
    580                    self._match_text_seq(target)
    581                target_id = self._parse_id_var()
    582            else:
    583                target_id = None
    584
    585            log = self._parse_string() if self._match_text_seq("IN") else None
    586
    587            if this in ("BINLOG EVENTS", "RELAYLOG EVENTS"):
    588                position = self._parse_number() if self._match_text_seq("FROM") else None
    589                db = None
    590            else:
    591                position = None
    592                db = None
    593
    594                if self._match(TokenType.FROM):
    595                    db = self._parse_id_var()
    596                elif self._match(TokenType.DOT):
    597                    db = target_id
    598                    target_id = self._parse_id_var()
    599
    600            channel = self._parse_id_var() if self._match_text_seq("FOR", "CHANNEL") else None
    601
    602            like = self._parse_string() if self._match_text_seq("LIKE") else None
    603            where = self._parse_where()
    604
    605            if this == "PROFILE":
    606                types = self._parse_csv(lambda: self._parse_var_from_options(self.PROFILE_TYPES))
    607                query = self._parse_number() if self._match_text_seq("FOR", "QUERY") else None
    608                offset = self._parse_number() if self._match_text_seq("OFFSET") else None
    609                limit = self._parse_number() if self._match_text_seq("LIMIT") else None
    610            else:
    611                types, query = None, None
    612                offset, limit = self._parse_oldstyle_limit()
    613
    614            mutex = True if self._match_text_seq("MUTEX") else None
    615            mutex = False if self._match_text_seq("STATUS") else mutex
    616
    617            return self.expression(
    618                exp.Show,
    619                this=this,
    620                target=target_id,
    621                full=full,
    622                log=log,
    623                position=position,
    624                db=db,
    625                channel=channel,
    626                like=like,
    627                where=where,
    628                types=types,
    629                query=query,
    630                offset=offset,
    631                limit=limit,
    632                mutex=mutex,
    633                **{"global": global_},  # type: ignore
    634            )
    635
    636        def _parse_oldstyle_limit(
    637            self,
    638        ) -> t.Tuple[t.Optional[exp.Expression], t.Optional[exp.Expression]]:
    639            limit = None
    640            offset = None
    641            if self._match_text_seq("LIMIT"):
    642                parts = self._parse_csv(self._parse_number)
    643                if len(parts) == 1:
    644                    limit = parts[0]
    645                elif len(parts) == 2:
    646                    limit = parts[1]
    647                    offset = parts[0]
    648
    649            return offset, limit
    650
    651        def _parse_set_item_charset(self, kind: str) -> exp.Expression:
    652            this = self._parse_string() or self._parse_unquoted_field()
    653            return self.expression(exp.SetItem, this=this, kind=kind)
    654
    655        def _parse_set_item_names(self) -> exp.Expression:
    656            charset = self._parse_string() or self._parse_unquoted_field()
    657            if self._match_text_seq("COLLATE"):
    658                collate = self._parse_string() or self._parse_unquoted_field()
    659            else:
    660                collate = None
    661
    662            return self.expression(exp.SetItem, this=charset, collate=collate, kind="NAMES")
    663
    664        def _parse_type(
    665            self, parse_interval: bool = True, fallback_to_identifier: bool = False
    666        ) -> t.Optional[exp.Expression]:
    667            # mysql binary is special and can work anywhere, even in order by operations
    668            # it operates like a no paren func
    669            if self._match(TokenType.BINARY, advance=False):
    670                data_type = self._parse_types(check_func=True, allow_identifiers=False)
    671
    672                if isinstance(data_type, exp.DataType):
    673                    return self.expression(exp.Cast, this=self._parse_column(), to=data_type)
    674
    675            return super()._parse_type(
    676                parse_interval=parse_interval, fallback_to_identifier=fallback_to_identifier
    677            )
    678
    679        def _parse_group_concat(self) -> t.Optional[exp.Expression]:
    680            def concat_exprs(
    681                node: t.Optional[exp.Expression], exprs: t.List[exp.Expression]
    682            ) -> exp.Expression:
    683                if isinstance(node, exp.Distinct) and len(node.expressions) > 1:
    684                    concat_exprs = [
    685                        self.expression(exp.Concat, expressions=node.expressions, safe=True)
    686                    ]
    687                    node.set("expressions", concat_exprs)
    688                    return node
    689                if len(exprs) == 1:
    690                    return exprs[0]
    691                return self.expression(exp.Concat, expressions=args, safe=True)
    692
    693            args = self._parse_csv(self._parse_lambda)
    694
    695            if args:
    696                order = args[-1] if isinstance(args[-1], exp.Order) else None
    697
    698                if order:
    699                    # Order By is the last (or only) expression in the list and has consumed the 'expr' before it,
    700                    # remove 'expr' from exp.Order and add it back to args
    701                    args[-1] = order.this
    702                    order.set("this", concat_exprs(order.this, args))
    703
    704                this = order or concat_exprs(args[0], args)
    705            else:
    706                this = None
    707
    708            separator = self._parse_field() if self._match(TokenType.SEPARATOR) else None
    709
    710            return self.expression(exp.GroupConcat, this=this, separator=separator)
    711
    712        def _parse_json_value(self) -> exp.JSONValue:
    713            this = self._parse_bitwise()
    714            self._match(TokenType.COMMA)
    715            path = self._parse_bitwise()
    716
    717            returning = self._match(TokenType.RETURNING) and self._parse_type()
    718
    719            return self.expression(
    720                exp.JSONValue,
    721                this=this,
    722                path=self.dialect.to_json_path(path),
    723                returning=returning,
    724                on_condition=self._parse_on_condition(),
    725            )
    726
    727        def _parse_alter_table_alter_index(self) -> exp.AlterIndex:
    728            index = self._parse_field(any_token=True)
    729
    730            if self._match_text_seq("VISIBLE"):
    731                visible = True
    732            elif self._match_text_seq("INVISIBLE"):
    733                visible = False
    734            else:
    735                visible = None
    736
    737            return self.expression(exp.AlterIndex, this=index, visible=visible)

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.ILIKE: 'ILIKE'>, <TokenType.VARCHAR: 'VARCHAR'>, <TokenType.DATABASE: 'DATABASE'>, <TokenType.UNNEST: 'UNNEST'>, <TokenType.CHAR: 'CHAR'>, <TokenType.HSTORE: 'HSTORE'>, <TokenType.MAP: 'MAP'>, <TokenType.VALUES: 'VALUES'>, <TokenType.SIMPLEAGGREGATEFUNCTION: 'SIMPLEAGGREGATEFUNCTION'>, <TokenType.STRUCT: 'STRUCT'>, <TokenType.OFFSET: 'OFFSET'>, <TokenType.UINT128: 'UINT128'>, <TokenType.UDOUBLE: 'UDOUBLE'>, <TokenType.LIKE: 'LIKE'>, <TokenType.LOWCARDINALITY: 'LOWCARDINALITY'>, <TokenType.ROWVERSION: 'ROWVERSION'>, <TokenType.XML: 'XML'>, <TokenType.BIGINT: 'BIGINT'>, <TokenType.SMALLMONEY: 'SMALLMONEY'>, <TokenType.TIMESTAMP_S: 'TIMESTAMP_S'>, <TokenType.INTERVAL: 'INTERVAL'>, <TokenType.TIME: 'TIME'>, <TokenType.TSTZRANGE: 'TSTZRANGE'>, <TokenType.DATERANGE: 'DATERANGE'>, <TokenType.VECTOR: 'VECTOR'>, <TokenType.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, <TokenType.TIMESTAMPNTZ: 'TIMESTAMPNTZ'>, <TokenType.JSON: 'JSON'>, <TokenType.VAR: 'VAR'>, <TokenType.INSERT: 'INSERT'>, <TokenType.MULTIPOLYGON: 'MULTIPOLYGON'>, <TokenType.FILTER: 'FILTER'>, <TokenType.INT128: 'INT128'>, <TokenType.FORMAT: 'FORMAT'>, <TokenType.DATETIME: 'DATETIME'>, <TokenType.REPLACE: 'REPLACE'>, <TokenType.UINT: 'UINT'>, <TokenType.DOUBLE: 'DOUBLE'>, <TokenType.ARRAY: 'ARRAY'>, <TokenType.BIT: 'BIT'>, <TokenType.TINYBLOB: 'TINYBLOB'>, <TokenType.UTINYINT: 'UTINYINT'>, <TokenType.COMMAND: 'COMMAND'>, <TokenType.NCHAR: 'NCHAR'>, <TokenType.IDENTIFIER: 'IDENTIFIER'>, <TokenType.UMEDIUMINT: 'UMEDIUMINT'>, <TokenType.MEDIUMTEXT: 'MEDIUMTEXT'>, <TokenType.BLOB: 'BLOB'>, <TokenType.MEDIUMBLOB: 'MEDIUMBLOB'>, <TokenType.UUID: 'UUID'>, <TokenType.LINESTRING: 'LINESTRING'>, <TokenType.NOTHING: 'NOTHING'>, <TokenType.FLOAT: 'FLOAT'>, <TokenType.ANY: 'ANY'>, <TokenType.SMALLINT: 'SMALLINT'>, <TokenType.TRUNCATE: 'TRUNCATE'>, <TokenType.IMAGE: 'IMAGE'>, <TokenType.NESTED: 'NESTED'>, <TokenType.TIMESTAMP_MS: 'TIMESTAMP_MS'>, <TokenType.TIMETZ: 'TIMETZ'>, <TokenType.IPADDRESS: 'IPADDRESS'>, <TokenType.FIXEDSTRING: 'FIXEDSTRING'>, <TokenType.NEXT: 'NEXT'>, <TokenType.ROW: 'ROW'>, <TokenType.INT8MULTIRANGE: 'INT8MULTIRANGE'>, <TokenType.TSMULTIRANGE: 'TSMULTIRANGE'>, <TokenType.RLIKE: 'RLIKE'>, <TokenType.IPPREFIX: 'IPPREFIX'>, <TokenType.DATE32: 'DATE32'>, <TokenType.NVARCHAR: 'NVARCHAR'>, <TokenType.RIGHT: 'RIGHT'>, <TokenType.MERGE: 'MERGE'>, <TokenType.LONGBLOB: 'LONGBLOB'>, <TokenType.DECIMAL: 'DECIMAL'>, <TokenType.USMALLINT: 'USMALLINT'>, <TokenType.CURRENT_SCHEMA: 'CURRENT_SCHEMA'>, <TokenType.TABLE: 'TABLE'>, <TokenType.DYNAMIC: 'DYNAMIC'>, <TokenType.OBJECT_IDENTIFIER: 'OBJECT_IDENTIFIER'>, <TokenType.TINYINT: 'TINYINT'>, <TokenType.ENUM: 'ENUM'>, <TokenType.CURRENT_USER: 'CURRENT_USER'>, <TokenType.ISNULL: 'ISNULL'>, <TokenType.DATEMULTIRANGE: 'DATEMULTIRANGE'>, <TokenType.XOR: 'XOR'>, <TokenType.SEQUENCE: 'SEQUENCE'>, <TokenType.OBJECT: 'OBJECT'>, <TokenType.TSRANGE: 'TSRANGE'>, <TokenType.BINARY: 'BINARY'>, <TokenType.RING: 'RING'>, <TokenType.RANGE: 'RANGE'>, <TokenType.INT4RANGE: 'INT4RANGE'>, <TokenType.MEDIUMINT: 'MEDIUMINT'>, <TokenType.TEXT: 'TEXT'>, <TokenType.ENUM16: 'ENUM16'>, <TokenType.SMALLDATETIME: 'SMALLDATETIME'>, <TokenType.INT4MULTIRANGE: 'INT4MULTIRANGE'>, <TokenType.GET: 'GET'>, <TokenType.POINT: 'POINT'>, <TokenType.DECIMAL128: 'DECIMAL128'>, <TokenType.UINT256: 'UINT256'>, <TokenType.POLYGON: 'POLYGON'>, <TokenType.TINYTEXT: 'TINYTEXT'>, <TokenType.TIMESTAMP_NS: 'TIMESTAMP_NS'>, <TokenType.CURRENT_TIME: 'CURRENT_TIME'>, <TokenType.FIRST: 'FIRST'>, <TokenType.DECIMAL32: 'DECIMAL32'>, <TokenType.VARIANT: 'VARIANT'>, <TokenType.CURRENT_DATETIME: 'CURRENT_DATETIME'>, <TokenType.GEOGRAPHY: 'GEOGRAPHY'>, <TokenType.ALL: 'ALL'>, <TokenType.LEFT: 'LEFT'>, <TokenType.LONGTEXT: 'LONGTEXT'>, <TokenType.NUMMULTIRANGE: 'NUMMULTIRANGE'>, <TokenType.NULL: 'NULL'>, <TokenType.TDIGEST: 'TDIGEST'>, <TokenType.CURRENT_TIMESTAMP: 'CURRENT_TIMESTAMP'>, <TokenType.UNKNOWN: 'UNKNOWN'>, <TokenType.UDECIMAL: 'UDECIMAL'>, <TokenType.NUMRANGE: 'NUMRANGE'>, <TokenType.INDEX: 'INDEX'>, <TokenType.LIST: 'LIST'>, <TokenType.WINDOW: 'WINDOW'>, <TokenType.SUPER: 'SUPER'>, <TokenType.DATETIME64: 'DATETIME64'>, <TokenType.GEOMETRY: 'GEOMETRY'>, <TokenType.TSTZMULTIRANGE: 'TSTZMULTIRANGE'>, <TokenType.SERIAL: 'SERIAL'>, <TokenType.DECIMAL256: 'DECIMAL256'>, <TokenType.ENUM8: 'ENUM8'>, <TokenType.INET: 'INET'>, <TokenType.INT8RANGE: 'INT8RANGE'>, <TokenType.VOID: 'VOID'>, <TokenType.SCHEMA: 'SCHEMA'>, <TokenType.TIMESTAMP: 'TIMESTAMP'>, <TokenType.NAME: 'NAME'>, <TokenType.GLOB: 'GLOB'>, <TokenType.MONEY: 'MONEY'>, <TokenType.DECIMAL64: 'DECIMAL64'>, <TokenType.HLLSKETCH: 'HLLSKETCH'>, <TokenType.INT: 'INT'>, <TokenType.BOOLEAN: 'BOOLEAN'>, <TokenType.PSEUDO_TYPE: 'PSEUDO_TYPE'>, <TokenType.YEAR: 'YEAR'>, <TokenType.INT256: 'INT256'>, <TokenType.USERDEFINED: 'USERDEFINED'>, <TokenType.UBIGINT: 'UBIGINT'>, <TokenType.BPCHAR: 'BPCHAR'>, <TokenType.JSONB: 'JSONB'>, <TokenType.DATE: 'DATE'>, <TokenType.COLLATE: 'COLLATE'>, <TokenType.IPV4: 'IPV4'>, <TokenType.SMALLSERIAL: 'SMALLSERIAL'>, <TokenType.UNION: 'UNION'>, <TokenType.DATETIME2: 'DATETIME2'>, <TokenType.BIGDECIMAL: 'BIGDECIMAL'>, <TokenType.AGGREGATEFUNCTION: 'AGGREGATEFUNCTION'>, <TokenType.VARBINARY: 'VARBINARY'>, <TokenType.SOME: 'SOME'>, <TokenType.MULTILINESTRING: 'MULTILINESTRING'>, <TokenType.IPV6: 'IPV6'>, <TokenType.CURRENT_DATE: 'CURRENT_DATE'>, <TokenType.TIMESTAMPTZ: 'TIMESTAMPTZ'>, <TokenType.EXISTS: 'EXISTS'>, <TokenType.PRIMARY_KEY: 'PRIMARY_KEY'>, <TokenType.NULLABLE: 'NULLABLE'>, <TokenType.BIGSERIAL: 'BIGSERIAL'>}
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.SHOW: 'SHOW'>, <TokenType.VARCHAR: 'VARCHAR'>, <TokenType.SINK: 'SINK'>, <TokenType.ESCAPE: 'ESCAPE'>, <TokenType.DATABASE: 'DATABASE'>, <TokenType.UNNEST: 'UNNEST'>, <TokenType.CHAR: 'CHAR'>, <TokenType.HSTORE: 'HSTORE'>, <TokenType.MAP: 'MAP'>, <TokenType.COMMIT: 'COMMIT'>, <TokenType.SIMPLEAGGREGATEFUNCTION: 'SIMPLEAGGREGATEFUNCTION'>, <TokenType.RENAME: 'RENAME'>, <TokenType.STRUCT: 'STRUCT'>, <TokenType.OFFSET: 'OFFSET'>, <TokenType.UINT128: 'UINT128'>, <TokenType.STAGE: 'STAGE'>, <TokenType.OPERATOR: 'OPERATOR'>, <TokenType.UDOUBLE: 'UDOUBLE'>, <TokenType.LOWCARDINALITY: 'LOWCARDINALITY'>, <TokenType.DIV: 'DIV'>, <TokenType.ROWVERSION: 'ROWVERSION'>, <TokenType.REFRESH: 'REFRESH'>, <TokenType.XML: 'XML'>, <TokenType.BIGINT: 'BIGINT'>, <TokenType.UPDATE: 'UPDATE'>, <TokenType.REFERENCES: 'REFERENCES'>, <TokenType.SMALLMONEY: 'SMALLMONEY'>, <TokenType.TIMESTAMP_S: 'TIMESTAMP_S'>, <TokenType.PUT: 'PUT'>, <TokenType.VIEW: 'VIEW'>, <TokenType.INTERVAL: 'INTERVAL'>, <TokenType.TIME: 'TIME'>, <TokenType.TSTZRANGE: 'TSTZRANGE'>, <TokenType.DATERANGE: 'DATERANGE'>, <TokenType.IS: 'IS'>, <TokenType.VECTOR: 'VECTOR'>, <TokenType.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, <TokenType.BEGIN: 'BEGIN'>, <TokenType.TIMESTAMPNTZ: 'TIMESTAMPNTZ'>, <TokenType.JSON: 'JSON'>, <TokenType.VAR: 'VAR'>, <TokenType.CUBE: 'CUBE'>, <TokenType.MULTIPOLYGON: 'MULTIPOLYGON'>, <TokenType.AUTO_INCREMENT: 'AUTO_INCREMENT'>, <TokenType.FILTER: 'FILTER'>, <TokenType.UNPIVOT: 'UNPIVOT'>, <TokenType.SOURCE: 'SOURCE'>, <TokenType.INT128: 'INT128'>, <TokenType.CACHE: 'CACHE'>, <TokenType.FORMAT: 'FORMAT'>, <TokenType.DATETIME: 'DATETIME'>, <TokenType.REPLACE: 'REPLACE'>, <TokenType.PERCENT: 'PERCENT'>, <TokenType.UINT: 'UINT'>, <TokenType.DOUBLE: 'DOUBLE'>, <TokenType.ARRAY: 'ARRAY'>, <TokenType.BIT: 'BIT'>, <TokenType.COPY: 'COPY'>, <TokenType.TINYBLOB: 'TINYBLOB'>, <TokenType.UTINYINT: 'UTINYINT'>, <TokenType.COMMAND: 'COMMAND'>, <TokenType.LIMIT: 'LIMIT'>, <TokenType.NCHAR: 'NCHAR'>, <TokenType.IDENTIFIER: 'IDENTIFIER'>, <TokenType.VOLATILE: 'VOLATILE'>, <TokenType.UMEDIUMINT: 'UMEDIUMINT'>, <TokenType.MEDIUMTEXT: 'MEDIUMTEXT'>, <TokenType.BLOB: 'BLOB'>, <TokenType.MEDIUMBLOB: 'MEDIUMBLOB'>, <TokenType.UUID: 'UUID'>, <TokenType.LINESTRING: 'LINESTRING'>, <TokenType.CASE: 'CASE'>, <TokenType.EXPORT: 'EXPORT'>, <TokenType.NOTHING: 'NOTHING'>, <TokenType.FLOAT: 'FLOAT'>, <TokenType.ANY: 'ANY'>, <TokenType.SMALLINT: 'SMALLINT'>, <TokenType.FINAL: 'FINAL'>, <TokenType.TRUNCATE: 'TRUNCATE'>, <TokenType.END: 'END'>, <TokenType.IMAGE: 'IMAGE'>, <TokenType.NESTED: 'NESTED'>, <TokenType.NAMESPACE: 'NAMESPACE'>, <TokenType.EXECUTE: 'EXECUTE'>, <TokenType.CONSTRAINT: 'CONSTRAINT'>, <TokenType.TIMESTAMP_MS: 'TIMESTAMP_MS'>, <TokenType.TIMETZ: 'TIMETZ'>, <TokenType.IPADDRESS: 'IPADDRESS'>, <TokenType.FIXEDSTRING: 'FIXEDSTRING'>, <TokenType.NEXT: 'NEXT'>, <TokenType.ROW: 'ROW'>, <TokenType.INT8MULTIRANGE: 'INT8MULTIRANGE'>, <TokenType.TSMULTIRANGE: 'TSMULTIRANGE'>, <TokenType.ORDINALITY: 'ORDINALITY'>, <TokenType.IPPREFIX: 'IPPREFIX'>, <TokenType.DATE32: 'DATE32'>, <TokenType.NVARCHAR: 'NVARCHAR'>, <TokenType.LONGBLOB: 'LONGBLOB'>, <TokenType.MERGE: 'MERGE'>, <TokenType.DECIMAL: 'DECIMAL'>, <TokenType.USMALLINT: 'USMALLINT'>, <TokenType.CURRENT_SCHEMA: 'CURRENT_SCHEMA'>, <TokenType.TABLE: 'TABLE'>, <TokenType.DYNAMIC: 'DYNAMIC'>, <TokenType.ASC: 'ASC'>, <TokenType.DESCRIBE: 'DESCRIBE'>, <TokenType.FALSE: 'FALSE'>, <TokenType.OBJECT_IDENTIFIER: 'OBJECT_IDENTIFIER'>, <TokenType.PIVOT: 'PIVOT'>, <TokenType.COLUMN: 'COLUMN'>, <TokenType.TINYINT: 'TINYINT'>, <TokenType.ENUM: 'ENUM'>, <TokenType.CURRENT_USER: 'CURRENT_USER'>, <TokenType.SEMI: 'SEMI'>, <TokenType.FOREIGN_KEY: 'FOREIGN_KEY'>, <TokenType.STREAMLIT: 'STREAMLIT'>, <TokenType.ISNULL: 'ISNULL'>, <TokenType.DATEMULTIRANGE: 'DATEMULTIRANGE'>, <TokenType.SEQUENCE: 'SEQUENCE'>, <TokenType.PRAGMA: 'PRAGMA'>, <TokenType.FUNCTION: 'FUNCTION'>, <TokenType.OBJECT: 'OBJECT'>, <TokenType.TSRANGE: 'TSRANGE'>, <TokenType.FILE_FORMAT: 'FILE_FORMAT'>, <TokenType.OVERWRITE: 'OVERWRITE'>, <TokenType.ANTI: 'ANTI'>, <TokenType.BINARY: 'BINARY'>, <TokenType.RING: 'RING'>, <TokenType.TAG: 'TAG'>, <TokenType.RANGE: 'RANGE'>, <TokenType.MODEL: 'MODEL'>, <TokenType.INT4RANGE: 'INT4RANGE'>, <TokenType.MEDIUMINT: 'MEDIUMINT'>, <TokenType.TEXT: 'TEXT'>, <TokenType.ENUM16: 'ENUM16'>, <TokenType.SMALLDATETIME: 'SMALLDATETIME'>, <TokenType.UNIQUE: 'UNIQUE'>, <TokenType.INT4MULTIRANGE: 'INT4MULTIRANGE'>, <TokenType.GET: 'GET'>, <TokenType.POINT: 'POINT'>, <TokenType.DECIMAL128: 'DECIMAL128'>, <TokenType.TOP: 'TOP'>, <TokenType.UINT256: 'UINT256'>, <TokenType.POLYGON: 'POLYGON'>, <TokenType.TINYTEXT: 'TINYTEXT'>, <TokenType.LOAD: 'LOAD'>, <TokenType.TIMESTAMP_NS: 'TIMESTAMP_NS'>, <TokenType.ROWS: 'ROWS'>, <TokenType.DECIMAL32: 'DECIMAL32'>, <TokenType.FIRST: 'FIRST'>, <TokenType.VARIANT: 'VARIANT'>, <TokenType.CURRENT_TIME: 'CURRENT_TIME'>, <TokenType.TRUE: 'TRUE'>, <TokenType.CURRENT_DATETIME: 'CURRENT_DATETIME'>, <TokenType.COMMENT: 'COMMENT'>, <TokenType.PROCEDURE: 'PROCEDURE'>, <TokenType.GEOGRAPHY: 'GEOGRAPHY'>, <TokenType.ALL: 'ALL'>, <TokenType.KILL: 'KILL'>, <TokenType.LONGTEXT: 'LONGTEXT'>, <TokenType.NUMMULTIRANGE: 'NUMMULTIRANGE'>, <TokenType.NULL: 'NULL'>, <TokenType.TDIGEST: 'TDIGEST'>, <TokenType.UNKNOWN: 'UNKNOWN'>, <TokenType.CURRENT_TIMESTAMP: 'CURRENT_TIMESTAMP'>, <TokenType.UDECIMAL: 'UDECIMAL'>, <TokenType.SET: 'SET'>, <TokenType.NUMRANGE: 'NUMRANGE'>, <TokenType.INDEX: 'INDEX'>, <TokenType.LIST: 'LIST'>, <TokenType.SETTINGS: 'SETTINGS'>, <TokenType.SUPER: 'SUPER'>, <TokenType.DATETIME64: 'DATETIME64'>, <TokenType.STORAGE_INTEGRATION: 'STORAGE_INTEGRATION'>, <TokenType.GEOMETRY: 'GEOMETRY'>, <TokenType.TSTZMULTIRANGE: 'TSTZMULTIRANGE'>, <TokenType.SERIAL: 'SERIAL'>, <TokenType.DECIMAL256: 'DECIMAL256'>, <TokenType.DEFAULT: 'DEFAULT'>, <TokenType.ENUM8: 'ENUM8'>, <TokenType.INET: 'INET'>, <TokenType.INT8RANGE: 'INT8RANGE'>, <TokenType.VOID: 'VOID'>, <TokenType.SCHEMA: 'SCHEMA'>, <TokenType.TIMESTAMP: 'TIMESTAMP'>, <TokenType.NAME: 'NAME'>, <TokenType.ROLLUP: 'ROLLUP'>, <TokenType.MONEY: 'MONEY'>, <TokenType.DECIMAL64: 'DECIMAL64'>, <TokenType.HLLSKETCH: 'HLLSKETCH'>, <TokenType.PARTITION: 'PARTITION'>, <TokenType.INT: 'INT'>, <TokenType.RECURSIVE: 'RECURSIVE'>, <TokenType.BOOLEAN: 'BOOLEAN'>, <TokenType.DETACH: 'DETACH'>, <TokenType.TEMPORARY: 'TEMPORARY'>, <TokenType.PSEUDO_TYPE: 'PSEUDO_TYPE'>, <TokenType.YEAR: 'YEAR'>, <TokenType.INT256: 'INT256'>, <TokenType.DELETE: 'DELETE'>, <TokenType.USERDEFINED: 'USERDEFINED'>, <TokenType.BPCHAR: 'BPCHAR'>, <TokenType.UBIGINT: 'UBIGINT'>, <TokenType.JSONB: 'JSONB'>, <TokenType.COLLATE: 'COLLATE'>, <TokenType.DATE: 'DATE'>, <TokenType.IPV4: 'IPV4'>, <TokenType.ATTACH: 'ATTACH'>, <TokenType.SMALLSERIAL: 'SMALLSERIAL'>, <TokenType.KEEP: 'KEEP'>, <TokenType.DATETIME2: 'DATETIME2'>, <TokenType.BIGDECIMAL: 'BIGDECIMAL'>, <TokenType.AGGREGATEFUNCTION: 'AGGREGATEFUNCTION'>, <TokenType.VARBINARY: 'VARBINARY'>, <TokenType.SOME: 'SOME'>, <TokenType.MULTILINESTRING: 'MULTILINESTRING'>, <TokenType.OVERLAPS: 'OVERLAPS'>, <TokenType.DESC: 'DESC'>, <TokenType.WAREHOUSE: 'WAREHOUSE'>, <TokenType.IPV6: 'IPV6'>, <TokenType.CURRENT_DATE: 'CURRENT_DATE'>, <TokenType.DICTIONARY: 'DICTIONARY'>, <TokenType.TIMESTAMPTZ: 'TIMESTAMPTZ'>, <TokenType.EXISTS: 'EXISTS'>, <TokenType.NULLABLE: 'NULLABLE'>, <TokenType.BIGSERIAL: 'BIGSERIAL'>}
RANGE_PARSERS = {<TokenType.AT_GT: 'AT_GT'>: <function binary_range_parser.<locals>._parse_binary_range>, <TokenType.BETWEEN: 'BETWEEN'>: <function Parser.<lambda>>, <TokenType.GLOB: 'GLOB'>: <function binary_range_parser.<locals>._parse_binary_range>, <TokenType.ILIKE: 'ILIKE'>: <function binary_range_parser.<locals>._parse_binary_range>, <TokenType.IN: 'IN'>: <function Parser.<lambda>>, <TokenType.IRLIKE: 'IRLIKE'>: <function binary_range_parser.<locals>._parse_binary_range>, <TokenType.IS: 'IS'>: <function Parser.<lambda>>, <TokenType.LIKE: 'LIKE'>: <function binary_range_parser.<locals>._parse_binary_range>, <TokenType.LT_AT: 'LT_AT'>: <function binary_range_parser.<locals>._parse_binary_range>, <TokenType.OVERLAPS: 'OVERLAPS'>: <function binary_range_parser.<locals>._parse_binary_range>, <TokenType.RLIKE: 'RLIKE'>: <function binary_range_parser.<locals>._parse_binary_range>, <TokenType.SIMILAR_TO: 'SIMILAR_TO'>: <function binary_range_parser.<locals>._parse_binary_range>, <TokenType.FOR: 'FOR'>: <function Parser.<lambda>>, <TokenType.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'>>, 'AND': <bound method Func.from_arg_list of <class 'sqlglot.expressions.And'>>, 'ANONYMOUS_AGG_FUNC': <bound method Func.from_arg_list of <class 'sqlglot.expressions.AnonymousAggFunc'>>, 'ANY_VALUE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.AnyValue'>>, 'APPLY': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Apply'>>, 'APPROX_DISTINCT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ApproxDistinct'>>, 'APPROX_COUNT_DISTINCT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ApproxDistinct'>>, 'APPROX_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': <function Parser.<lambda>>, 'ARRAY_ALL': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArrayAll'>>, 'ARRAY_ANY': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArrayAny'>>, 'ARRAY_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_CONCAT_AGG': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArrayConcatAgg'>>, 'ARRAY_CONSTRUCT_COMPACT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArrayConstructCompact'>>, 'ARRAY_CONTAINS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArrayContains'>>, 'ARRAY_HAS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArrayContains'>>, 'ARRAY_CONTAINS_ALL': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArrayContainsAll'>>, 'ARRAY_HAS_ALL': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArrayContainsAll'>>, 'FILTER': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArrayFilter'>>, 'ARRAY_FILTER': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArrayFilter'>>, 'ARRAY_INTERSECT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArrayIntersect'>>, 'ARRAY_INTERSECTION': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArrayIntersect'>>, 'ARRAY_OVERLAPS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArrayOverlaps'>>, 'ARRAY_REMOVE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArrayRemove'>>, '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': <function Parser.<lambda>>, 'CHAR': <function Parser.<lambda>>, 'COALESCE': <function build_coalesce>, 'IFNULL': <function build_coalesce>, 'NVL': <function build_coalesce>, 'COLLATE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Collate'>>, 'COLUMNS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Columns'>>, 'COMBINED_AGG_FUNC': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CombinedAggFunc'>>, 'COMBINED_PARAMETERIZED_AGG': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CombinedParameterizedAgg'>>, 'CONCAT': <function Parser.<lambda>>, 'CONCAT_WS': <function Parser.<lambda>>, 'CONNECT_BY_ROOT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ConnectByRoot'>>, 'CONTAINS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Contains'>>, 'CONVERT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Convert'>>, 'CONVERT_TIMEZONE': <function build_convert_timezone>, 'CONVERT_TO_CHARSET': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ConvertToCharset'>>, 'CORR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Corr'>>, 'COUNT': <function Parser.<lambda>>, 'COUNT_IF': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CountIf'>>, 'COUNTIF': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CountIf'>>, 'COVAR_POP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CovarPop'>>, 'COVAR_SAMP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CovarSamp'>>, '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_SCHEMA': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CurrentSchema'>>, '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>, 'DATE_BIN': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DateBin'>>, 'DATEDIFF': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DateDiff'>>, 'DATE_DIFF': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DateDiff'>>, 'DATE_FROM_PARTS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DateFromParts'>>, 'DATEFROMPARTS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DateFromParts'>>, 'DATE_STR_TO_DATE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DateStrToDate'>>, 'DATE_SUB': <function build_date_delta_with_interval.<locals>._builder>, 'DATE_TO_DATE_STR': <function Parser.<lambda>>, 'DATE_TO_DI': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DateToDi'>>, 'DATE_TRUNC': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DateTrunc'>>, 'DATETIME': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Datetime'>>, 'DATETIME_ADD': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DatetimeAdd'>>, 'DATETIME_DIFF': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DatetimeDiff'>>, 'DATETIME_SUB': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DatetimeSub'>>, 'DATETIME_TRUNC': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DatetimeTrunc'>>, 'DAY': <function MySQL.Parser.<lambda>>, 'DAY_OF_MONTH': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DayOfMonth'>>, 'DAYOFMONTH': <function MySQL.Parser.<lambda>>, 'DAY_OF_WEEK': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DayOfWeek'>>, 'DAYOFWEEK': <function MySQL.Parser.<lambda>>, 'DAYOFWEEK_ISO': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DayOfWeekIso'>>, 'ISODOW': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DayOfWeekIso'>>, 'DAY_OF_YEAR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DayOfYear'>>, 'DAYOFYEAR': <function MySQL.Parser.<lambda>>, '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'>>, 'ENDS_WITH': <bound method Func.from_arg_list of <class 'sqlglot.expressions.EndsWith'>>, 'ENDSWITH': <bound method Func.from_arg_list of <class 'sqlglot.expressions.EndsWith'>>, 'EXISTS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Exists'>>, 'EXP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Exp'>>, 'EXPLODE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Explode'>>, 'EXPLODE_OUTER': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ExplodeOuter'>>, 'EXPLODING_GENERATE_SERIES': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ExplodingGenerateSeries'>>, 'EXTRACT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Extract'>>, 'FEATURES_AT_TIME': <bound method Func.from_arg_list of <class 'sqlglot.expressions.FeaturesAtTime'>>, 'FIRST': <bound method Func.from_arg_list of <class 'sqlglot.expressions.First'>>, 'FIRST_VALUE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.FirstValue'>>, 'FLATTEN': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Flatten'>>, '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'>>, 'INLINE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Inline'>>, 'INT64': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Int64'>>, 'IS_ASCII': <bound method Func.from_arg_list of <class 'sqlglot.expressions.IsAscii'>>, 'IS_INF': <bound method Func.from_arg_list of <class 'sqlglot.expressions.IsInf'>>, 'ISINF': <bound method Func.from_arg_list of <class 'sqlglot.expressions.IsInf'>>, 'IS_NAN': <bound method Func.from_arg_list of <class 'sqlglot.expressions.IsNan'>>, 'ISNAN': <bound method Func.from_arg_list of <class 'sqlglot.expressions.IsNan'>>, '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_EXISTS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONBExists'>>, 'JSONB_EXTRACT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONBExtract'>>, 'JSONB_EXTRACT_SCALAR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONBExtractScalar'>>, 'J_S_O_N_B_OBJECT_AGG': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONBObjectAgg'>>, 'J_S_O_N_CAST': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONCast'>>, 'J_S_O_N_EXISTS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONExists'>>, 'JSON_EXTRACT': <function build_extract_json_with_path.<locals>._builder>, 'JSON_EXTRACT_ARRAY': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONExtractArray'>>, 'JSON_EXTRACT_SCALAR': <function build_extract_json_with_path.<locals>._builder>, 'JSON_FORMAT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONFormat'>>, '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'>>, 'J_S_O_N_VALUE_ARRAY': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONValueArray'>>, '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': <function MySQL.Parser.<lambda>>, 'LEN': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Length'>>, 'CHAR_LENGTH': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Length'>>, 'CHARACTER_LENGTH': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Length'>>, 'LEVENSHTEIN': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Levenshtein'>>, 'LIST': <bound method Func.from_arg_list of <class 'sqlglot.expressions.List'>>, 'LN': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Ln'>>, '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'>>, 'MAKE_INTERVAL': <bound method Func.from_arg_list of <class 'sqlglot.expressions.MakeInterval'>>, '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'>>, 'MEDIAN': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Median'>>, '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'>>, 'NORMALIZE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Normalize'>>, 'NTH_VALUE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.NthValue'>>, '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'>>, 'OR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Or'>>, 'OVERLAY': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Overlay'>>, 'PAD': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Pad'>>, 'PARAMETERIZED_AGG': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ParameterizedAgg'>>, 'PARSE_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_EXTRACT_ALL': <bound method Func.from_arg_list of <class 'sqlglot.expressions.RegexpExtractAll'>>, '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'>>, 'SPLIT_PART': <bound method Func.from_arg_list of <class 'sqlglot.expressions.SplitPart'>>, 'SQRT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Sqrt'>>, 'ST_DISTANCE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StDistance'>>, 'ST_POINT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StPoint'>>, 'ST_MAKEPOINT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StPoint'>>, 'STANDARD_HASH': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StandardHash'>>, 'STAR_MAP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StarMap'>>, 'STARTS_WITH': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StartsWith'>>, 'STARTSWITH': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StartsWith'>>, 'STDDEV': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Stddev'>>, 'STDEV': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Stddev'>>, 'STDDEV_POP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StddevPop'>>, 'STDDEV_SAMP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StddevSamp'>>, 'STR_POSITION': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StrPosition'>>, 'STR_TO_DATE': <function _str_to_date>, 'STR_TO_MAP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StrToMap'>>, 'STR_TO_TIME': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StrToTime'>>, 'STR_TO_UNIX': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StrToUnix'>>, 'STRING': <bound method Func.from_arg_list of <class 'sqlglot.expressions.String'>>, 'STRING_TO_ARRAY': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StringToArray'>>, 'SPLIT_BY_STRING': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StringToArray'>>, 'STRTOK_TO_ARRAY': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StringToArray'>>, 'STRUCT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Struct'>>, 'STRUCT_EXTRACT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StructExtract'>>, 'STUFF': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Stuff'>>, 'INSERT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Stuff'>>, 'SUBSTRING': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Substring'>>, 'SUBSTR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Substring'>>, '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_DOUBLE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ToDouble'>>, '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_DATETIME': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TsOrDsToDatetime'>>, 'TS_OR_DS_TO_TIME': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TsOrDsToTime'>>, 'TS_OR_DS_TO_TIMESTAMP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TsOrDsToTimestamp'>>, 'UNHEX': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Unhex'>>, 'UNICODE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Unicode'>>, 'UNIX_DATE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.UnixDate'>>, 'UNIX_SECONDS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.UnixSeconds'>>, 'UNIX_TO_STR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.UnixToStr'>>, 'UNIX_TO_TIME': <bound method Func.from_arg_list of <class 'sqlglot.expressions.UnixToTime'>>, 'UNIX_TO_TIME_STR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.UnixToTimeStr'>>, 'UNNEST': <function Parser.<lambda>>, 'UPPER': <function build_upper>, 'UCASE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Upper'>>, 'UUID': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Uuid'>>, 'GEN_RANDOM_UUID': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Uuid'>>, 'GENERATE_UUID': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Uuid'>>, 'UUID_STRING': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Uuid'>>, 'VAR_MAP': <function build_var_map>, 'VARIANCE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Variance'>>, 'VARIANCE_SAMP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Variance'>>, 'VAR_SAMP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Variance'>>, 'VARIANCE_POP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.VariancePop'>>, 'VAR_POP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.VariancePop'>>, 'WEEK': <function MySQL.Parser.<lambda>>, 'WEEK_OF_YEAR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.WeekOfYear'>>, 'WEEKOFYEAR': <function MySQL.Parser.<lambda>>, 'XMLELEMENT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.XMLElement'>>, '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>>, 'ARRAYAGG': <function Parser.<lambda>>, 'GLOB': <function Parser.<lambda>>, 'JSON_EXTRACT_PATH_TEXT': <function build_extract_json_with_path.<locals>._builder>, 'LIKE': <function build_like>, 'LOG2': <function Parser.<lambda>>, 'LOG10': <function Parser.<lambda>>, 'LPAD': <function Parser.<lambda>>, 'LEFTPAD': <function Parser.<lambda>>, 'LTRIM': <function Parser.<lambda>>, 'MOD': <function build_mod>, 'RIGHTPAD': <function Parser.<lambda>>, 'RPAD': <function Parser.<lambda>>, 'RTRIM': <function Parser.<lambda>>, 'SCOPE_RESOLUTION': <function Parser.<lambda>>, 'STRPOS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StrPosition'>>, 'CHARINDEX': <function Parser.<lambda>>, 'INSTR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StrPosition'>>, 'LOCATE': <function Parser.<lambda>>, 'TO_HEX': <function build_hex>, 'CONVERT_TZ': <function MySQL.Parser.<lambda>>, 'CURDATE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CurrentDate'>>, 'DATE_FORMAT': <function build_formatted_time.<locals>._builder>, 'FORMAT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.NumberToStr'>>, 'FROM_UNIXTIME': <function build_formatted_time.<locals>._builder>, 'ISNULL': <function isnull_to_is_null>, 'MAKETIME': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimeFromParts'>>, 'MONTHNAME': <function MySQL.Parser.<lambda>>, 'SCHEMA': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CurrentSchema'>>, 'DATABASE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CurrentSchema'>>}
FUNCTION_PARSERS = {'ARG_MAX': <function Parser.<dictcomp>.<lambda>>, 'ARGMAX': <function Parser.<dictcomp>.<lambda>>, 'MAX_BY': <function Parser.<dictcomp>.<lambda>>, 'ARG_MIN': <function Parser.<dictcomp>.<lambda>>, 'ARGMIN': <function Parser.<dictcomp>.<lambda>>, 'MIN_BY': <function Parser.<dictcomp>.<lambda>>, 'CAST': <function Parser.<lambda>>, 'CEIL': <function Parser.<lambda>>, 'CONVERT': <function Parser.<lambda>>, 'DECODE': <function Parser.<lambda>>, 'EXTRACT': <function Parser.<lambda>>, 'FLOOR': <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>>, 'NORMALIZE': <function Parser.<lambda>>, 'OPENJSON': <function Parser.<lambda>>, 'OVERLAY': <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>>, 'XMLELEMENT': <function Parser.<lambda>>, 'XMLTABLE': <function Parser.<lambda>>, 'CHAR': <function MySQL.Parser.<lambda>>, 'GROUP_CONCAT': <function MySQL.Parser.<lambda>>, 'VALUES': <function MySQL.Parser.<lambda>>, 'JSON_VALUE': <function MySQL.Parser.<lambda>>}
STATEMENT_PARSERS = {<TokenType.ALTER: 'ALTER'>: <function Parser.<lambda>>, <TokenType.ANALYZE: 'ANALYZE'>: <function Parser.<lambda>>, <TokenType.BEGIN: 'BEGIN'>: <function Parser.<lambda>>, <TokenType.CACHE: 'CACHE'>: <function Parser.<lambda>>, <TokenType.COMMENT: 'COMMENT'>: <function Parser.<lambda>>, <TokenType.COMMIT: 'COMMIT'>: <function Parser.<lambda>>, <TokenType.COPY: 'COPY'>: <function Parser.<lambda>>, <TokenType.CREATE: 'CREATE'>: <function Parser.<lambda>>, <TokenType.DELETE: 'DELETE'>: <function Parser.<lambda>>, <TokenType.DESC: 'DESC'>: <function Parser.<lambda>>, <TokenType.DESCRIBE: 'DESCRIBE'>: <function Parser.<lambda>>, <TokenType.DROP: 'DROP'>: <function Parser.<lambda>>, <TokenType.GRANT: 'GRANT'>: <function Parser.<lambda>>, <TokenType.INSERT: 'INSERT'>: <function Parser.<lambda>>, <TokenType.KILL: 'KILL'>: <function Parser.<lambda>>, <TokenType.LOAD: 'LOAD'>: <function Parser.<lambda>>, <TokenType.MERGE: 'MERGE'>: <function Parser.<lambda>>, <TokenType.PIVOT: 'PIVOT'>: <function Parser.<lambda>>, <TokenType.PRAGMA: 'PRAGMA'>: <function Parser.<lambda>>, <TokenType.REFRESH: 'REFRESH'>: <function Parser.<lambda>>, <TokenType.ROLLBACK: 'ROLLBACK'>: <function Parser.<lambda>>, <TokenType.SET: 'SET'>: <function Parser.<lambda>>, <TokenType.TRUNCATE: 'TRUNCATE'>: <function Parser.<lambda>>, <TokenType.UNCACHE: 'UNCACHE'>: <function Parser.<lambda>>, <TokenType.UNPIVOT: 'UNPIVOT'>: <function Parser.<lambda>>, <TokenType.UPDATE: 'UPDATE'>: <function Parser.<lambda>>, <TokenType.USE: 'USE'>: <function Parser.<lambda>>, <TokenType.SEMICOLON: 'SEMICOLON'>: <function Parser.<lambda>>, <TokenType.SHOW: 'SHOW'>: <function MySQL.Parser.<lambda>>}
SHOW_PARSERS = {'BINARY LOGS': <function _show_parser.<locals>._parse>, 'MASTER LOGS': <function _show_parser.<locals>._parse>, 'BINLOG EVENTS': <function _show_parser.<locals>._parse>, 'CHARACTER SET': <function _show_parser.<locals>._parse>, 'CHARSET': <function _show_parser.<locals>._parse>, 'COLLATION': <function _show_parser.<locals>._parse>, 'FULL COLUMNS': <function _show_parser.<locals>._parse>, 'COLUMNS': <function _show_parser.<locals>._parse>, 'CREATE DATABASE': <function _show_parser.<locals>._parse>, 'CREATE EVENT': <function _show_parser.<locals>._parse>, 'CREATE FUNCTION': <function _show_parser.<locals>._parse>, 'CREATE PROCEDURE': <function _show_parser.<locals>._parse>, 'CREATE TABLE': <function _show_parser.<locals>._parse>, 'CREATE TRIGGER': <function _show_parser.<locals>._parse>, 'CREATE VIEW': <function _show_parser.<locals>._parse>, 'DATABASES': <function _show_parser.<locals>._parse>, 'SCHEMAS': <function _show_parser.<locals>._parse>, 'ENGINE': <function _show_parser.<locals>._parse>, 'STORAGE ENGINES': <function _show_parser.<locals>._parse>, 'ENGINES': <function _show_parser.<locals>._parse>, 'ERRORS': <function _show_parser.<locals>._parse>, 'EVENTS': <function _show_parser.<locals>._parse>, 'FUNCTION CODE': <function _show_parser.<locals>._parse>, 'FUNCTION STATUS': <function _show_parser.<locals>._parse>, 'GRANTS': <function _show_parser.<locals>._parse>, 'INDEX': <function _show_parser.<locals>._parse>, 'MASTER STATUS': <function _show_parser.<locals>._parse>, 'OPEN TABLES': <function _show_parser.<locals>._parse>, 'PLUGINS': <function _show_parser.<locals>._parse>, 'PROCEDURE CODE': <function _show_parser.<locals>._parse>, 'PROCEDURE STATUS': <function _show_parser.<locals>._parse>, 'PRIVILEGES': <function _show_parser.<locals>._parse>, 'FULL PROCESSLIST': <function _show_parser.<locals>._parse>, 'PROCESSLIST': <function _show_parser.<locals>._parse>, 'PROFILE': <function _show_parser.<locals>._parse>, 'PROFILES': <function _show_parser.<locals>._parse>, 'RELAYLOG EVENTS': <function _show_parser.<locals>._parse>, 'REPLICAS': <function _show_parser.<locals>._parse>, 'SLAVE HOSTS': <function _show_parser.<locals>._parse>, 'REPLICA STATUS': <function _show_parser.<locals>._parse>, 'SLAVE STATUS': <function _show_parser.<locals>._parse>, 'GLOBAL STATUS': <function _show_parser.<locals>._parse>, 'SESSION STATUS': <function _show_parser.<locals>._parse>, 'STATUS': <function _show_parser.<locals>._parse>, 'TABLE STATUS': <function _show_parser.<locals>._parse>, 'FULL TABLES': <function _show_parser.<locals>._parse>, 'TABLES': <function _show_parser.<locals>._parse>, 'TRIGGERS': <function _show_parser.<locals>._parse>, 'GLOBAL VARIABLES': <function _show_parser.<locals>._parse>, 'SESSION VARIABLES': <function _show_parser.<locals>._parse>, 'VARIABLES': <function _show_parser.<locals>._parse>, 'WARNINGS': <function _show_parser.<locals>._parse>}
PROPERTY_PARSERS = {'ALLOWED_VALUES': <function Parser.<lambda>>, 'ALGORITHM': <function Parser.<lambda>>, 'AUTO': <function Parser.<lambda>>, 'AUTO_INCREMENT': <function Parser.<lambda>>, 'BACKUP': <function Parser.<lambda>>, 'BLOCKCOMPRESSION': <function Parser.<lambda>>, 'CHARSET': <function Parser.<lambda>>, 'CHARACTER SET': <function Parser.<lambda>>, 'CHECKSUM': <function Parser.<lambda>>, 'CLUSTER BY': <function Parser.<lambda>>, 'CLUSTERED': <function Parser.<lambda>>, 'COLLATE': <function Parser.<lambda>>, 'COMMENT': <function Parser.<lambda>>, 'CONTAINS': <function Parser.<lambda>>, 'COPY': <function Parser.<lambda>>, 'DATABLOCKSIZE': <function Parser.<lambda>>, 'DATA_DELETION': <function Parser.<lambda>>, 'DEFINER': <function Parser.<lambda>>, 'DETERMINISTIC': <function Parser.<lambda>>, 'DISTRIBUTED': <function Parser.<lambda>>, 'DUPLICATE': <function Parser.<lambda>>, 'DYNAMIC': <function Parser.<lambda>>, 'DISTKEY': <function Parser.<lambda>>, 'DISTSTYLE': <function Parser.<lambda>>, 'EMPTY': <function Parser.<lambda>>, 'ENGINE': <function Parser.<lambda>>, 'ENVIRONMENT': <function Parser.<lambda>>, 'EXECUTE': <function Parser.<lambda>>, 'EXTERNAL': <function Parser.<lambda>>, 'FALLBACK': <function Parser.<lambda>>, 'FORMAT': <function Parser.<lambda>>, 'FREESPACE': <function Parser.<lambda>>, 'GLOBAL': <function Parser.<lambda>>, 'HEAP': <function Parser.<lambda>>, 'ICEBERG': <function Parser.<lambda>>, 'IMMUTABLE': <function Parser.<lambda>>, 'INHERITS': <function Parser.<lambda>>, 'INPUT': <function Parser.<lambda>>, 'JOURNAL': <function Parser.<lambda>>, 'LANGUAGE': <function Parser.<lambda>>, 'LAYOUT': <function Parser.<lambda>>, 'LIFETIME': <function Parser.<lambda>>, 'LIKE': <function Parser.<lambda>>, 'LOCATION': <function Parser.<lambda>>, 'LOCK': <function MySQL.Parser.<lambda>>, 'LOCKING': <function Parser.<lambda>>, 'LOG': <function Parser.<lambda>>, 'MATERIALIZED': <function Parser.<lambda>>, 'MERGEBLOCKRATIO': <function Parser.<lambda>>, 'MODIFIES': <function Parser.<lambda>>, 'MULTISET': <function Parser.<lambda>>, 'NO': <function Parser.<lambda>>, 'ON': <function Parser.<lambda>>, 'ORDER BY': <function Parser.<lambda>>, 'OUTPUT': <function Parser.<lambda>>, 'PARTITION': <function Parser.<lambda>>, 'PARTITION BY': <function Parser.<lambda>>, 'PARTITIONED BY': <function Parser.<lambda>>, 'PARTITIONED_BY': <function Parser.<lambda>>, 'PRIMARY KEY': <function Parser.<lambda>>, 'RANGE': <function Parser.<lambda>>, 'READS': <function Parser.<lambda>>, 'REMOTE': <function Parser.<lambda>>, 'RETURNS': <function Parser.<lambda>>, 'STRICT': <function Parser.<lambda>>, 'STREAMING': <function Parser.<lambda>>, 'ROW': <function Parser.<lambda>>, 'ROW_FORMAT': <function Parser.<lambda>>, 'SAMPLE': <function Parser.<lambda>>, 'SECURE': <function Parser.<lambda>>, 'SECURITY': <function Parser.<lambda>>, 'SET': <function Parser.<lambda>>, 'SETTINGS': <function Parser.<lambda>>, 'SHARING': <function Parser.<lambda>>, 'SORTKEY': <function Parser.<lambda>>, 'SOURCE': <function Parser.<lambda>>, 'STABLE': <function Parser.<lambda>>, 'STORED': <function Parser.<lambda>>, 'SYSTEM_VERSIONING': <function Parser.<lambda>>, 'TBLPROPERTIES': <function Parser.<lambda>>, 'TEMP': <function Parser.<lambda>>, 'TEMPORARY': <function Parser.<lambda>>, 'TO': <function Parser.<lambda>>, 'TRANSIENT': <function Parser.<lambda>>, 'TRANSFORM': <function Parser.<lambda>>, 'TTL': <function Parser.<lambda>>, 'USING': <function Parser.<lambda>>, 'UNLOGGED': <function Parser.<lambda>>, 'VOLATILE': <function Parser.<lambda>>, 'WITH': <function Parser.<lambda>>}
SET_PARSERS = {'GLOBAL': <function Parser.<lambda>>, 'LOCAL': <function Parser.<lambda>>, 'SESSION': <function Parser.<lambda>>, 'TRANSACTION': <function Parser.<lambda>>, 'PERSIST': <function MySQL.Parser.<lambda>>, 'PERSIST_ONLY': <function MySQL.Parser.<lambda>>, 'CHARACTER SET': <function MySQL.Parser.<lambda>>, 'CHARSET': <function MySQL.Parser.<lambda>>, 'NAMES': <function MySQL.Parser.<lambda>>}
CONSTRAINT_PARSERS = {'AUTOINCREMENT': <function Parser.<lambda>>, 'AUTO_INCREMENT': <function Parser.<lambda>>, 'CASESPECIFIC': <function Parser.<lambda>>, 'CHARACTER SET': <function Parser.<lambda>>, 'CHECK': <function Parser.<lambda>>, 'COLLATE': <function Parser.<lambda>>, 'COMMENT': <function Parser.<lambda>>, 'COMPRESS': <function Parser.<lambda>>, 'CLUSTERED': <function Parser.<lambda>>, 'NONCLUSTERED': <function Parser.<lambda>>, 'DEFAULT': <function Parser.<lambda>>, 'ENCODE': <function Parser.<lambda>>, 'EPHEMERAL': <function Parser.<lambda>>, 'EXCLUDE': <function Parser.<lambda>>, 'FOREIGN KEY': <function Parser.<lambda>>, 'FORMAT': <function Parser.<lambda>>, 'GENERATED': <function Parser.<lambda>>, 'IDENTITY': <function Parser.<lambda>>, 'INLINE': <function Parser.<lambda>>, 'LIKE': <function Parser.<lambda>>, 'NOT': <function Parser.<lambda>>, 'NULL': <function Parser.<lambda>>, 'ON': <function Parser.<lambda>>, 'PATH': <function Parser.<lambda>>, 'PERIOD': <function Parser.<lambda>>, 'PRIMARY KEY': <function Parser.<lambda>>, 'REFERENCES': <function Parser.<lambda>>, 'TITLE': <function Parser.<lambda>>, 'TTL': <function Parser.<lambda>>, 'UNIQUE': <function Parser.<lambda>>, 'UPPERCASE': <function Parser.<lambda>>, 'WATERMARK': <function Parser.<lambda>>, 'WITH': <function Parser.<lambda>>, 'BUCKET': <function Parser.<lambda>>, 'TRUNCATE': <function Parser.<lambda>>, 'FULLTEXT': <function MySQL.Parser.<lambda>>, 'INDEX': <function MySQL.Parser.<lambda>>, 'KEY': <function MySQL.Parser.<lambda>>, 'SPATIAL': <function MySQL.Parser.<lambda>>}
ALTER_PARSERS = {'ADD': <function Parser.<lambda>>, 'AS': <function Parser.<lambda>>, 'ALTER': <function Parser.<lambda>>, 'CLUSTER BY': <function Parser.<lambda>>, 'DELETE': <function Parser.<lambda>>, 'DROP': <function Parser.<lambda>>, 'RENAME': <function Parser.<lambda>>, 'SET': <function Parser.<lambda>>, 'SWAP': <function Parser.<lambda>>, 'MODIFY': <function MySQL.Parser.<lambda>>}
ALTER_ALTER_PARSERS = {'DISTKEY': <function Parser.<lambda>>, 'DISTSTYLE': <function Parser.<lambda>>, 'SORTKEY': <function Parser.<lambda>>, 'COMPOUND': <function Parser.<lambda>>, 'INDEX': <function MySQL.Parser.<lambda>>}
SCHEMA_UNNAMED_CONSTRAINTS = {'EXCLUDE', 'KEY', 'BUCKET', 'FULLTEXT', 'LIKE', 'PERIOD', 'PRIMARY KEY', 'FOREIGN KEY', 'INDEX', 'TRUNCATE', 'SPATIAL', 'UNIQUE', 'CHECK', 'WATERMARK'}
PROFILE_TYPES: Dict[str, Sequence[Union[Sequence[str], str]]] = {'ALL': (), 'CPU': (), 'IPC': (), 'MEMORY': (), 'SOURCE': (), 'SWAPS': (), 'BLOCK': ('IO',), 'CONTEXT': ('SWITCHES',), 'PAGE': ('FAULTS',)}
TYPE_TOKENS = {<TokenType.VARCHAR: 'VARCHAR'>, <TokenType.OBJECT: 'OBJECT'>, <TokenType.TSRANGE: 'TSRANGE'>, <TokenType.BINARY: 'BINARY'>, <TokenType.RING: 'RING'>, <TokenType.INT4RANGE: 'INT4RANGE'>, <TokenType.RANGE: 'RANGE'>, <TokenType.MEDIUMINT: 'MEDIUMINT'>, <TokenType.TEXT: 'TEXT'>, <TokenType.CHAR: 'CHAR'>, <TokenType.HSTORE: 'HSTORE'>, <TokenType.MAP: 'MAP'>, <TokenType.ENUM16: 'ENUM16'>, <TokenType.SIMPLEAGGREGATEFUNCTION: 'SIMPLEAGGREGATEFUNCTION'>, <TokenType.SMALLDATETIME: 'SMALLDATETIME'>, <TokenType.STRUCT: 'STRUCT'>, <TokenType.INT4MULTIRANGE: 'INT4MULTIRANGE'>, <TokenType.UINT128: 'UINT128'>, <TokenType.POINT: 'POINT'>, <TokenType.DECIMAL128: 'DECIMAL128'>, <TokenType.UDOUBLE: 'UDOUBLE'>, <TokenType.UINT256: 'UINT256'>, <TokenType.POLYGON: 'POLYGON'>, <TokenType.TINYTEXT: 'TINYTEXT'>, <TokenType.LOWCARDINALITY: 'LOWCARDINALITY'>, <TokenType.TIMESTAMP_NS: 'TIMESTAMP_NS'>, <TokenType.ROWVERSION: 'ROWVERSION'>, <TokenType.DECIMAL32: 'DECIMAL32'>, <TokenType.VARIANT: 'VARIANT'>, <TokenType.XML: 'XML'>, <TokenType.BIGINT: 'BIGINT'>, <TokenType.GEOGRAPHY: 'GEOGRAPHY'>, <TokenType.SMALLMONEY: 'SMALLMONEY'>, <TokenType.TIMESTAMP_S: 'TIMESTAMP_S'>, <TokenType.INTERVAL: 'INTERVAL'>, <TokenType.TIME: 'TIME'>, <TokenType.LONGTEXT: 'LONGTEXT'>, <TokenType.TSTZRANGE: 'TSTZRANGE'>, <TokenType.DATERANGE: 'DATERANGE'>, <TokenType.NUMMULTIRANGE: 'NUMMULTIRANGE'>, <TokenType.VECTOR: 'VECTOR'>, <TokenType.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, <TokenType.TIMESTAMPNTZ: 'TIMESTAMPNTZ'>, <TokenType.JSON: 'JSON'>, <TokenType.NULL: 'NULL'>, <TokenType.MULTIPOLYGON: 'MULTIPOLYGON'>, <TokenType.TDIGEST: 'TDIGEST'>, <TokenType.UNKNOWN: 'UNKNOWN'>, <TokenType.UDECIMAL: 'UDECIMAL'>, <TokenType.SET: 'SET'>, <TokenType.INT128: 'INT128'>, <TokenType.NUMRANGE: 'NUMRANGE'>, <TokenType.DATETIME: 'DATETIME'>, <TokenType.LIST: 'LIST'>, <TokenType.UINT: 'UINT'>, <TokenType.DOUBLE: 'DOUBLE'>, <TokenType.SUPER: 'SUPER'>, <TokenType.ARRAY: 'ARRAY'>, <TokenType.DATETIME64: 'DATETIME64'>, <TokenType.BIT: 'BIT'>, <TokenType.TINYBLOB: 'TINYBLOB'>, <TokenType.GEOMETRY: 'GEOMETRY'>, <TokenType.UTINYINT: 'UTINYINT'>, <TokenType.TSTZMULTIRANGE: 'TSTZMULTIRANGE'>, <TokenType.SERIAL: 'SERIAL'>, <TokenType.NCHAR: 'NCHAR'>, <TokenType.UMEDIUMINT: 'UMEDIUMINT'>, <TokenType.MEDIUMTEXT: 'MEDIUMTEXT'>, <TokenType.DECIMAL256: 'DECIMAL256'>, <TokenType.BLOB: 'BLOB'>, <TokenType.MEDIUMBLOB: 'MEDIUMBLOB'>, <TokenType.UUID: 'UUID'>, <TokenType.ENUM8: 'ENUM8'>, <TokenType.INET: 'INET'>, <TokenType.INT8RANGE: 'INT8RANGE'>, <TokenType.VOID: 'VOID'>, <TokenType.LINESTRING: 'LINESTRING'>, <TokenType.NOTHING: 'NOTHING'>, <TokenType.FLOAT: 'FLOAT'>, <TokenType.TIMESTAMP: 'TIMESTAMP'>, <TokenType.SMALLINT: 'SMALLINT'>, <TokenType.NAME: 'NAME'>, <TokenType.MONEY: 'MONEY'>, <TokenType.DECIMAL64: 'DECIMAL64'>, <TokenType.IMAGE: 'IMAGE'>, <TokenType.NESTED: 'NESTED'>, <TokenType.HLLSKETCH: 'HLLSKETCH'>, <TokenType.INT: 'INT'>, <TokenType.BOOLEAN: 'BOOLEAN'>, <TokenType.PSEUDO_TYPE: 'PSEUDO_TYPE'>, <TokenType.TIMESTAMP_MS: 'TIMESTAMP_MS'>, <TokenType.YEAR: 'YEAR'>, <TokenType.INT256: 'INT256'>, <TokenType.USERDEFINED: 'USERDEFINED'>, <TokenType.UBIGINT: 'UBIGINT'>, <TokenType.TIMETZ: 'TIMETZ'>, <TokenType.IPADDRESS: 'IPADDRESS'>, <TokenType.FIXEDSTRING: 'FIXEDSTRING'>, <TokenType.INT8MULTIRANGE: 'INT8MULTIRANGE'>, <TokenType.TSMULTIRANGE: 'TSMULTIRANGE'>, <TokenType.BPCHAR: 'BPCHAR'>, <TokenType.JSONB: 'JSONB'>, <TokenType.DATE: 'DATE'>, <TokenType.IPPREFIX: 'IPPREFIX'>, <TokenType.DATE32: 'DATE32'>, <TokenType.IPV4: 'IPV4'>, <TokenType.NVARCHAR: 'NVARCHAR'>, <TokenType.LONGBLOB: 'LONGBLOB'>, <TokenType.SMALLSERIAL: 'SMALLSERIAL'>, <TokenType.UNION: 'UNION'>, <TokenType.DECIMAL: 'DECIMAL'>, <TokenType.USMALLINT: 'USMALLINT'>, <TokenType.DYNAMIC: 'DYNAMIC'>, <TokenType.DATETIME2: 'DATETIME2'>, <TokenType.BIGDECIMAL: 'BIGDECIMAL'>, <TokenType.AGGREGATEFUNCTION: 'AGGREGATEFUNCTION'>, <TokenType.VARBINARY: 'VARBINARY'>, <TokenType.OBJECT_IDENTIFIER: 'OBJECT_IDENTIFIER'>, <TokenType.TINYINT: 'TINYINT'>, <TokenType.MULTILINESTRING: 'MULTILINESTRING'>, <TokenType.ENUM: 'ENUM'>, <TokenType.IPV6: 'IPV6'>, <TokenType.TIMESTAMPTZ: 'TIMESTAMPTZ'>, <TokenType.DATEMULTIRANGE: 'DATEMULTIRANGE'>, <TokenType.NULLABLE: 'NULLABLE'>, <TokenType.BIGSERIAL: 'BIGSERIAL'>}
ENUM_TYPE_TOKENS = {<TokenType.SET: 'SET'>, <TokenType.ENUM: 'ENUM'>, <TokenType.ENUM8: 'ENUM8'>, <TokenType.ENUM16: 'ENUM16'>, <TokenType.DYNAMIC: 'DYNAMIC'>}
OPERATION_MODIFIERS = {'SQL_NO_CACHE', 'HIGH_PRIORITY', 'SQL_SMALL_RESULT', 'SQL_BIG_RESULT', 'SQL_BUFFER_RESULT', 'SQL_CALC_FOUND_ROWS', 'STRAIGHT_JOIN'}
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
  ALIAS_TOKENS
  COLON_PLACEHOLDER_TOKENS
  ARRAY_CONSTRUCTORS
  COMMENT_TABLE_ALIAS_TOKENS
  UPDATE_ALIAS_TOKENS
  TRIM_TYPES
  ASSIGNMENT
  EQUALITY
  COMPARISON
  BITWISE
  TERM
  FACTOR
  EXPONENT
  TIMES
  TIMESTAMPS
  SET_OPERATIONS
  JOIN_METHODS
  JOIN_SIDES
  JOIN_KINDS
  JOIN_HINTS
  LAMBDAS
  COLUMN_OPERATORS
  EXPRESSION_PARSERS
  UNARY_PARSERS
  STRING_PARSERS
  NUMERIC_PARSERS
  PRIMARY_PARSERS
  PLACEHOLDER_PARSERS
  PIPE_SYNTAX_TRANSFORM_PARSERS
  NO_PAREN_FUNCTION_PARSERS
  INVALID_FUNC_NAME_TOKENS
  FUNCTIONS_WITH_ALIASED_ARGS
  KEY_VALUE_DEFINITIONS
  QUERY_MODIFIER_PARSERS
  TYPE_LITERAL_PARSERS
  TYPE_CONVERTERS
  DDL_SELECT_TOKENS
  PRE_VOLATILE_TOKENS
  TRANSACTION_KIND
  TRANSACTION_CHARACTERISTICS
  CONFLICT_ACTIONS
  CREATE_SEQUENCE
  ISOLATED_LOADING_OPTIONS
  USABLES
  CAST_ACTIONS
  SCHEMA_BINDING_OPTIONS
  PROCEDURE_OPTIONS
  EXECUTE_AS_OPTIONS
  KEY_CONSTRAINT_OPTIONS
  WINDOW_EXCLUDE_OPTIONS
  INSERT_ALTERNATIVES
  CLONE_KEYWORDS
  HISTORICAL_DATA_PREFIX
  HISTORICAL_DATA_KIND
  OPCLASS_FOLLOW_KEYWORDS
  OPTYPE_FOLLOW_TOKENS
  TABLE_INDEX_HINT_TOKENS
  VIEW_ATTRIBUTES
  WINDOW_ALIAS_TOKENS
  WINDOW_BEFORE_PAREN_TOKENS
  WINDOW_SIDES
  JSON_KEY_VALUE_SEPARATOR_TOKENS
  FETCH_TOKENS
  ADD_CONSTRAINT_TOKENS
  DISTINCT_TOKENS
  NULL_TOKENS
  UNNEST_OFFSET_ALIAS_TOKENS
  SELECT_START_TOKENS
  COPY_INTO_VARLEN_OPTIONS
  IS_JSON_PREDICATE_KIND
  ODBC_DATETIME_LITERALS
  ON_CONDITION_TOKENS
  PRIVILEGE_FOLLOW_TOKENS
  DESCRIBE_STYLES
  ANALYZE_STYLES
  ANALYZE_EXPRESSION_PARSERS
  PARTITION_KEYWORDS
  AMBIGUOUS_ALIAS_TOKENS
  RECURSIVE_CTE_SEARCH_KIND
  MODIFIABLES
  STRICT_CAST
  PREFIXED_PIVOT_COLUMNS
  IDENTIFY_PIVOT_STRINGS
  TABLESAMPLE_CSV
  DEFAULT_SAMPLING_METHOD
  SET_REQUIRES_ASSIGNMENT_DELIMITER
  TRIM_PATTERN_FIRST
  MODIFIERS_ATTACHED_TO_SET_OP
  SET_OP_MODIFIERS
  NO_PAREN_IF_COMMANDS
  JSON_ARROWS_REQUIRE_JSON_TYPE
  COLON_IS_VARIANT_EXTRACT
  SUPPORTS_IMPLICIT_UNNEST
  INTERVAL_SPANS
  WRAPPED_TRANSFORM_COLUMN_CONSTRAINT
  OPTIONAL_ALIAS_TOKEN_CTE
  ALTER_RENAME_REQUIRES_COLUMN
  error_level
  error_message_context
  max_errors
  dialect
  reset
  parse
  parse_into
  check_errors
  raise_error
  expression
  validate_expression
  parse_set_operation
  errors
  sql

class MySQL.Generator(sqlglot.generator.Generator): View Source

     739    class Generator(generator.Generator):
     740        INTERVAL_ALLOWS_PLURAL_FORM = False
     741        LOCKING_READS_SUPPORTED = True
     742        NULL_ORDERING_SUPPORTED = None
     743        JOIN_HINTS = False
     744        TABLE_HINTS = True
     745        DUPLICATE_KEY_UPDATE_WITH_SET = False
     746        QUERY_HINT_SEP = " "
     747        VALUES_AS_TABLE = False
     748        NVL2_SUPPORTED = False
     749        LAST_DAY_SUPPORTS_DATE_PART = False
     750        JSON_TYPE_REQUIRED_FOR_EXTRACTION = True
     751        JSON_PATH_BRACKETED_KEY_SUPPORTED = False
     752        JSON_KEY_VALUE_PAIR_SEP = ","
     753        SUPPORTS_TO_NUMBER = False
     754        PARSE_JSON_NAME: t.Optional[str] = None
     755        PAD_FILL_PATTERN_IS_REQUIRED = True
     756        WRAP_DERIVED_VALUES = False
     757        VARCHAR_REQUIRES_SIZE = True
     758        SUPPORTS_MEDIAN = False
     759
     760        TRANSFORMS = {
     761            **generator.Generator.TRANSFORMS,
     762            exp.ArrayAgg: rename_func("GROUP_CONCAT"),
     763            exp.CurrentDate: no_paren_current_date_sql,
     764            exp.DateDiff: _remove_ts_or_ds_to_date(
     765                lambda self, e: self.func("DATEDIFF", e.this, e.expression), ("this", "expression")
     766            ),
     767            exp.DateAdd: _remove_ts_or_ds_to_date(date_add_sql("ADD")),
     768            exp.DateStrToDate: datestrtodate_sql,
     769            exp.DateSub: _remove_ts_or_ds_to_date(date_add_sql("SUB")),
     770            exp.DateTrunc: _date_trunc_sql,
     771            exp.Day: _remove_ts_or_ds_to_date(),
     772            exp.DayOfMonth: _remove_ts_or_ds_to_date(rename_func("DAYOFMONTH")),
     773            exp.DayOfWeek: _remove_ts_or_ds_to_date(rename_func("DAYOFWEEK")),
     774            exp.DayOfYear: _remove_ts_or_ds_to_date(rename_func("DAYOFYEAR")),
     775            exp.GroupConcat: lambda self,
     776            e: f"""GROUP_CONCAT({self.sql(e, "this")} SEPARATOR {self.sql(e, "separator") or "','"})""",
     777            exp.ILike: no_ilike_sql,
     778            exp.JSONExtractScalar: arrow_json_extract_sql,
     779            exp.Length: length_or_char_length_sql,
     780            exp.LogicalOr: rename_func("MAX"),
     781            exp.LogicalAnd: rename_func("MIN"),
     782            exp.Max: max_or_greatest,
     783            exp.Min: min_or_least,
     784            exp.Month: _remove_ts_or_ds_to_date(),
     785            exp.NullSafeEQ: lambda self, e: self.binary(e, "<=>"),
     786            exp.NullSafeNEQ: lambda self, e: f"NOT {self.binary(e, '<=>')}",
     787            exp.NumberToStr: rename_func("FORMAT"),
     788            exp.Pivot: no_pivot_sql,
     789            exp.Select: transforms.preprocess(
     790                [
     791                    transforms.eliminate_distinct_on,
     792                    transforms.eliminate_semi_and_anti_joins,
     793                    transforms.eliminate_qualify,
     794                    transforms.eliminate_full_outer_join,
     795                    transforms.unnest_generate_date_array_using_recursive_cte,
     796                ]
     797            ),
     798            exp.StrPosition: lambda self, e: strposition_sql(
     799                self, e, func_name="LOCATE", supports_position=True
     800            ),
     801            exp.StrToDate: _str_to_date_sql,
     802            exp.StrToTime: _str_to_date_sql,
     803            exp.Stuff: rename_func("INSERT"),
     804            exp.TableSample: no_tablesample_sql,
     805            exp.TimeFromParts: rename_func("MAKETIME"),
     806            exp.TimestampAdd: date_add_interval_sql("DATE", "ADD"),
     807            exp.TimestampDiff: lambda self, e: self.func(
     808                "TIMESTAMPDIFF", unit_to_var(e), e.expression, e.this
     809            ),
     810            exp.TimestampSub: date_add_interval_sql("DATE", "SUB"),
     811            exp.TimeStrToUnix: rename_func("UNIX_TIMESTAMP"),
     812            exp.TimeStrToTime: lambda self, e: timestrtotime_sql(
     813                self,
     814                e,
     815                include_precision=not e.args.get("zone"),
     816            ),
     817            exp.TimeToStr: _remove_ts_or_ds_to_date(
     818                lambda self, e: self.func("DATE_FORMAT", e.this, self.format_time(e))
     819            ),
     820            exp.Trim: trim_sql,
     821            exp.TryCast: no_trycast_sql,
     822            exp.TsOrDsAdd: date_add_sql("ADD"),
     823            exp.TsOrDsDiff: lambda self, e: self.func("DATEDIFF", e.this, e.expression),
     824            exp.TsOrDsToDate: _ts_or_ds_to_date_sql,
     825            exp.Unicode: lambda self, e: f"ORD(CONVERT({self.sql(e.this)} USING utf32))",
     826            exp.UnixToTime: _unix_to_time_sql,
     827            exp.Week: _remove_ts_or_ds_to_date(),
     828            exp.WeekOfYear: _remove_ts_or_ds_to_date(rename_func("WEEKOFYEAR")),
     829            exp.Year: _remove_ts_or_ds_to_date(),
     830        }
     831
     832        UNSIGNED_TYPE_MAPPING = {
     833            exp.DataType.Type.UBIGINT: "BIGINT",
     834            exp.DataType.Type.UINT: "INT",
     835            exp.DataType.Type.UMEDIUMINT: "MEDIUMINT",
     836            exp.DataType.Type.USMALLINT: "SMALLINT",
     837            exp.DataType.Type.UTINYINT: "TINYINT",
     838            exp.DataType.Type.UDECIMAL: "DECIMAL",
     839            exp.DataType.Type.UDOUBLE: "DOUBLE",
     840        }
     841
     842        TIMESTAMP_TYPE_MAPPING = {
     843            exp.DataType.Type.DATETIME2: "DATETIME",
     844            exp.DataType.Type.SMALLDATETIME: "DATETIME",
     845            exp.DataType.Type.TIMESTAMP: "DATETIME",
     846            exp.DataType.Type.TIMESTAMPNTZ: "DATETIME",
     847            exp.DataType.Type.TIMESTAMPTZ: "TIMESTAMP",
     848            exp.DataType.Type.TIMESTAMPLTZ: "TIMESTAMP",
     849        }
     850
     851        TYPE_MAPPING = {
     852            **generator.Generator.TYPE_MAPPING,
     853            **UNSIGNED_TYPE_MAPPING,
     854            **TIMESTAMP_TYPE_MAPPING,
     855        }
     856
     857        TYPE_MAPPING.pop(exp.DataType.Type.MEDIUMTEXT)
     858        TYPE_MAPPING.pop(exp.DataType.Type.LONGTEXT)
     859        TYPE_MAPPING.pop(exp.DataType.Type.TINYTEXT)
     860        TYPE_MAPPING.pop(exp.DataType.Type.BLOB)
     861        TYPE_MAPPING.pop(exp.DataType.Type.MEDIUMBLOB)
     862        TYPE_MAPPING.pop(exp.DataType.Type.LONGBLOB)
     863        TYPE_MAPPING.pop(exp.DataType.Type.TINYBLOB)
     864
     865        PROPERTIES_LOCATION = {
     866            **generator.Generator.PROPERTIES_LOCATION,
     867            exp.TransientProperty: exp.Properties.Location.UNSUPPORTED,
     868            exp.VolatileProperty: exp.Properties.Location.UNSUPPORTED,
     869        }
     870
     871        LIMIT_FETCH = "LIMIT"
     872
     873        LIMIT_ONLY_LITERALS = True
     874
     875        CHAR_CAST_MAPPING = dict.fromkeys(
     876            (
     877                exp.DataType.Type.LONGTEXT,
     878                exp.DataType.Type.LONGBLOB,
     879                exp.DataType.Type.MEDIUMBLOB,
     880                exp.DataType.Type.MEDIUMTEXT,
     881                exp.DataType.Type.TEXT,
     882                exp.DataType.Type.TINYBLOB,
     883                exp.DataType.Type.TINYTEXT,
     884                exp.DataType.Type.VARCHAR,
     885            ),
     886            "CHAR",
     887        )
     888        SIGNED_CAST_MAPPING = dict.fromkeys(
     889            (
     890                exp.DataType.Type.BIGINT,
     891                exp.DataType.Type.BOOLEAN,
     892                exp.DataType.Type.INT,
     893                exp.DataType.Type.SMALLINT,
     894                exp.DataType.Type.TINYINT,
     895                exp.DataType.Type.MEDIUMINT,
     896            ),
     897            "SIGNED",
     898        )
     899
     900        # MySQL doesn't support many datatypes in cast.
     901        # https://dev.mysql.com/doc/refman/8.0/en/cast-functions.html#function_cast
     902        CAST_MAPPING = {
     903            **CHAR_CAST_MAPPING,
     904            **SIGNED_CAST_MAPPING,
     905            exp.DataType.Type.UBIGINT: "UNSIGNED",
     906        }
     907
     908        TIMESTAMP_FUNC_TYPES = {
     909            exp.DataType.Type.TIMESTAMPTZ,
     910            exp.DataType.Type.TIMESTAMPLTZ,
     911        }
     912
     913        # https://dev.mysql.com/doc/refman/8.0/en/keywords.html
     914        RESERVED_KEYWORDS = {
     915            "accessible",
     916            "add",
     917            "all",
     918            "alter",
     919            "analyze",
     920            "and",
     921            "as",
     922            "asc",
     923            "asensitive",
     924            "before",
     925            "between",
     926            "bigint",
     927            "binary",
     928            "blob",
     929            "both",
     930            "by",
     931            "call",
     932            "cascade",
     933            "case",
     934            "change",
     935            "char",
     936            "character",
     937            "check",
     938            "collate",
     939            "column",
     940            "condition",
     941            "constraint",
     942            "continue",
     943            "convert",
     944            "create",
     945            "cross",
     946            "cube",
     947            "cume_dist",
     948            "current_date",
     949            "current_time",
     950            "current_timestamp",
     951            "current_user",
     952            "cursor",
     953            "database",
     954            "databases",
     955            "day_hour",
     956            "day_microsecond",
     957            "day_minute",
     958            "day_second",
     959            "dec",
     960            "decimal",
     961            "declare",
     962            "default",
     963            "delayed",
     964            "delete",
     965            "dense_rank",
     966            "desc",
     967            "describe",
     968            "deterministic",
     969            "distinct",
     970            "distinctrow",
     971            "div",
     972            "double",
     973            "drop",
     974            "dual",
     975            "each",
     976            "else",
     977            "elseif",
     978            "empty",
     979            "enclosed",
     980            "escaped",
     981            "except",
     982            "exists",
     983            "exit",
     984            "explain",
     985            "false",
     986            "fetch",
     987            "first_value",
     988            "float",
     989            "float4",
     990            "float8",
     991            "for",
     992            "force",
     993            "foreign",
     994            "from",
     995            "fulltext",
     996            "function",
     997            "generated",
     998            "get",
     999            "grant",
    1000            "group",
    1001            "grouping",
    1002            "groups",
    1003            "having",
    1004            "high_priority",
    1005            "hour_microsecond",
    1006            "hour_minute",
    1007            "hour_second",
    1008            "if",
    1009            "ignore",
    1010            "in",
    1011            "index",
    1012            "infile",
    1013            "inner",
    1014            "inout",
    1015            "insensitive",
    1016            "insert",
    1017            "int",
    1018            "int1",
    1019            "int2",
    1020            "int3",
    1021            "int4",
    1022            "int8",
    1023            "integer",
    1024            "intersect",
    1025            "interval",
    1026            "into",
    1027            "io_after_gtids",
    1028            "io_before_gtids",
    1029            "is",
    1030            "iterate",
    1031            "join",
    1032            "json_table",
    1033            "key",
    1034            "keys",
    1035            "kill",
    1036            "lag",
    1037            "last_value",
    1038            "lateral",
    1039            "lead",
    1040            "leading",
    1041            "leave",
    1042            "left",
    1043            "like",
    1044            "limit",
    1045            "linear",
    1046            "lines",
    1047            "load",
    1048            "localtime",
    1049            "localtimestamp",
    1050            "lock",
    1051            "long",
    1052            "longblob",
    1053            "longtext",
    1054            "loop",
    1055            "low_priority",
    1056            "master_bind",
    1057            "master_ssl_verify_server_cert",
    1058            "match",
    1059            "maxvalue",
    1060            "mediumblob",
    1061            "mediumint",
    1062            "mediumtext",
    1063            "middleint",
    1064            "minute_microsecond",
    1065            "minute_second",
    1066            "mod",
    1067            "modifies",
    1068            "natural",
    1069            "not",
    1070            "no_write_to_binlog",
    1071            "nth_value",
    1072            "ntile",
    1073            "null",
    1074            "numeric",
    1075            "of",
    1076            "on",
    1077            "optimize",
    1078            "optimizer_costs",
    1079            "option",
    1080            "optionally",
    1081            "or",
    1082            "order",
    1083            "out",
    1084            "outer",
    1085            "outfile",
    1086            "over",
    1087            "partition",
    1088            "percent_rank",
    1089            "precision",
    1090            "primary",
    1091            "procedure",
    1092            "purge",
    1093            "range",
    1094            "rank",
    1095            "read",
    1096            "reads",
    1097            "read_write",
    1098            "real",
    1099            "recursive",
    1100            "references",
    1101            "regexp",
    1102            "release",
    1103            "rename",
    1104            "repeat",
    1105            "replace",
    1106            "require",
    1107            "resignal",
    1108            "restrict",
    1109            "return",
    1110            "revoke",
    1111            "right",
    1112            "rlike",
    1113            "row",
    1114            "rows",
    1115            "row_number",
    1116            "schema",
    1117            "schemas",
    1118            "second_microsecond",
    1119            "select",
    1120            "sensitive",
    1121            "separator",
    1122            "set",
    1123            "show",
    1124            "signal",
    1125            "smallint",
    1126            "spatial",
    1127            "specific",
    1128            "sql",
    1129            "sqlexception",
    1130            "sqlstate",
    1131            "sqlwarning",
    1132            "sql_big_result",
    1133            "sql_calc_found_rows",
    1134            "sql_small_result",
    1135            "ssl",
    1136            "starting",
    1137            "stored",
    1138            "straight_join",
    1139            "system",
    1140            "table",
    1141            "terminated",
    1142            "then",
    1143            "tinyblob",
    1144            "tinyint",
    1145            "tinytext",
    1146            "to",
    1147            "trailing",
    1148            "trigger",
    1149            "true",
    1150            "undo",
    1151            "union",
    1152            "unique",
    1153            "unlock",
    1154            "unsigned",
    1155            "update",
    1156            "usage",
    1157            "use",
    1158            "using",
    1159            "utc_date",
    1160            "utc_time",
    1161            "utc_timestamp",
    1162            "values",
    1163            "varbinary",
    1164            "varchar",
    1165            "varcharacter",
    1166            "varying",
    1167            "virtual",
    1168            "when",
    1169            "where",
    1170            "while",
    1171            "window",
    1172            "with",
    1173            "write",
    1174            "xor",
    1175            "year_month",
    1176            "zerofill",
    1177        }
    1178
    1179        def computedcolumnconstraint_sql(self, expression: exp.ComputedColumnConstraint) -> str:
    1180            persisted = "STORED" if expression.args.get("persisted") else "VIRTUAL"
    1181            return f"GENERATED ALWAYS AS ({self.sql(expression.this.unnest())}) {persisted}"
    1182
    1183        def array_sql(self, expression: exp.Array) -> str:
    1184            self.unsupported("Arrays are not supported by MySQL")
    1185            return self.function_fallback_sql(expression)
    1186
    1187        def arraycontainsall_sql(self, expression: exp.ArrayContainsAll) -> str:
    1188            self.unsupported("Array operations are not supported by MySQL")
    1189            return self.function_fallback_sql(expression)
    1190
    1191        def dpipe_sql(self, expression: exp.DPipe) -> str:
    1192            return self.func("CONCAT", *expression.flatten())
    1193
    1194        def extract_sql(self, expression: exp.Extract) -> str:
    1195            unit = expression.name
    1196            if unit and unit.lower() == "epoch":
    1197                return self.func("UNIX_TIMESTAMP", expression.expression)
    1198
    1199            return super().extract_sql(expression)
    1200
    1201        def datatype_sql(self, expression: exp.DataType) -> str:
    1202            if (
    1203                self.VARCHAR_REQUIRES_SIZE
    1204                and expression.is_type(exp.DataType.Type.VARCHAR)
    1205                and not expression.expressions
    1206            ):
    1207                # `VARCHAR` must always have a size - if it doesn't, we always generate `TEXT`
    1208                return "TEXT"
    1209
    1210            # https://dev.mysql.com/doc/refman/8.0/en/numeric-type-syntax.html
    1211            result = super().datatype_sql(expression)
    1212            if expression.this in self.UNSIGNED_TYPE_MAPPING:
    1213                result = f"{result} UNSIGNED"
    1214
    1215            return result
    1216
    1217        def jsonarraycontains_sql(self, expression: exp.JSONArrayContains) -> str:
    1218            return f"{self.sql(expression, 'this')} MEMBER OF({self.sql(expression, 'expression')})"
    1219
    1220        def cast_sql(self, expression: exp.Cast, safe_prefix: t.Optional[str] = None) -> str:
    1221            if expression.to.this in self.TIMESTAMP_FUNC_TYPES:
    1222                return self.func("TIMESTAMP", expression.this)
    1223
    1224            to = self.CAST_MAPPING.get(expression.to.this)
    1225
    1226            if to:
    1227                expression.to.set("this", to)
    1228            return super().cast_sql(expression)
    1229
    1230        def show_sql(self, expression: exp.Show) -> str:
    1231            this = f" {expression.name}"
    1232            full = " FULL" if expression.args.get("full") else ""
    1233            global_ = " GLOBAL" if expression.args.get("global") else ""
    1234
    1235            target = self.sql(expression, "target")
    1236            target = f" {target}" if target else ""
    1237            if expression.name in ("COLUMNS", "INDEX"):
    1238                target = f" FROM{target}"
    1239            elif expression.name == "GRANTS":
    1240                target = f" FOR{target}"
    1241
    1242            db = self._prefixed_sql("FROM", expression, "db")
    1243
    1244            like = self._prefixed_sql("LIKE", expression, "like")
    1245            where = self.sql(expression, "where")
    1246
    1247            types = self.expressions(expression, key="types")
    1248            types = f" {types}" if types else types
    1249            query = self._prefixed_sql("FOR QUERY", expression, "query")
    1250
    1251            if expression.name == "PROFILE":
    1252                offset = self._prefixed_sql("OFFSET", expression, "offset")
    1253                limit = self._prefixed_sql("LIMIT", expression, "limit")
    1254            else:
    1255                offset = ""
    1256                limit = self._oldstyle_limit_sql(expression)
    1257
    1258            log = self._prefixed_sql("IN", expression, "log")
    1259            position = self._prefixed_sql("FROM", expression, "position")
    1260
    1261            channel = self._prefixed_sql("FOR CHANNEL", expression, "channel")
    1262
    1263            if expression.name == "ENGINE":
    1264                mutex_or_status = " MUTEX" if expression.args.get("mutex") else " STATUS"
    1265            else:
    1266                mutex_or_status = ""
    1267
    1268            return f"SHOW{full}{global_}{this}{target}{types}{db}{query}{log}{position}{channel}{mutex_or_status}{like}{where}{offset}{limit}"
    1269
    1270        def altercolumn_sql(self, expression: exp.AlterColumn) -> str:
    1271            dtype = self.sql(expression, "dtype")
    1272            if not dtype:
    1273                return super().altercolumn_sql(expression)
    1274
    1275            this = self.sql(expression, "this")
    1276            return f"MODIFY COLUMN {this} {dtype}"
    1277
    1278        def _prefixed_sql(self, prefix: str, expression: exp.Expression, arg: str) -> str:
    1279            sql = self.sql(expression, arg)
    1280            return f" {prefix} {sql}" if sql else ""
    1281
    1282        def _oldstyle_limit_sql(self, expression: exp.Show) -> str:
    1283            limit = self.sql(expression, "limit")
    1284            offset = self.sql(expression, "offset")
    1285            if limit:
    1286                limit_offset = f"{offset}, {limit}" if offset else limit
    1287                return f" LIMIT {limit_offset}"
    1288            return ""
    1289
    1290        def chr_sql(self, expression: exp.Chr) -> str:
    1291            this = self.expressions(sqls=[expression.this] + expression.expressions)
    1292            charset = expression.args.get("charset")
    1293            using = f" USING {self.sql(charset)}" if charset else ""
    1294            return f"CHAR({this}{using})"
    1295
    1296        def timestamptrunc_sql(self, expression: exp.TimestampTrunc) -> str:
    1297            unit = expression.args.get("unit")
    1298
    1299            # Pick an old-enough date to avoid negative timestamp diffs
    1300            start_ts = "'0000-01-01 00:00:00'"
    1301
    1302            # Source: https://stackoverflow.com/a/32955740
    1303            timestamp_diff = build_date_delta(exp.TimestampDiff)([unit, start_ts, expression.this])
    1304            interval = exp.Interval(this=timestamp_diff, unit=unit)
    1305            dateadd = build_date_delta_with_interval(exp.DateAdd)([start_ts, interval])
    1306
    1307            return self.sql(dateadd)
    1308
    1309        def converttimezone_sql(self, expression: exp.ConvertTimezone) -> str:
    1310            from_tz = expression.args.get("source_tz")
    1311            to_tz = expression.args.get("target_tz")
    1312            dt = expression.args.get("timestamp")
    1313
    1314            return self.func("CONVERT_TZ", dt, from_tz, to_tz)
    1315
    1316        def attimezone_sql(self, expression: exp.AtTimeZone) -> str:
    1317            self.unsupported("AT TIME ZONE is not supported by MySQL")
    1318            return self.sql(expression.this)
    1319
    1320        def isascii_sql(self, expression: exp.IsAscii) -> str:
    1321            return f"REGEXP_LIKE({self.sql(expression.this)}, '^[[:ascii:]]*$')"
    1322
    1323        @unsupported_args("this")
    1324        def currentschema_sql(self, expression: exp.CurrentSchema) -> str:
    1325            return self.func("SCHEMA")

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: Optional[str] = None
PAD_FILL_PATTERN_IS_REQUIRED = True
WRAP_DERIVED_VALUES = False
VARCHAR_REQUIRES_SIZE = True
SUPPORTS_MEDIAN = 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.AnalyzeColumns'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.AnalyzeWith'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.ArrayContainsAll'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.ArrayOverlaps'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.AutoRefreshProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.BackupProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.CaseSpecificColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.Ceil'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.CharacterSetColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.CharacterSetProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.ClusteredColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.CollateColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.CommentColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.ConnectByRoot'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.ConvertToCharset'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.CopyGrantsProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.CredentialsProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.DateFormatColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.DefaultColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.DynamicProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.EmptyProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.EncodeColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.EnviromentProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.EphemeralColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.ExcludeColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.ExecuteAsProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.Except'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.ExternalProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.Floor'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.Get'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.GlobalProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.HeapProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.IcebergProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.InheritsProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.InlineLengthColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.InputModelProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.Intersect'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.IntervalSpan'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.Int64'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.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.PartitionedByBucket'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.PartitionByTruncate'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.PivotAny'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.ProjectionPolicyColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.Put'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.RemoteWithConnectionModelProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.ReturnsProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.SampleProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.SecureProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.SecurityProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.SetConfigProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.SetProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.SettingsProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.SharingProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.SqlReadWriteProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.SqlSecurityProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.StabilityProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.Stream'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.StreamingTableProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.StrictProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.SwapTable'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.Tags'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.TemporaryProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.TitleColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.ToMap'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.ToTableProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.TransformModelProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.TransientProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.Union'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.UnloggedProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.UsingTemplateProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.UsingData'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.Uuid'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.UppercaseColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.VarMap'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.ViewAttributeProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.VolatileProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.WithJournalTableProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.WithProcedureOptions'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.WithSchemaBindingProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.WithOperator'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.ForceProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.ArrayAgg'>: <function rename_func.<locals>.<lambda>>, <class 'sqlglot.expressions.CurrentDate'>: <function no_paren_current_date_sql>, <class 'sqlglot.expressions.DateDiff'>: <function _remove_ts_or_ds_to_date.<locals>.func>, <class 'sqlglot.expressions.DateAdd'>: <function _remove_ts_or_ds_to_date.<locals>.func>, <class 'sqlglot.expressions.DateStrToDate'>: <function datestrtodate_sql>, <class 'sqlglot.expressions.DateSub'>: <function _remove_ts_or_ds_to_date.<locals>.func>, <class 'sqlglot.expressions.DateTrunc'>: <function _date_trunc_sql>, <class 'sqlglot.expressions.Day'>: <function _remove_ts_or_ds_to_date.<locals>.func>, <class 'sqlglot.expressions.DayOfMonth'>: <function _remove_ts_or_ds_to_date.<locals>.func>, <class 'sqlglot.expressions.DayOfWeek'>: <function _remove_ts_or_ds_to_date.<locals>.func>, <class 'sqlglot.expressions.DayOfYear'>: <function _remove_ts_or_ds_to_date.<locals>.func>, <class 'sqlglot.expressions.GroupConcat'>: <function MySQL.Generator.<lambda>>, <class 'sqlglot.expressions.ILike'>: <function no_ilike_sql>, <class 'sqlglot.expressions.JSONExtractScalar'>: <function arrow_json_extract_sql>, <class 'sqlglot.expressions.Length'>: <function length_or_char_length_sql>, <class 'sqlglot.expressions.LogicalOr'>: <function rename_func.<locals>.<lambda>>, <class 'sqlglot.expressions.LogicalAnd'>: <function rename_func.<locals>.<lambda>>, <class 'sqlglot.expressions.Max'>: <function max_or_greatest>, <class 'sqlglot.expressions.Min'>: <function min_or_least>, <class 'sqlglot.expressions.Month'>: <function _remove_ts_or_ds_to_date.<locals>.func>, <class 'sqlglot.expressions.NullSafeEQ'>: <function MySQL.Generator.<lambda>>, <class 'sqlglot.expressions.NullSafeNEQ'>: <function MySQL.Generator.<lambda>>, <class 'sqlglot.expressions.NumberToStr'>: <function rename_func.<locals>.<lambda>>, <class 'sqlglot.expressions.Pivot'>: <function no_pivot_sql>, <class 'sqlglot.expressions.Select'>: <function preprocess.<locals>._to_sql>, <class 'sqlglot.expressions.StrPosition'>: <function MySQL.Generator.<lambda>>, <class 'sqlglot.expressions.StrToDate'>: <function _str_to_date_sql>, <class 'sqlglot.expressions.StrToTime'>: <function _str_to_date_sql>, <class 'sqlglot.expressions.Stuff'>: <function rename_func.<locals>.<lambda>>, <class 'sqlglot.expressions.TableSample'>: <function no_tablesample_sql>, <class 'sqlglot.expressions.TimeFromParts'>: <function rename_func.<locals>.<lambda>>, <class 'sqlglot.expressions.TimestampAdd'>: <function date_add_interval_sql.<locals>.func>, <class 'sqlglot.expressions.TimestampDiff'>: <function MySQL.Generator.<lambda>>, <class 'sqlglot.expressions.TimestampSub'>: <function date_add_interval_sql.<locals>.func>, <class 'sqlglot.expressions.TimeStrToUnix'>: <function rename_func.<locals>.<lambda>>, <class 'sqlglot.expressions.TimeStrToTime'>: <function MySQL.Generator.<lambda>>, <class 'sqlglot.expressions.TimeToStr'>: <function _remove_ts_or_ds_to_date.<locals>.func>, <class 'sqlglot.expressions.Trim'>: <function trim_sql>, <class 'sqlglot.expressions.TryCast'>: <function no_trycast_sql>, <class 'sqlglot.expressions.TsOrDsAdd'>: <function date_add_sql.<locals>.func>, <class 'sqlglot.expressions.TsOrDsDiff'>: <function MySQL.Generator.<lambda>>, <class 'sqlglot.expressions.TsOrDsToDate'>: <function _ts_or_ds_to_date_sql>, <class 'sqlglot.expressions.Unicode'>: <function MySQL.Generator.<lambda>>, <class 'sqlglot.expressions.UnixToTime'>: <function _unix_to_time_sql>, <class 'sqlglot.expressions.Week'>: <function _remove_ts_or_ds_to_date.<locals>.func>, <class 'sqlglot.expressions.WeekOfYear'>: <function _remove_ts_or_ds_to_date.<locals>.func>, <class 'sqlglot.expressions.Year'>: <function _remove_ts_or_ds_to_date.<locals>.func>}
UNSIGNED_TYPE_MAPPING = {<Type.UBIGINT: 'UBIGINT'>: 'BIGINT', <Type.UINT: 'UINT'>: 'INT', <Type.UMEDIUMINT: 'UMEDIUMINT'>: 'MEDIUMINT', <Type.USMALLINT: 'USMALLINT'>: 'SMALLINT', <Type.UTINYINT: 'UTINYINT'>: 'TINYINT', <Type.UDECIMAL: 'UDECIMAL'>: 'DECIMAL', <Type.UDOUBLE: 'UDOUBLE'>: 'DOUBLE'}
TIMESTAMP_TYPE_MAPPING = {<Type.DATETIME2: 'DATETIME2'>: 'DATETIME', <Type.SMALLDATETIME: 'SMALLDATETIME'>: 'DATETIME', <Type.TIMESTAMP: 'TIMESTAMP'>: 'DATETIME', <Type.TIMESTAMPNTZ: 'TIMESTAMPNTZ'>: 'DATETIME', <Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>: 'TIMESTAMP', <Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>: 'TIMESTAMP'}
TYPE_MAPPING = {<Type.DATETIME2: 'DATETIME2'>: 'DATETIME', <Type.NCHAR: 'NCHAR'>: 'CHAR', <Type.NVARCHAR: 'NVARCHAR'>: 'VARCHAR', <Type.INET: 'INET'>: 'INET', <Type.ROWVERSION: 'ROWVERSION'>: 'VARBINARY', <Type.SMALLDATETIME: 'SMALLDATETIME'>: 'DATETIME', <Type.UBIGINT: 'UBIGINT'>: 'BIGINT', <Type.UINT: 'UINT'>: 'INT', <Type.UMEDIUMINT: 'UMEDIUMINT'>: 'MEDIUMINT', <Type.USMALLINT: 'USMALLINT'>: 'SMALLINT', <Type.UTINYINT: 'UTINYINT'>: 'TINYINT', <Type.UDECIMAL: 'UDECIMAL'>: 'DECIMAL', <Type.UDOUBLE: 'UDOUBLE'>: 'DOUBLE', <Type.TIMESTAMP: 'TIMESTAMP'>: 'DATETIME', <Type.TIMESTAMPNTZ: 'TIMESTAMPNTZ'>: 'DATETIME', <Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>: 'TIMESTAMP', <Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>: 'TIMESTAMP'}
PROPERTIES_LOCATION = {<class 'sqlglot.expressions.AllowedValuesProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.AlgorithmProperty'>: <Location.POST_CREATE: 'POST_CREATE'>, <class 'sqlglot.expressions.AutoIncrementProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.AutoRefreshProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.BackupProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.BlockCompressionProperty'>: <Location.POST_NAME: 'POST_NAME'>, <class 'sqlglot.expressions.CharacterSetProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.ChecksumProperty'>: <Location.POST_NAME: 'POST_NAME'>, <class 'sqlglot.expressions.CollateProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.CopyGrantsProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.Cluster'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.ClusteredByProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.DistributedByProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.DuplicateKeyProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.DataBlocksizeProperty'>: <Location.POST_NAME: 'POST_NAME'>, <class 'sqlglot.expressions.DataDeletionProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.DefinerProperty'>: <Location.POST_CREATE: 'POST_CREATE'>, <class 'sqlglot.expressions.DictRange'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.DictProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.DynamicProperty'>: <Location.POST_CREATE: 'POST_CREATE'>, <class 'sqlglot.expressions.DistKeyProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.DistStyleProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.EmptyProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.EncodeProperty'>: <Location.POST_EXPRESSION: 'POST_EXPRESSION'>, <class 'sqlglot.expressions.EngineProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.EnviromentProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.ExecuteAsProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.ExternalProperty'>: <Location.POST_CREATE: 'POST_CREATE'>, <class 'sqlglot.expressions.FallbackProperty'>: <Location.POST_NAME: 'POST_NAME'>, <class 'sqlglot.expressions.FileFormatProperty'>: <Location.POST_WITH: 'POST_WITH'>, <class 'sqlglot.expressions.FreespaceProperty'>: <Location.POST_NAME: 'POST_NAME'>, <class 'sqlglot.expressions.GlobalProperty'>: <Location.POST_CREATE: 'POST_CREATE'>, <class 'sqlglot.expressions.HeapProperty'>: <Location.POST_WITH: 'POST_WITH'>, <class 'sqlglot.expressions.InheritsProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.IcebergProperty'>: <Location.POST_CREATE: 'POST_CREATE'>, <class 'sqlglot.expressions.IncludeProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.InputModelProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.IsolatedLoadingProperty'>: <Location.POST_NAME: 'POST_NAME'>, <class 'sqlglot.expressions.JournalProperty'>: <Location.POST_NAME: 'POST_NAME'>, <class 'sqlglot.expressions.LanguageProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.LikeProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.LocationProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.LockProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.LockingProperty'>: <Location.POST_ALIAS: 'POST_ALIAS'>, <class 'sqlglot.expressions.LogProperty'>: <Location.POST_NAME: 'POST_NAME'>, <class 'sqlglot.expressions.MaterializedProperty'>: <Location.POST_CREATE: 'POST_CREATE'>, <class 'sqlglot.expressions.MergeBlockRatioProperty'>: <Location.POST_NAME: 'POST_NAME'>, <class 'sqlglot.expressions.NoPrimaryIndexProperty'>: <Location.POST_EXPRESSION: 'POST_EXPRESSION'>, <class 'sqlglot.expressions.OnProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.OnCommitProperty'>: <Location.POST_EXPRESSION: 'POST_EXPRESSION'>, <class 'sqlglot.expressions.Order'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.OutputModelProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.PartitionedByProperty'>: <Location.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.SecurityProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.SerdeProperties'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.Set'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.SettingsProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.SetProperty'>: <Location.POST_CREATE: 'POST_CREATE'>, <class 'sqlglot.expressions.SetConfigProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.SharingProperty'>: <Location.POST_EXPRESSION: 'POST_EXPRESSION'>, <class 'sqlglot.expressions.SequenceProperties'>: <Location.POST_EXPRESSION: 'POST_EXPRESSION'>, <class 'sqlglot.expressions.SortKeyProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.SqlReadWriteProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.SqlSecurityProperty'>: <Location.POST_CREATE: 'POST_CREATE'>, <class 'sqlglot.expressions.StabilityProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.StorageHandlerProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.StreamingTableProperty'>: <Location.POST_CREATE: 'POST_CREATE'>, <class 'sqlglot.expressions.StrictProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.Tags'>: <Location.POST_WITH: 'POST_WITH'>, <class 'sqlglot.expressions.TemporaryProperty'>: <Location.POST_CREATE: 'POST_CREATE'>, <class 'sqlglot.expressions.ToTableProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.TransientProperty'>: <Location.UNSUPPORTED: 'UNSUPPORTED'>, <class 'sqlglot.expressions.TransformModelProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.MergeTreeTTL'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.UnloggedProperty'>: <Location.POST_CREATE: 'POST_CREATE'>, <class 'sqlglot.expressions.UsingTemplateProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.ViewAttributeProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.VolatileProperty'>: <Location.UNSUPPORTED: 'UNSUPPORTED'>, <class 'sqlglot.expressions.WithDataProperty'>: <Location.POST_EXPRESSION: 'POST_EXPRESSION'>, <class 'sqlglot.expressions.WithJournalTableProperty'>: <Location.POST_NAME: 'POST_NAME'>, <class 'sqlglot.expressions.WithProcedureOptions'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.WithSchemaBindingProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.WithSystemVersioningProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.ForceProperty'>: <Location.POST_CREATE: 'POST_CREATE'>}
LIMIT_FETCH = 'LIMIT'
LIMIT_ONLY_LITERALS = True
CHAR_CAST_MAPPING = {<Type.LONGTEXT: 'LONGTEXT'>: 'CHAR', <Type.LONGBLOB: 'LONGBLOB'>: 'CHAR', <Type.MEDIUMBLOB: 'MEDIUMBLOB'>: 'CHAR', <Type.MEDIUMTEXT: 'MEDIUMTEXT'>: 'CHAR', <Type.TEXT: 'TEXT'>: 'CHAR', <Type.TINYBLOB: 'TINYBLOB'>: 'CHAR', <Type.TINYTEXT: 'TINYTEXT'>: 'CHAR', <Type.VARCHAR: 'VARCHAR'>: 'CHAR'}
SIGNED_CAST_MAPPING = {<Type.BIGINT: 'BIGINT'>: 'SIGNED', <Type.BOOLEAN: 'BOOLEAN'>: 'SIGNED', <Type.INT: 'INT'>: 'SIGNED', <Type.SMALLINT: 'SMALLINT'>: 'SIGNED', <Type.TINYINT: 'TINYINT'>: 'SIGNED', <Type.MEDIUMINT: 'MEDIUMINT'>: 'SIGNED'}
CAST_MAPPING = {<Type.LONGTEXT: 'LONGTEXT'>: 'CHAR', <Type.LONGBLOB: 'LONGBLOB'>: 'CHAR', <Type.MEDIUMBLOB: 'MEDIUMBLOB'>: 'CHAR', <Type.MEDIUMTEXT: 'MEDIUMTEXT'>: 'CHAR', <Type.TEXT: 'TEXT'>: 'CHAR', <Type.TINYBLOB: 'TINYBLOB'>: 'CHAR', <Type.TINYTEXT: 'TINYTEXT'>: 'CHAR', <Type.VARCHAR: 'VARCHAR'>: 'CHAR', <Type.BIGINT: 'BIGINT'>: 'SIGNED', <Type.BOOLEAN: 'BOOLEAN'>: 'SIGNED', <Type.INT: 'INT'>: 'SIGNED', <Type.SMALLINT: 'SMALLINT'>: 'SIGNED', <Type.TINYINT: 'TINYINT'>: 'SIGNED', <Type.MEDIUMINT: 'MEDIUMINT'>: 'SIGNED', <Type.UBIGINT: 'UBIGINT'>: 'UNSIGNED'}
TIMESTAMP_FUNC_TYPES = {<Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, <Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>}
RESERVED_KEYWORDS = {'day_second', 'write', 'kill', 'day_hour', 'day_minute', 'all', 'lag', 'else', 'outer', 'schemas', 'first_value', 'interval', 'virtual', 'use', 'insert', 'current_timestamp', 'mediumblob', 'enclosed', 'procedure', 'current_date', 'if', 'tinyblob', 'exit', 'order', 'show', 'load', 'zerofill', 'as', 'ntile', 'varying', 'index', 'trailing', 'sqlexception', 'double', 'group', 'databases', 'leading', 'partition', 'varcharacter', 'false', 'function', 'sql_small_result', 'xor', 'usage', 'condition', 'mod', 'exists', 'update', 'using', 'cursor', 'smallint', 'int8', 'mediumint', 'groups', 'explain', 'unlock', 'system', 'in', 'year_month', 'resignal', 'cube', 'int4', 'master_bind', 'true', 'deterministic', 'restrict', 'before', 'char', 'lines', 'second_microsecond', 'localtime', 'purge', 'modifies', 'window', 'int2', 'constraint', 'convert', 'having', 'is', 'sqlwarning', 'inner', 'tinyint', 'spatial', 'desc', 'recursive', 'insensitive', 'iterate', 'rank', 'where', 'for', 'regexp', 'outfile', 'range', 'by', 'or', 'read', 'sqlstate', 'div', 'into', 'precision', 'alter', 'trigger', 'key', 'collate', 'declare', 'null', 'starting', 'infile', 'delayed', 'return', 'to', 'loop', 'optionally', 'int1', 'replace', 'cume_dist', 'row_number', 'database', 'set', 'rename', 'dense_rank', 'current_user', 'middleint', 'delete', 'row', 'while', 'table', 'bigint', 'require', 'utc_timestamp', 'low_priority', 'out', 'rlike', 'json_table', 'unique', 'varchar', 'day_microsecond', 'on', 'release', 'grouping', 'cascade', 'elseif', 'straight_join', 'drop', 'master_ssl_verify_server_cert', 'optimizer_costs', 'last_value', 'add', 'get', 'minute_second', 'except', 'reads', 'lock', 'both', 'left', 'repeat', 'each', 'values', 'force', 'lateral', 'longtext', 'revoke', 'signal', 'change', 'optimize', 'empty', 'unsigned', 'option', 'no_write_to_binlog', 'float8', 'over', 'references', 'limit', 'mediumtext', 'distinct', 'float4', 'from', 'sql_big_result', 'int3', 'stored', 'current_time', 'intersect', 'hour_microsecond', 'int', 'rows', 'asensitive', 'terminated', 'create', 'accessible', 'read_write', 'right', 'undo', 'long', 'localtimestamp', 'grant', 'describe', 'leave', 'case', 'with', 'blob', 'lead', 'character', 'column', 'numeric', 'separator', 'io_after_gtids', 'minute_microsecond', 'percent_rank', 'dual', 'fulltext', 'of', 'analyze', 'float', 'sql', 'cross', 'hour_second', 'dec', 'default', 'decimal', 'like', 'specific', 'utc_date', 'fetch', 'nth_value', 'tinytext', 'ssl', 'between', 'join', 'keys', 'primary', 'when', 'natural', 'utc_time', 'then', 'integer', 'foreign', 'generated', 'inout', 'longblob', 'union', 'check', 'and', 'escaped', 'varbinary', 'call', 'schema', 'continue', 'sensitive', 'sql_calc_found_rows', 'high_priority', 'real', 'binary', 'linear', 'distinctrow', 'match', 'maxvalue', 'asc', 'io_before_gtids', 'select', 'hour_minute', 'ignore', 'not'}
def computedcolumnconstraint_sql(self, expression: sqlglot.expressions.ComputedColumnConstraint) -> str: View Source

    1179        def computedcolumnconstraint_sql(self, expression: exp.ComputedColumnConstraint) -> str:
    1180            persisted = "STORED" if expression.args.get("persisted") else "VIRTUAL"
    1181            return f"GENERATED ALWAYS AS ({self.sql(expression.this.unnest())}) {persisted}"

def array_sql(self, expression: sqlglot.expressions.Array) -> str: View Source

    1183        def array_sql(self, expression: exp.Array) -> str:
    1184            self.unsupported("Arrays are not supported by MySQL")
    1185            return self.function_fallback_sql(expression)

def arraycontainsall_sql(self, expression: sqlglot.expressions.ArrayContainsAll) -> str: View Source

    1187        def arraycontainsall_sql(self, expression: exp.ArrayContainsAll) -> str:
    1188            self.unsupported("Array operations are not supported by MySQL")
    1189            return self.function_fallback_sql(expression)

def dpipe_sql(self, expression: sqlglot.expressions.DPipe) -> str: View Source

    1191        def dpipe_sql(self, expression: exp.DPipe) -> str:
    1192            return self.func("CONCAT", *expression.flatten())

def extract_sql(self, expression: sqlglot.expressions.Extract) -> str: View Source

    1194        def extract_sql(self, expression: exp.Extract) -> str:
    1195            unit = expression.name
    1196            if unit and unit.lower() == "epoch":
    1197                return self.func("UNIX_TIMESTAMP", expression.expression)
    1198
    1199            return super().extract_sql(expression)

def datatype_sql(self, expression: sqlglot.expressions.DataType) -> str: View Source

    1201        def datatype_sql(self, expression: exp.DataType) -> str:
    1202            if (
    1203                self.VARCHAR_REQUIRES_SIZE
    1204                and expression.is_type(exp.DataType.Type.VARCHAR)
    1205                and not expression.expressions
    1206            ):
    1207                # `VARCHAR` must always have a size - if it doesn't, we always generate `TEXT`
    1208                return "TEXT"
    1209
    1210            # https://dev.mysql.com/doc/refman/8.0/en/numeric-type-syntax.html
    1211            result = super().datatype_sql(expression)
    1212            if expression.this in self.UNSIGNED_TYPE_MAPPING:
    1213                result = f"{result} UNSIGNED"
    1214
    1215            return result

def jsonarraycontains_sql(self, expression: sqlglot.expressions.JSONArrayContains) -> str: View Source

    1217        def jsonarraycontains_sql(self, expression: exp.JSONArrayContains) -> str:
    1218            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: View Source

    1220        def cast_sql(self, expression: exp.Cast, safe_prefix: t.Optional[str] = None) -> str:
    1221            if expression.to.this in self.TIMESTAMP_FUNC_TYPES:
    1222                return self.func("TIMESTAMP", expression.this)
    1223
    1224            to = self.CAST_MAPPING.get(expression.to.this)
    1225
    1226            if to:
    1227                expression.to.set("this", to)
    1228            return super().cast_sql(expression)

def show_sql(self, expression: sqlglot.expressions.Show) -> str: View Source

    1230        def show_sql(self, expression: exp.Show) -> str:
    1231            this = f" {expression.name}"
    1232            full = " FULL" if expression.args.get("full") else ""
    1233            global_ = " GLOBAL" if expression.args.get("global") else ""
    1234
    1235            target = self.sql(expression, "target")
    1236            target = f" {target}" if target else ""
    1237            if expression.name in ("COLUMNS", "INDEX"):
    1238                target = f" FROM{target}"
    1239            elif expression.name == "GRANTS":
    1240                target = f" FOR{target}"
    1241
    1242            db = self._prefixed_sql("FROM", expression, "db")
    1243
    1244            like = self._prefixed_sql("LIKE", expression, "like")
    1245            where = self.sql(expression, "where")
    1246
    1247            types = self.expressions(expression, key="types")
    1248            types = f" {types}" if types else types
    1249            query = self._prefixed_sql("FOR QUERY", expression, "query")
    1250
    1251            if expression.name == "PROFILE":
    1252                offset = self._prefixed_sql("OFFSET", expression, "offset")
    1253                limit = self._prefixed_sql("LIMIT", expression, "limit")
    1254            else:
    1255                offset = ""
    1256                limit = self._oldstyle_limit_sql(expression)
    1257
    1258            log = self._prefixed_sql("IN", expression, "log")
    1259            position = self._prefixed_sql("FROM", expression, "position")
    1260
    1261            channel = self._prefixed_sql("FOR CHANNEL", expression, "channel")
    1262
    1263            if expression.name == "ENGINE":
    1264                mutex_or_status = " MUTEX" if expression.args.get("mutex") else " STATUS"
    1265            else:
    1266                mutex_or_status = ""
    1267
    1268            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: View Source

    1270        def altercolumn_sql(self, expression: exp.AlterColumn) -> str:
    1271            dtype = self.sql(expression, "dtype")
    1272            if not dtype:
    1273                return super().altercolumn_sql(expression)
    1274
    1275            this = self.sql(expression, "this")
    1276            return f"MODIFY COLUMN {this} {dtype}"

def chr_sql(self, expression: sqlglot.expressions.Chr) -> str: View Source

    1290        def chr_sql(self, expression: exp.Chr) -> str:
    1291            this = self.expressions(sqls=[expression.this] + expression.expressions)
    1292            charset = expression.args.get("charset")
    1293            using = f" USING {self.sql(charset)}" if charset else ""
    1294            return f"CHAR({this}{using})"

def timestamptrunc_sql(self, expression: sqlglot.expressions.TimestampTrunc) -> str: View Source

    1296        def timestamptrunc_sql(self, expression: exp.TimestampTrunc) -> str:
    1297            unit = expression.args.get("unit")
    1298
    1299            # Pick an old-enough date to avoid negative timestamp diffs
    1300            start_ts = "'0000-01-01 00:00:00'"
    1301
    1302            # Source: https://stackoverflow.com/a/32955740
    1303            timestamp_diff = build_date_delta(exp.TimestampDiff)([unit, start_ts, expression.this])
    1304            interval = exp.Interval(this=timestamp_diff, unit=unit)
    1305            dateadd = build_date_delta_with_interval(exp.DateAdd)([start_ts, interval])
    1306
    1307            return self.sql(dateadd)

def converttimezone_sql(self, expression: sqlglot.expressions.ConvertTimezone) -> str: View Source

    1309        def converttimezone_sql(self, expression: exp.ConvertTimezone) -> str:
    1310            from_tz = expression.args.get("source_tz")
    1311            to_tz = expression.args.get("target_tz")
    1312            dt = expression.args.get("timestamp")
    1313
    1314            return self.func("CONVERT_TZ", dt, from_tz, to_tz)

def attimezone_sql(self, expression: sqlglot.expressions.AtTimeZone) -> str: View Source

    1316        def attimezone_sql(self, expression: exp.AtTimeZone) -> str:
    1317            self.unsupported("AT TIME ZONE is not supported by MySQL")
    1318            return self.sql(expression.this)

def isascii_sql(self, expression: sqlglot.expressions.IsAscii) -> str: View Source

    1320        def isascii_sql(self, expression: exp.IsAscii) -> str:
    1321            return f"REGEXP_LIKE({self.sql(expression.this)}, '^[[:ascii:]]*$')"

@unsupported_args('this')
def currentschema_sql(self, expression: sqlglot.expressions.CurrentSchema) -> str: View Source

    1323        @unsupported_args("this")
    1324        def currentschema_sql(self, expression: exp.CurrentSchema) -> str:
    1325            return self.func("SCHEMA")

SELECT_KINDS: Tuple[str, ...] = ()
TRY_SUPPORTED = False
SUPPORTS_UESCAPE = False
AFTER_HAVING_MODIFIER_TRANSFORMS = {'windows': <function Generator.<lambda>>, 'qualify': <function Generator.<lambda>>}

##### Inherited Members

sqlglot.generator.Generator
  Generator
  IGNORE_NULLS_IN_FUNC
  EXCEPT_INTERSECT_SUPPORT_ALL_CLAUSE
  CREATE_FUNCTION_RETURN_AS
  MATCHED_BY_SOURCE
  SINGLE_STRING_INTERVAL
  RENAME_TABLE_WITH_DB
  GROUPINGS_SEP
  INDEX_ON
  QUERY_HINTS
  IS_BOOL_ALLOWED
  LIMIT_IS_TOP
  RETURNING_END
  EXTRACT_ALLOWS_QUOTES
  TZ_TO_WITH_TIME_ZONE
  ALTER_TABLE_INCLUDE_COLUMN_KEYWORD
  UNNEST_WITH_ORDINALITY
  AGGREGATE_FILTER_SUPPORTED
  SEMI_ANTI_JOIN_WITH_SIDE
  COMPUTED_COLUMN_WITH_TYPE
  SUPPORTS_TABLE_COPY
  TABLESAMPLE_REQUIRES_PARENS
  TABLESAMPLE_SIZE_IS_ROWS
  TABLESAMPLE_KEYWORDS
  TABLESAMPLE_WITH_METHOD
  TABLESAMPLE_SEED_KEYWORD
  COLLATE_IS_FUNC
  DATA_TYPE_SPECIFIERS_ALLOWED
  ENSURE_BOOLS
  CTE_RECURSIVE_KEYWORD_REQUIRED
  SUPPORTS_SINGLE_ARG_CONCAT
  SUPPORTS_TABLE_ALIAS_COLUMNS
  UNPIVOT_ALIASES_ARE_IDENTIFIERS
  INSERT_OVERWRITE
  SUPPORTS_SELECT_INTO
  SUPPORTS_UNLOGGED_TABLES
  SUPPORTS_CREATE_TABLE_LIKE
  LIKE_PROPERTY_INSIDE_SCHEMA
  MULTI_ARG_DISTINCT
  JSON_PATH_SINGLE_QUOTE_ESCAPE
  SUPPORTED_JSON_PATH_PARTS
  CAN_IMPLEMENT_ARRAY_ANY
  SUPPORTS_WINDOW_EXCLUDE
  SET_OP_MODIFIERS
  COPY_PARAMS_ARE_WRAPPED
  COPY_PARAMS_EQ_REQUIRED
  COPY_HAS_INTO_KEYWORD
  STAR_EXCEPT
  HEX_FUNC
  WITH_PROPERTIES_PREFIX
  QUOTE_JSON_PATH
  SUPPORTS_EXPLODING_PROJECTIONS
  ARRAY_CONCAT_IS_VAR_LEN
  SUPPORTS_CONVERT_TIMEZONE
  SUPPORTS_UNIX_SECONDS
  ALTER_SET_WRAPPED
  ARRAY_SIZE_NAME
  ALTER_SET_TYPE
  ARRAY_SIZE_DIM_REQUIRED
  TIME_PART_SINGULARS
  TOKEN_MAPPING
  STRUCT_DELIMITER
  PARAMETER_TOKEN
  NAMED_PLACEHOLDER_TOKEN
  EXPRESSION_PRECEDES_PROPERTIES_CREATABLES
  WITH_SEPARATED_COMMENTS
  EXCLUDE_COMMENTS
  UNWRAPPED_INTERVAL_VALUES
  PARAMETERIZABLE_TEXT_TYPES
  EXPRESSIONS_WITHOUT_NESTED_CTES
  RESPECT_IGNORE_NULLS_UNSUPPORTED_EXPRESSIONS
  SENTINEL_LINE_BREAK
  pretty
  identify
  normalize
  pad
  unsupported_level
  max_unsupported
  leading_comma
  max_text_width
  comments
  dialect
  normalize_functions
  unsupported_messages
  generate
  preprocess
  unsupported
  sep
  seg
  sanitize_comment
  maybe_comment
  wrap
  no_identify
  normalize_func
  indent
  sql
  uncache_sql
  cache_sql
  characterset_sql
  column_parts
  column_sql
  columnposition_sql
  columndef_sql
  columnconstraint_sql
  autoincrementcolumnconstraint_sql
  compresscolumnconstraint_sql
  generatedasidentitycolumnconstraint_sql
  generatedasrowcolumnconstraint_sql
  periodforsystemtimeconstraint_sql
  notnullcolumnconstraint_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
  set_operation
  set_operations
  fetch_sql
  limitoptions_sql
  filter_sql
  hint_sql
  indexparameters_sql
  index_sql
  identifier_sql
  hex_sql
  lowerhex_sql
  inputoutputformat_sql
  national_sql
  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
  introducer_sql
  kill_sql
  pseudotype_sql
  objectidentifier_sql
  onconflict_sql
  returning_sql
  rowformatdelimitedproperty_sql
  withtablehint_sql
  indextablehint_sql
  historicaldata_sql
  table_parts
  table_sql
  tablefromrows_sql
  tablesample_sql
  pivot_sql
  version_sql
  tuple_sql
  update_sql
  values_sql
  var_sql
  into_sql
  from_sql
  groupingsets_sql
  rollup_sql
  cube_sql
  group_sql
  having_sql
  connect_sql
  prior_sql
  join_sql
  lambda_sql
  lateral_op
  lateral_sql
  limit_sql
  offset_sql
  setitem_sql
  set_sql
  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
  for_modifiers
  queryoption_sql
  offset_limit_modifiers
  after_limit_modifiers
  select_sql
  schema_sql
  schema_columns_sql
  star_sql
  parameter_sql
  sessionparameter_sql
  placeholder_sql
  subquery_sql
  qualify_sql
  unnest_sql
  prewhere_sql
  where_sql
  window_sql
  partition_by_sql
  windowspec_sql
  withingroup_sql
  between_sql
  bracket_offset_expressions
  bracket_sql
  all_sql
  any_sql
  exists_sql
  case_sql
  constraint_sql
  nextvaluefor_sql
  trim_sql
  convert_concat_args
  concat_sql
  concatws_sql
  check_sql
  foreignkey_sql
  primarykey_sql
  if_sql
  matchagainst_sql
  jsonkeyvalue_sql
  jsonpath_sql
  json_path_part
  formatjson_sql
  jsonobject_sql
  jsonobjectagg_sql
  jsonarray_sql
  jsonarrayagg_sql
  jsoncolumndef_sql
  jsonschema_sql
  jsontable_sql
  openjsoncolumndef_sql
  openjson_sql
  in_sql
  in_unnest_op
  interval_sql
  return_sql
  reference_sql
  anonymous_sql
  paren_sql
  neg_sql
  not_sql
  alias_sql
  pivotalias_sql
  aliases_sql
  atindex_sql
  fromtimezone_sql
  add_sql
  and_sql
  or_sql
  xor_sql
  connector_sql
  bitwiseand_sql
  bitwiseleftshift_sql
  bitwisenot_sql
  bitwiseor_sql
  bitwiserightshift_sql
  bitwisexor_sql
  currentdate_sql
  collate_sql
  command_sql
  comment_sql
  mergetreettlaction_sql
  mergetreettl_sql
  transaction_sql
  commit_sql
  rollback_sql
  alterindex_sql
  alterdiststyle_sql
  altersortkey_sql
  alterrename_sql
  renamecolumn_sql
  alterset_sql
  alter_sql
  add_column_sql
  droppartition_sql
  addconstraint_sql
  addpartition_sql
  distinct_sql
  ignorenulls_sql
  respectnulls_sql
  havingmax_sql
  intdiv_sql
  div_sql
  safedivide_sql
  overlaps_sql
  distance_sql
  dot_sql
  eq_sql
  propertyeq_sql
  escape_sql
  glob_sql
  gt_sql
  gte_sql
  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
  jsoncast_sql
  try_sql
  log_sql
  use_sql
  binary
  ceil_floor
  function_fallback_sql
  func
  format_args
  too_wide
  format_time
  expressions
  op_expressions
  naked_property
  tag_sql
  token_sql
  userdefinedfunction_sql
  joinhint_sql
  kwarg_sql
  when_sql
  whens_sql
  merge_sql
  tochar_sql
  tonumber_sql
  dictproperty_sql
  dictrange_sql
  dictsubproperty_sql
  duplicatekeyproperty_sql
  uniquekeyproperty_sql
  distributedbyproperty_sql
  oncluster_sql
  clusteredbyproperty_sql
  anyvalue_sql
  querytransform_sql
  indexconstraintoption_sql
  checkcolumnconstraint_sql
  indexcolumnconstraint_sql
  nvl2_sql
  comprehension_sql
  columnprefix_sql
  opclass_sql
  predict_sql
  forin_sql
  refresh_sql
  toarray_sql
  tsordstotime_sql
  tsordstotimestamp_sql
  tsordstodatetime_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
  json_sql
  jsonvalue_sql
  conditionalinsert_sql
  multitableinserts_sql
  oncondition_sql
  jsonextractquote_sql
  jsonexists_sql
  arrayagg_sql
  apply_sql
  grant_sql
  grantprivilege_sql
  grantprincipal_sql
  columns_sql
  overlay_sql
  todouble_sql
  string_sql
  median_sql
  overflowtruncatebehavior_sql
  unixseconds_sql
  arraysize_sql
  attach_sql
  detach_sql
  attachoption_sql
  featuresattime_sql
  watermarkcolumnconstraint_sql
  encodeproperty_sql
  includeproperty_sql
  xmlelement_sql
  xmlkeyvalueoption_sql
  partitionbyrangeproperty_sql
  partitionbyrangepropertydynamic_sql
  unpivotcolumns_sql
  analyzesample_sql
  analyzestatistics_sql
  analyzehistogram_sql
  analyzedelete_sql
  analyzelistchainedrows_sql
  analyzevalidate_sql
  analyze_sql
  xmltable_sql
  xmlnamespace_sql
  export_sql
  declare_sql
  declareitem_sql
  recursivewithsearch_sql
  parameterizedagg_sql
  anonymousaggfunc_sql
  combinedaggfunc_sql
  combinedparameterizedagg_sql
  get_put_sql
  translatecharacters_sql