sqlglot.dialects.mysql
1from __future__ import annotations 2 3import typing as t 4 5from sqlglot import exp, generator, parser, tokens, transforms 6from sqlglot.dialects.dialect import ( 7 Dialect, 8 NormalizationStrategy, 9 arrow_json_extract_sql, 10 date_add_interval_sql, 11 datestrtodate_sql, 12 build_formatted_time, 13 isnull_to_is_null, 14 locate_to_strposition, 15 max_or_greatest, 16 min_or_least, 17 no_ilike_sql, 18 no_paren_current_date_sql, 19 no_pivot_sql, 20 no_tablesample_sql, 21 no_trycast_sql, 22 build_date_delta, 23 build_date_delta_with_interval, 24 rename_func, 25 strposition_to_locate_sql, 26 unit_to_var, 27) 28from sqlglot.helper import seq_get 29from sqlglot.tokens import TokenType 30 31 32def _show_parser(*args: t.Any, **kwargs: t.Any) -> t.Callable[[MySQL.Parser], exp.Show]: 33 def _parse(self: MySQL.Parser) -> exp.Show: 34 return self._parse_show_mysql(*args, **kwargs) 35 36 return _parse 37 38 39def _date_trunc_sql(self: MySQL.Generator, expression: exp.DateTrunc) -> str: 40 expr = self.sql(expression, "this") 41 unit = expression.text("unit").upper() 42 43 if unit == "WEEK": 44 concat = f"CONCAT(YEAR({expr}), ' ', WEEK({expr}, 1), ' 1')" 45 date_format = "%Y %u %w" 46 elif unit == "MONTH": 47 concat = f"CONCAT(YEAR({expr}), ' ', MONTH({expr}), ' 1')" 48 date_format = "%Y %c %e" 49 elif unit == "QUARTER": 50 concat = f"CONCAT(YEAR({expr}), ' ', QUARTER({expr}) * 3 - 2, ' 1')" 51 date_format = "%Y %c %e" 52 elif unit == "YEAR": 53 concat = f"CONCAT(YEAR({expr}), ' 1 1')" 54 date_format = "%Y %c %e" 55 else: 56 if unit != "DAY": 57 self.unsupported(f"Unexpected interval unit: {unit}") 58 return self.func("DATE", expr) 59 60 return self.func("STR_TO_DATE", concat, f"'{date_format}'") 61 62 63# All specifiers for time parts (as opposed to date parts) 64# https://dev.mysql.com/doc/refman/8.0/en/date-and-time-functions.html#function_date-format 65TIME_SPECIFIERS = {"f", "H", "h", "I", "i", "k", "l", "p", "r", "S", "s", "T"} 66 67 68def _has_time_specifier(date_format: str) -> bool: 69 i = 0 70 length = len(date_format) 71 72 while i < length: 73 if date_format[i] == "%": 74 i += 1 75 if i < length and date_format[i] in TIME_SPECIFIERS: 76 return True 77 i += 1 78 return False 79 80 81def _str_to_date(args: t.List) -> exp.StrToDate | exp.StrToTime: 82 mysql_date_format = seq_get(args, 1) 83 date_format = MySQL.format_time(mysql_date_format) 84 this = seq_get(args, 0) 85 86 if mysql_date_format and _has_time_specifier(mysql_date_format.name): 87 return exp.StrToTime(this=this, format=date_format) 88 89 return exp.StrToDate(this=this, format=date_format) 90 91 92def _str_to_date_sql( 93 self: MySQL.Generator, expression: exp.StrToDate | exp.StrToTime | exp.TsOrDsToDate 94) -> str: 95 return self.func("STR_TO_DATE", expression.this, self.format_time(expression)) 96 97 98def _trim_sql(self: MySQL.Generator, expression: exp.Trim) -> str: 99 target = self.sql(expression, "this") 100 trim_type = self.sql(expression, "position") 101 remove_chars = self.sql(expression, "expression") 102 103 # Use TRIM/LTRIM/RTRIM syntax if the expression isn't mysql-specific 104 if not remove_chars: 105 return self.trim_sql(expression) 106 107 trim_type = f"{trim_type} " if trim_type else "" 108 remove_chars = f"{remove_chars} " if remove_chars else "" 109 from_part = "FROM " if trim_type or remove_chars else "" 110 return f"TRIM({trim_type}{remove_chars}{from_part}{target})" 111 112 113def _unix_to_time_sql(self: MySQL.Generator, expression: exp.UnixToTime) -> str: 114 scale = expression.args.get("scale") 115 timestamp = expression.this 116 117 if scale in (None, exp.UnixToTime.SECONDS): 118 return self.func("FROM_UNIXTIME", timestamp, self.format_time(expression)) 119 120 return self.func( 121 "FROM_UNIXTIME", 122 exp.Div(this=timestamp, expression=exp.func("POW", 10, scale)), 123 self.format_time(expression), 124 ) 125 126 127def date_add_sql( 128 kind: str, 129) -> t.Callable[[generator.Generator, exp.Expression], str]: 130 def func(self: generator.Generator, expression: exp.Expression) -> str: 131 return self.func( 132 f"DATE_{kind}", 133 expression.this, 134 exp.Interval(this=expression.expression, unit=unit_to_var(expression)), 135 ) 136 137 return func 138 139 140def _ts_or_ds_to_date_sql(self: MySQL.Generator, expression: exp.TsOrDsToDate) -> str: 141 time_format = expression.args.get("format") 142 return _str_to_date_sql(self, expression) if time_format else self.func("DATE", expression.this) 143 144 145def _remove_ts_or_ds_to_date( 146 to_sql: t.Optional[t.Callable[[MySQL.Generator, exp.Expression], str]] = None, 147 args: t.Tuple[str, ...] = ("this",), 148) -> t.Callable[[MySQL.Generator, exp.Func], str]: 149 def func(self: MySQL.Generator, expression: exp.Func) -> str: 150 for arg_key in args: 151 arg = expression.args.get(arg_key) 152 if isinstance(arg, exp.TsOrDsToDate) and not arg.args.get("format"): 153 expression.set(arg_key, arg.this) 154 155 return to_sql(self, expression) if to_sql else self.function_fallback_sql(expression) 156 157 return func 158 159 160class MySQL(Dialect): 161 # https://dev.mysql.com/doc/refman/8.0/en/identifiers.html 162 IDENTIFIERS_CAN_START_WITH_DIGIT = True 163 164 # We default to treating all identifiers as case-sensitive, since it matches MySQL's 165 # behavior on Linux systems. For MacOS and Windows systems, one can override this 166 # setting by specifying `dialect="mysql, normalization_strategy = lowercase"`. 167 # 168 # See also https://dev.mysql.com/doc/refman/8.2/en/identifier-case-sensitivity.html 169 NORMALIZATION_STRATEGY = NormalizationStrategy.CASE_SENSITIVE 170 171 TIME_FORMAT = "'%Y-%m-%d %T'" 172 DPIPE_IS_STRING_CONCAT = False 173 SUPPORTS_USER_DEFINED_TYPES = False 174 SUPPORTS_SEMI_ANTI_JOIN = False 175 SAFE_DIVISION = True 176 177 # https://prestodb.io/docs/current/functions/datetime.html#mysql-date-functions 178 TIME_MAPPING = { 179 "%M": "%B", 180 "%c": "%-m", 181 "%e": "%-d", 182 "%h": "%I", 183 "%i": "%M", 184 "%s": "%S", 185 "%u": "%W", 186 "%k": "%-H", 187 "%l": "%-I", 188 "%T": "%H:%M:%S", 189 "%W": "%a", 190 } 191 192 class Tokenizer(tokens.Tokenizer): 193 QUOTES = ["'", '"'] 194 COMMENTS = ["--", "#", ("/*", "*/")] 195 IDENTIFIERS = ["`"] 196 STRING_ESCAPES = ["'", '"', "\\"] 197 BIT_STRINGS = [("b'", "'"), ("B'", "'"), ("0b", "")] 198 HEX_STRINGS = [("x'", "'"), ("X'", "'"), ("0x", "")] 199 200 KEYWORDS = { 201 **tokens.Tokenizer.KEYWORDS, 202 "CHARSET": TokenType.CHARACTER_SET, 203 "FORCE": TokenType.FORCE, 204 "IGNORE": TokenType.IGNORE, 205 "KEY": TokenType.KEY, 206 "LOCK TABLES": TokenType.COMMAND, 207 "LONGBLOB": TokenType.LONGBLOB, 208 "LONGTEXT": TokenType.LONGTEXT, 209 "MEDIUMBLOB": TokenType.MEDIUMBLOB, 210 "TINYBLOB": TokenType.TINYBLOB, 211 "TINYTEXT": TokenType.TINYTEXT, 212 "MEDIUMTEXT": TokenType.MEDIUMTEXT, 213 "MEDIUMINT": TokenType.MEDIUMINT, 214 "MEMBER OF": TokenType.MEMBER_OF, 215 "SEPARATOR": TokenType.SEPARATOR, 216 "START": TokenType.BEGIN, 217 "SIGNED": TokenType.BIGINT, 218 "SIGNED INTEGER": TokenType.BIGINT, 219 "UNLOCK TABLES": TokenType.COMMAND, 220 "UNSIGNED": TokenType.UBIGINT, 221 "UNSIGNED INTEGER": TokenType.UBIGINT, 222 "YEAR": TokenType.YEAR, 223 "_ARMSCII8": TokenType.INTRODUCER, 224 "_ASCII": TokenType.INTRODUCER, 225 "_BIG5": TokenType.INTRODUCER, 226 "_BINARY": TokenType.INTRODUCER, 227 "_CP1250": TokenType.INTRODUCER, 228 "_CP1251": TokenType.INTRODUCER, 229 "_CP1256": TokenType.INTRODUCER, 230 "_CP1257": TokenType.INTRODUCER, 231 "_CP850": TokenType.INTRODUCER, 232 "_CP852": TokenType.INTRODUCER, 233 "_CP866": TokenType.INTRODUCER, 234 "_CP932": TokenType.INTRODUCER, 235 "_DEC8": TokenType.INTRODUCER, 236 "_EUCJPMS": TokenType.INTRODUCER, 237 "_EUCKR": TokenType.INTRODUCER, 238 "_GB18030": TokenType.INTRODUCER, 239 "_GB2312": TokenType.INTRODUCER, 240 "_GBK": TokenType.INTRODUCER, 241 "_GEOSTD8": TokenType.INTRODUCER, 242 "_GREEK": TokenType.INTRODUCER, 243 "_HEBREW": TokenType.INTRODUCER, 244 "_HP8": TokenType.INTRODUCER, 245 "_KEYBCS2": TokenType.INTRODUCER, 246 "_KOI8R": TokenType.INTRODUCER, 247 "_KOI8U": TokenType.INTRODUCER, 248 "_LATIN1": TokenType.INTRODUCER, 249 "_LATIN2": TokenType.INTRODUCER, 250 "_LATIN5": TokenType.INTRODUCER, 251 "_LATIN7": TokenType.INTRODUCER, 252 "_MACCE": TokenType.INTRODUCER, 253 "_MACROMAN": TokenType.INTRODUCER, 254 "_SJIS": TokenType.INTRODUCER, 255 "_SWE7": TokenType.INTRODUCER, 256 "_TIS620": TokenType.INTRODUCER, 257 "_UCS2": TokenType.INTRODUCER, 258 "_UJIS": TokenType.INTRODUCER, 259 # https://dev.mysql.com/doc/refman/8.0/en/string-literals.html 260 "_UTF8": TokenType.INTRODUCER, 261 "_UTF16": TokenType.INTRODUCER, 262 "_UTF16LE": TokenType.INTRODUCER, 263 "_UTF32": TokenType.INTRODUCER, 264 "_UTF8MB3": TokenType.INTRODUCER, 265 "_UTF8MB4": TokenType.INTRODUCER, 266 "@@": TokenType.SESSION_PARAMETER, 267 } 268 269 COMMANDS = {*tokens.Tokenizer.COMMANDS, TokenType.REPLACE} - {TokenType.SHOW} 270 271 class Parser(parser.Parser): 272 FUNC_TOKENS = { 273 *parser.Parser.FUNC_TOKENS, 274 TokenType.DATABASE, 275 TokenType.SCHEMA, 276 TokenType.VALUES, 277 } 278 279 CONJUNCTION = { 280 **parser.Parser.CONJUNCTION, 281 TokenType.DAMP: exp.And, 282 TokenType.XOR: exp.Xor, 283 } 284 285 DISJUNCTION = { 286 **parser.Parser.DISJUNCTION, 287 TokenType.DPIPE: exp.Or, 288 } 289 290 TABLE_ALIAS_TOKENS = ( 291 parser.Parser.TABLE_ALIAS_TOKENS - parser.Parser.TABLE_INDEX_HINT_TOKENS 292 ) 293 294 RANGE_PARSERS = { 295 **parser.Parser.RANGE_PARSERS, 296 TokenType.MEMBER_OF: lambda self, this: self.expression( 297 exp.JSONArrayContains, 298 this=this, 299 expression=self._parse_wrapped(self._parse_expression), 300 ), 301 } 302 303 FUNCTIONS = { 304 **parser.Parser.FUNCTIONS, 305 "DATE": lambda args: exp.TsOrDsToDate(this=seq_get(args, 0)), 306 "DATE_ADD": build_date_delta_with_interval(exp.DateAdd), 307 "DATE_FORMAT": build_formatted_time(exp.TimeToStr, "mysql"), 308 "DATE_SUB": build_date_delta_with_interval(exp.DateSub), 309 "DAY": lambda args: exp.Day(this=exp.TsOrDsToDate(this=seq_get(args, 0))), 310 "DAYOFMONTH": lambda args: exp.DayOfMonth(this=exp.TsOrDsToDate(this=seq_get(args, 0))), 311 "DAYOFWEEK": lambda args: exp.DayOfWeek(this=exp.TsOrDsToDate(this=seq_get(args, 0))), 312 "DAYOFYEAR": lambda args: exp.DayOfYear(this=exp.TsOrDsToDate(this=seq_get(args, 0))), 313 "INSTR": lambda args: exp.StrPosition(substr=seq_get(args, 1), this=seq_get(args, 0)), 314 "FROM_UNIXTIME": build_formatted_time(exp.UnixToTime, "mysql"), 315 "ISNULL": isnull_to_is_null, 316 "LOCATE": locate_to_strposition, 317 "MAKETIME": exp.TimeFromParts.from_arg_list, 318 "MONTH": lambda args: exp.Month(this=exp.TsOrDsToDate(this=seq_get(args, 0))), 319 "MONTHNAME": lambda args: exp.TimeToStr( 320 this=exp.TsOrDsToDate(this=seq_get(args, 0)), 321 format=exp.Literal.string("%B"), 322 ), 323 "STR_TO_DATE": _str_to_date, 324 "TIMESTAMPDIFF": build_date_delta(exp.TimestampDiff), 325 "TO_DAYS": lambda args: exp.paren( 326 exp.DateDiff( 327 this=exp.TsOrDsToDate(this=seq_get(args, 0)), 328 expression=exp.TsOrDsToDate(this=exp.Literal.string("0000-01-01")), 329 unit=exp.var("DAY"), 330 ) 331 + 1 332 ), 333 "WEEK": lambda args: exp.Week( 334 this=exp.TsOrDsToDate(this=seq_get(args, 0)), mode=seq_get(args, 1) 335 ), 336 "WEEKOFYEAR": lambda args: exp.WeekOfYear(this=exp.TsOrDsToDate(this=seq_get(args, 0))), 337 "YEAR": lambda args: exp.Year(this=exp.TsOrDsToDate(this=seq_get(args, 0))), 338 } 339 340 FUNCTION_PARSERS = { 341 **parser.Parser.FUNCTION_PARSERS, 342 "CHAR": lambda self: self._parse_chr(), 343 "GROUP_CONCAT": lambda self: self._parse_group_concat(), 344 # https://dev.mysql.com/doc/refman/5.7/en/miscellaneous-functions.html#function_values 345 "VALUES": lambda self: self.expression( 346 exp.Anonymous, this="VALUES", expressions=[self._parse_id_var()] 347 ), 348 } 349 350 STATEMENT_PARSERS = { 351 **parser.Parser.STATEMENT_PARSERS, 352 TokenType.SHOW: lambda self: self._parse_show(), 353 } 354 355 SHOW_PARSERS = { 356 "BINARY LOGS": _show_parser("BINARY LOGS"), 357 "MASTER LOGS": _show_parser("BINARY LOGS"), 358 "BINLOG EVENTS": _show_parser("BINLOG EVENTS"), 359 "CHARACTER SET": _show_parser("CHARACTER SET"), 360 "CHARSET": _show_parser("CHARACTER SET"), 361 "COLLATION": _show_parser("COLLATION"), 362 "FULL COLUMNS": _show_parser("COLUMNS", target="FROM", full=True), 363 "COLUMNS": _show_parser("COLUMNS", target="FROM"), 364 "CREATE DATABASE": _show_parser("CREATE DATABASE", target=True), 365 "CREATE EVENT": _show_parser("CREATE EVENT", target=True), 366 "CREATE FUNCTION": _show_parser("CREATE FUNCTION", target=True), 367 "CREATE PROCEDURE": _show_parser("CREATE PROCEDURE", target=True), 368 "CREATE TABLE": _show_parser("CREATE TABLE", target=True), 369 "CREATE TRIGGER": _show_parser("CREATE TRIGGER", target=True), 370 "CREATE VIEW": _show_parser("CREATE VIEW", target=True), 371 "DATABASES": _show_parser("DATABASES"), 372 "SCHEMAS": _show_parser("DATABASES"), 373 "ENGINE": _show_parser("ENGINE", target=True), 374 "STORAGE ENGINES": _show_parser("ENGINES"), 375 "ENGINES": _show_parser("ENGINES"), 376 "ERRORS": _show_parser("ERRORS"), 377 "EVENTS": _show_parser("EVENTS"), 378 "FUNCTION CODE": _show_parser("FUNCTION CODE", target=True), 379 "FUNCTION STATUS": _show_parser("FUNCTION STATUS"), 380 "GRANTS": _show_parser("GRANTS", target="FOR"), 381 "INDEX": _show_parser("INDEX", target="FROM"), 382 "MASTER STATUS": _show_parser("MASTER STATUS"), 383 "OPEN TABLES": _show_parser("OPEN TABLES"), 384 "PLUGINS": _show_parser("PLUGINS"), 385 "PROCEDURE CODE": _show_parser("PROCEDURE CODE", target=True), 386 "PROCEDURE STATUS": _show_parser("PROCEDURE STATUS"), 387 "PRIVILEGES": _show_parser("PRIVILEGES"), 388 "FULL PROCESSLIST": _show_parser("PROCESSLIST", full=True), 389 "PROCESSLIST": _show_parser("PROCESSLIST"), 390 "PROFILE": _show_parser("PROFILE"), 391 "PROFILES": _show_parser("PROFILES"), 392 "RELAYLOG EVENTS": _show_parser("RELAYLOG EVENTS"), 393 "REPLICAS": _show_parser("REPLICAS"), 394 "SLAVE HOSTS": _show_parser("REPLICAS"), 395 "REPLICA STATUS": _show_parser("REPLICA STATUS"), 396 "SLAVE STATUS": _show_parser("REPLICA STATUS"), 397 "GLOBAL STATUS": _show_parser("STATUS", global_=True), 398 "SESSION STATUS": _show_parser("STATUS"), 399 "STATUS": _show_parser("STATUS"), 400 "TABLE STATUS": _show_parser("TABLE STATUS"), 401 "FULL TABLES": _show_parser("TABLES", full=True), 402 "TABLES": _show_parser("TABLES"), 403 "TRIGGERS": _show_parser("TRIGGERS"), 404 "GLOBAL VARIABLES": _show_parser("VARIABLES", global_=True), 405 "SESSION VARIABLES": _show_parser("VARIABLES"), 406 "VARIABLES": _show_parser("VARIABLES"), 407 "WARNINGS": _show_parser("WARNINGS"), 408 } 409 410 PROPERTY_PARSERS = { 411 **parser.Parser.PROPERTY_PARSERS, 412 "LOCK": lambda self: self._parse_property_assignment(exp.LockProperty), 413 } 414 415 SET_PARSERS = { 416 **parser.Parser.SET_PARSERS, 417 "PERSIST": lambda self: self._parse_set_item_assignment("PERSIST"), 418 "PERSIST_ONLY": lambda self: self._parse_set_item_assignment("PERSIST_ONLY"), 419 "CHARACTER SET": lambda self: self._parse_set_item_charset("CHARACTER SET"), 420 "CHARSET": lambda self: self._parse_set_item_charset("CHARACTER SET"), 421 "NAMES": lambda self: self._parse_set_item_names(), 422 } 423 424 CONSTRAINT_PARSERS = { 425 **parser.Parser.CONSTRAINT_PARSERS, 426 "FULLTEXT": lambda self: self._parse_index_constraint(kind="FULLTEXT"), 427 "INDEX": lambda self: self._parse_index_constraint(), 428 "KEY": lambda self: self._parse_index_constraint(), 429 "SPATIAL": lambda self: self._parse_index_constraint(kind="SPATIAL"), 430 } 431 432 ALTER_PARSERS = { 433 **parser.Parser.ALTER_PARSERS, 434 "MODIFY": lambda self: self._parse_alter_table_alter(), 435 } 436 437 SCHEMA_UNNAMED_CONSTRAINTS = { 438 *parser.Parser.SCHEMA_UNNAMED_CONSTRAINTS, 439 "FULLTEXT", 440 "INDEX", 441 "KEY", 442 "SPATIAL", 443 } 444 445 PROFILE_TYPES: parser.OPTIONS_TYPE = { 446 **dict.fromkeys(("ALL", "CPU", "IPC", "MEMORY", "SOURCE", "SWAPS"), tuple()), 447 "BLOCK": ("IO",), 448 "CONTEXT": ("SWITCHES",), 449 "PAGE": ("FAULTS",), 450 } 451 452 TYPE_TOKENS = { 453 *parser.Parser.TYPE_TOKENS, 454 TokenType.SET, 455 } 456 457 ENUM_TYPE_TOKENS = { 458 *parser.Parser.ENUM_TYPE_TOKENS, 459 TokenType.SET, 460 } 461 462 LOG_DEFAULTS_TO_LN = True 463 STRING_ALIASES = True 464 VALUES_FOLLOWED_BY_PAREN = False 465 SUPPORTS_PARTITION_SELECTION = True 466 467 def _parse_primary_key_part(self) -> t.Optional[exp.Expression]: 468 this = self._parse_id_var() 469 if not self._match(TokenType.L_PAREN): 470 return this 471 472 expression = self._parse_number() 473 self._match_r_paren() 474 return self.expression(exp.ColumnPrefix, this=this, expression=expression) 475 476 def _parse_index_constraint( 477 self, kind: t.Optional[str] = None 478 ) -> exp.IndexColumnConstraint: 479 if kind: 480 self._match_texts(("INDEX", "KEY")) 481 482 this = self._parse_id_var(any_token=False) 483 index_type = self._match(TokenType.USING) and self._advance_any() and self._prev.text 484 expressions = self._parse_wrapped_csv(self._parse_ordered) 485 486 options = [] 487 while True: 488 if self._match_text_seq("KEY_BLOCK_SIZE"): 489 self._match(TokenType.EQ) 490 opt = exp.IndexConstraintOption(key_block_size=self._parse_number()) 491 elif self._match(TokenType.USING): 492 opt = exp.IndexConstraintOption(using=self._advance_any() and self._prev.text) 493 elif self._match_text_seq("WITH", "PARSER"): 494 opt = exp.IndexConstraintOption(parser=self._parse_var(any_token=True)) 495 elif self._match(TokenType.COMMENT): 496 opt = exp.IndexConstraintOption(comment=self._parse_string()) 497 elif self._match_text_seq("VISIBLE"): 498 opt = exp.IndexConstraintOption(visible=True) 499 elif self._match_text_seq("INVISIBLE"): 500 opt = exp.IndexConstraintOption(visible=False) 501 elif self._match_text_seq("ENGINE_ATTRIBUTE"): 502 self._match(TokenType.EQ) 503 opt = exp.IndexConstraintOption(engine_attr=self._parse_string()) 504 elif self._match_text_seq("SECONDARY_ENGINE_ATTRIBUTE"): 505 self._match(TokenType.EQ) 506 opt = exp.IndexConstraintOption(secondary_engine_attr=self._parse_string()) 507 else: 508 opt = None 509 510 if not opt: 511 break 512 513 options.append(opt) 514 515 return self.expression( 516 exp.IndexColumnConstraint, 517 this=this, 518 expressions=expressions, 519 kind=kind, 520 index_type=index_type, 521 options=options, 522 ) 523 524 def _parse_show_mysql( 525 self, 526 this: str, 527 target: bool | str = False, 528 full: t.Optional[bool] = None, 529 global_: t.Optional[bool] = None, 530 ) -> exp.Show: 531 if target: 532 if isinstance(target, str): 533 self._match_text_seq(target) 534 target_id = self._parse_id_var() 535 else: 536 target_id = None 537 538 log = self._parse_string() if self._match_text_seq("IN") else None 539 540 if this in ("BINLOG EVENTS", "RELAYLOG EVENTS"): 541 position = self._parse_number() if self._match_text_seq("FROM") else None 542 db = None 543 else: 544 position = None 545 db = None 546 547 if self._match(TokenType.FROM): 548 db = self._parse_id_var() 549 elif self._match(TokenType.DOT): 550 db = target_id 551 target_id = self._parse_id_var() 552 553 channel = self._parse_id_var() if self._match_text_seq("FOR", "CHANNEL") else None 554 555 like = self._parse_string() if self._match_text_seq("LIKE") else None 556 where = self._parse_where() 557 558 if this == "PROFILE": 559 types = self._parse_csv(lambda: self._parse_var_from_options(self.PROFILE_TYPES)) 560 query = self._parse_number() if self._match_text_seq("FOR", "QUERY") else None 561 offset = self._parse_number() if self._match_text_seq("OFFSET") else None 562 limit = self._parse_number() if self._match_text_seq("LIMIT") else None 563 else: 564 types, query = None, None 565 offset, limit = self._parse_oldstyle_limit() 566 567 mutex = True if self._match_text_seq("MUTEX") else None 568 mutex = False if self._match_text_seq("STATUS") else mutex 569 570 return self.expression( 571 exp.Show, 572 this=this, 573 target=target_id, 574 full=full, 575 log=log, 576 position=position, 577 db=db, 578 channel=channel, 579 like=like, 580 where=where, 581 types=types, 582 query=query, 583 offset=offset, 584 limit=limit, 585 mutex=mutex, 586 **{"global": global_}, # type: ignore 587 ) 588 589 def _parse_oldstyle_limit( 590 self, 591 ) -> t.Tuple[t.Optional[exp.Expression], t.Optional[exp.Expression]]: 592 limit = None 593 offset = None 594 if self._match_text_seq("LIMIT"): 595 parts = self._parse_csv(self._parse_number) 596 if len(parts) == 1: 597 limit = parts[0] 598 elif len(parts) == 2: 599 limit = parts[1] 600 offset = parts[0] 601 602 return offset, limit 603 604 def _parse_set_item_charset(self, kind: str) -> exp.Expression: 605 this = self._parse_string() or self._parse_unquoted_field() 606 return self.expression(exp.SetItem, this=this, kind=kind) 607 608 def _parse_set_item_names(self) -> exp.Expression: 609 charset = self._parse_string() or self._parse_unquoted_field() 610 if self._match_text_seq("COLLATE"): 611 collate = self._parse_string() or self._parse_unquoted_field() 612 else: 613 collate = None 614 615 return self.expression(exp.SetItem, this=charset, collate=collate, kind="NAMES") 616 617 def _parse_type( 618 self, parse_interval: bool = True, fallback_to_identifier: bool = False 619 ) -> t.Optional[exp.Expression]: 620 # mysql binary is special and can work anywhere, even in order by operations 621 # it operates like a no paren func 622 if self._match(TokenType.BINARY, advance=False): 623 data_type = self._parse_types(check_func=True, allow_identifiers=False) 624 625 if isinstance(data_type, exp.DataType): 626 return self.expression(exp.Cast, this=self._parse_column(), to=data_type) 627 628 return super()._parse_type( 629 parse_interval=parse_interval, fallback_to_identifier=fallback_to_identifier 630 ) 631 632 def _parse_chr(self) -> t.Optional[exp.Expression]: 633 expressions = self._parse_csv(self._parse_assignment) 634 kwargs: t.Dict[str, t.Any] = {"this": seq_get(expressions, 0)} 635 636 if len(expressions) > 1: 637 kwargs["expressions"] = expressions[1:] 638 639 if self._match(TokenType.USING): 640 kwargs["charset"] = self._parse_var() 641 642 return self.expression(exp.Chr, **kwargs) 643 644 def _parse_group_concat(self) -> t.Optional[exp.Expression]: 645 def concat_exprs( 646 node: t.Optional[exp.Expression], exprs: t.List[exp.Expression] 647 ) -> exp.Expression: 648 if isinstance(node, exp.Distinct) and len(node.expressions) > 1: 649 concat_exprs = [ 650 self.expression(exp.Concat, expressions=node.expressions, safe=True) 651 ] 652 node.set("expressions", concat_exprs) 653 return node 654 if len(exprs) == 1: 655 return exprs[0] 656 return self.expression(exp.Concat, expressions=args, safe=True) 657 658 args = self._parse_csv(self._parse_lambda) 659 660 if args: 661 order = args[-1] if isinstance(args[-1], exp.Order) else None 662 663 if order: 664 # Order By is the last (or only) expression in the list and has consumed the 'expr' before it, 665 # remove 'expr' from exp.Order and add it back to args 666 args[-1] = order.this 667 order.set("this", concat_exprs(order.this, args)) 668 669 this = order or concat_exprs(args[0], args) 670 else: 671 this = None 672 673 separator = self._parse_field() if self._match(TokenType.SEPARATOR) else None 674 675 return self.expression(exp.GroupConcat, this=this, separator=separator) 676 677 class Generator(generator.Generator): 678 INTERVAL_ALLOWS_PLURAL_FORM = False 679 LOCKING_READS_SUPPORTED = True 680 NULL_ORDERING_SUPPORTED = None 681 JOIN_HINTS = False 682 TABLE_HINTS = True 683 DUPLICATE_KEY_UPDATE_WITH_SET = False 684 QUERY_HINT_SEP = " " 685 VALUES_AS_TABLE = False 686 NVL2_SUPPORTED = False 687 LAST_DAY_SUPPORTS_DATE_PART = False 688 JSON_TYPE_REQUIRED_FOR_EXTRACTION = True 689 JSON_PATH_BRACKETED_KEY_SUPPORTED = False 690 JSON_KEY_VALUE_PAIR_SEP = "," 691 SUPPORTS_TO_NUMBER = False 692 PARSE_JSON_NAME = None 693 PAD_FILL_PATTERN_IS_REQUIRED = True 694 WRAP_DERIVED_VALUES = False 695 696 TRANSFORMS = { 697 **generator.Generator.TRANSFORMS, 698 exp.ArrayAgg: rename_func("GROUP_CONCAT"), 699 exp.CurrentDate: no_paren_current_date_sql, 700 exp.DateDiff: _remove_ts_or_ds_to_date( 701 lambda self, e: self.func("DATEDIFF", e.this, e.expression), ("this", "expression") 702 ), 703 exp.DateAdd: _remove_ts_or_ds_to_date(date_add_sql("ADD")), 704 exp.DateStrToDate: datestrtodate_sql, 705 exp.DateSub: _remove_ts_or_ds_to_date(date_add_sql("SUB")), 706 exp.DateTrunc: _date_trunc_sql, 707 exp.Day: _remove_ts_or_ds_to_date(), 708 exp.DayOfMonth: _remove_ts_or_ds_to_date(rename_func("DAYOFMONTH")), 709 exp.DayOfWeek: _remove_ts_or_ds_to_date(rename_func("DAYOFWEEK")), 710 exp.DayOfYear: _remove_ts_or_ds_to_date(rename_func("DAYOFYEAR")), 711 exp.GroupConcat: lambda self, 712 e: f"""GROUP_CONCAT({self.sql(e, "this")} SEPARATOR {self.sql(e, "separator") or "','"})""", 713 exp.ILike: no_ilike_sql, 714 exp.JSONExtractScalar: arrow_json_extract_sql, 715 exp.Max: max_or_greatest, 716 exp.Min: min_or_least, 717 exp.Month: _remove_ts_or_ds_to_date(), 718 exp.NullSafeEQ: lambda self, e: self.binary(e, "<=>"), 719 exp.NullSafeNEQ: lambda self, e: f"NOT {self.binary(e, '<=>')}", 720 exp.Pivot: no_pivot_sql, 721 exp.Select: transforms.preprocess( 722 [ 723 transforms.eliminate_distinct_on, 724 transforms.eliminate_semi_and_anti_joins, 725 transforms.eliminate_qualify, 726 transforms.eliminate_full_outer_join, 727 ] 728 ), 729 exp.StrPosition: strposition_to_locate_sql, 730 exp.StrToDate: _str_to_date_sql, 731 exp.StrToTime: _str_to_date_sql, 732 exp.Stuff: rename_func("INSERT"), 733 exp.TableSample: no_tablesample_sql, 734 exp.TimeFromParts: rename_func("MAKETIME"), 735 exp.TimestampAdd: date_add_interval_sql("DATE", "ADD"), 736 exp.TimestampDiff: lambda self, e: self.func( 737 "TIMESTAMPDIFF", unit_to_var(e), e.expression, e.this 738 ), 739 exp.TimestampSub: date_add_interval_sql("DATE", "SUB"), 740 exp.TimeStrToUnix: rename_func("UNIX_TIMESTAMP"), 741 exp.TimeStrToTime: lambda self, e: self.sql( 742 exp.cast(e.this, exp.DataType.Type.DATETIME, copy=True) 743 ), 744 exp.TimeToStr: _remove_ts_or_ds_to_date( 745 lambda self, e: self.func("DATE_FORMAT", e.this, self.format_time(e)) 746 ), 747 exp.Trim: _trim_sql, 748 exp.TryCast: no_trycast_sql, 749 exp.TsOrDsAdd: date_add_sql("ADD"), 750 exp.TsOrDsDiff: lambda self, e: self.func("DATEDIFF", e.this, e.expression), 751 exp.TsOrDsToDate: _ts_or_ds_to_date_sql, 752 exp.UnixToTime: _unix_to_time_sql, 753 exp.Week: _remove_ts_or_ds_to_date(), 754 exp.WeekOfYear: _remove_ts_or_ds_to_date(rename_func("WEEKOFYEAR")), 755 exp.Year: _remove_ts_or_ds_to_date(), 756 } 757 758 UNSIGNED_TYPE_MAPPING = { 759 exp.DataType.Type.UBIGINT: "BIGINT", 760 exp.DataType.Type.UINT: "INT", 761 exp.DataType.Type.UMEDIUMINT: "MEDIUMINT", 762 exp.DataType.Type.USMALLINT: "SMALLINT", 763 exp.DataType.Type.UTINYINT: "TINYINT", 764 exp.DataType.Type.UDECIMAL: "DECIMAL", 765 } 766 767 TIMESTAMP_TYPE_MAPPING = { 768 exp.DataType.Type.TIMESTAMP: "DATETIME", 769 exp.DataType.Type.TIMESTAMPTZ: "TIMESTAMP", 770 exp.DataType.Type.TIMESTAMPLTZ: "TIMESTAMP", 771 } 772 773 TYPE_MAPPING = { 774 **generator.Generator.TYPE_MAPPING, 775 **UNSIGNED_TYPE_MAPPING, 776 **TIMESTAMP_TYPE_MAPPING, 777 } 778 779 TYPE_MAPPING.pop(exp.DataType.Type.MEDIUMTEXT) 780 TYPE_MAPPING.pop(exp.DataType.Type.LONGTEXT) 781 TYPE_MAPPING.pop(exp.DataType.Type.TINYTEXT) 782 TYPE_MAPPING.pop(exp.DataType.Type.MEDIUMBLOB) 783 TYPE_MAPPING.pop(exp.DataType.Type.LONGBLOB) 784 TYPE_MAPPING.pop(exp.DataType.Type.TINYBLOB) 785 786 PROPERTIES_LOCATION = { 787 **generator.Generator.PROPERTIES_LOCATION, 788 exp.TransientProperty: exp.Properties.Location.UNSUPPORTED, 789 exp.VolatileProperty: exp.Properties.Location.UNSUPPORTED, 790 } 791 792 LIMIT_FETCH = "LIMIT" 793 794 LIMIT_ONLY_LITERALS = True 795 796 CHAR_CAST_MAPPING = dict.fromkeys( 797 ( 798 exp.DataType.Type.LONGTEXT, 799 exp.DataType.Type.LONGBLOB, 800 exp.DataType.Type.MEDIUMBLOB, 801 exp.DataType.Type.MEDIUMTEXT, 802 exp.DataType.Type.TEXT, 803 exp.DataType.Type.TINYBLOB, 804 exp.DataType.Type.TINYTEXT, 805 exp.DataType.Type.VARCHAR, 806 ), 807 "CHAR", 808 ) 809 SIGNED_CAST_MAPPING = dict.fromkeys( 810 ( 811 exp.DataType.Type.BIGINT, 812 exp.DataType.Type.BOOLEAN, 813 exp.DataType.Type.INT, 814 exp.DataType.Type.SMALLINT, 815 exp.DataType.Type.TINYINT, 816 exp.DataType.Type.MEDIUMINT, 817 ), 818 "SIGNED", 819 ) 820 821 # MySQL doesn't support many datatypes in cast. 822 # https://dev.mysql.com/doc/refman/8.0/en/cast-functions.html#function_cast 823 CAST_MAPPING = { 824 **CHAR_CAST_MAPPING, 825 **SIGNED_CAST_MAPPING, 826 exp.DataType.Type.UBIGINT: "UNSIGNED", 827 } 828 829 TIMESTAMP_FUNC_TYPES = { 830 exp.DataType.Type.TIMESTAMPTZ, 831 exp.DataType.Type.TIMESTAMPLTZ, 832 } 833 834 # https://dev.mysql.com/doc/refman/8.0/en/keywords.html 835 RESERVED_KEYWORDS = { 836 "accessible", 837 "add", 838 "all", 839 "alter", 840 "analyze", 841 "and", 842 "as", 843 "asc", 844 "asensitive", 845 "before", 846 "between", 847 "bigint", 848 "binary", 849 "blob", 850 "both", 851 "by", 852 "call", 853 "cascade", 854 "case", 855 "change", 856 "char", 857 "character", 858 "check", 859 "collate", 860 "column", 861 "condition", 862 "constraint", 863 "continue", 864 "convert", 865 "create", 866 "cross", 867 "cube", 868 "cume_dist", 869 "current_date", 870 "current_time", 871 "current_timestamp", 872 "current_user", 873 "cursor", 874 "database", 875 "databases", 876 "day_hour", 877 "day_microsecond", 878 "day_minute", 879 "day_second", 880 "dec", 881 "decimal", 882 "declare", 883 "default", 884 "delayed", 885 "delete", 886 "dense_rank", 887 "desc", 888 "describe", 889 "deterministic", 890 "distinct", 891 "distinctrow", 892 "div", 893 "double", 894 "drop", 895 "dual", 896 "each", 897 "else", 898 "elseif", 899 "empty", 900 "enclosed", 901 "escaped", 902 "except", 903 "exists", 904 "exit", 905 "explain", 906 "false", 907 "fetch", 908 "first_value", 909 "float", 910 "float4", 911 "float8", 912 "for", 913 "force", 914 "foreign", 915 "from", 916 "fulltext", 917 "function", 918 "generated", 919 "get", 920 "grant", 921 "group", 922 "grouping", 923 "groups", 924 "having", 925 "high_priority", 926 "hour_microsecond", 927 "hour_minute", 928 "hour_second", 929 "if", 930 "ignore", 931 "in", 932 "index", 933 "infile", 934 "inner", 935 "inout", 936 "insensitive", 937 "insert", 938 "int", 939 "int1", 940 "int2", 941 "int3", 942 "int4", 943 "int8", 944 "integer", 945 "intersect", 946 "interval", 947 "into", 948 "io_after_gtids", 949 "io_before_gtids", 950 "is", 951 "iterate", 952 "join", 953 "json_table", 954 "key", 955 "keys", 956 "kill", 957 "lag", 958 "last_value", 959 "lateral", 960 "lead", 961 "leading", 962 "leave", 963 "left", 964 "like", 965 "limit", 966 "linear", 967 "lines", 968 "load", 969 "localtime", 970 "localtimestamp", 971 "lock", 972 "long", 973 "longblob", 974 "longtext", 975 "loop", 976 "low_priority", 977 "master_bind", 978 "master_ssl_verify_server_cert", 979 "match", 980 "maxvalue", 981 "mediumblob", 982 "mediumint", 983 "mediumtext", 984 "middleint", 985 "minute_microsecond", 986 "minute_second", 987 "mod", 988 "modifies", 989 "natural", 990 "not", 991 "no_write_to_binlog", 992 "nth_value", 993 "ntile", 994 "null", 995 "numeric", 996 "of", 997 "on", 998 "optimize", 999 "optimizer_costs", 1000 "option", 1001 "optionally", 1002 "or", 1003 "order", 1004 "out", 1005 "outer", 1006 "outfile", 1007 "over", 1008 "partition", 1009 "percent_rank", 1010 "precision", 1011 "primary", 1012 "procedure", 1013 "purge", 1014 "range", 1015 "rank", 1016 "read", 1017 "reads", 1018 "read_write", 1019 "real", 1020 "recursive", 1021 "references", 1022 "regexp", 1023 "release", 1024 "rename", 1025 "repeat", 1026 "replace", 1027 "require", 1028 "resignal", 1029 "restrict", 1030 "return", 1031 "revoke", 1032 "right", 1033 "rlike", 1034 "row", 1035 "rows", 1036 "row_number", 1037 "schema", 1038 "schemas", 1039 "second_microsecond", 1040 "select", 1041 "sensitive", 1042 "separator", 1043 "set", 1044 "show", 1045 "signal", 1046 "smallint", 1047 "spatial", 1048 "specific", 1049 "sql", 1050 "sqlexception", 1051 "sqlstate", 1052 "sqlwarning", 1053 "sql_big_result", 1054 "sql_calc_found_rows", 1055 "sql_small_result", 1056 "ssl", 1057 "starting", 1058 "stored", 1059 "straight_join", 1060 "system", 1061 "table", 1062 "terminated", 1063 "then", 1064 "tinyblob", 1065 "tinyint", 1066 "tinytext", 1067 "to", 1068 "trailing", 1069 "trigger", 1070 "true", 1071 "undo", 1072 "union", 1073 "unique", 1074 "unlock", 1075 "unsigned", 1076 "update", 1077 "usage", 1078 "use", 1079 "using", 1080 "utc_date", 1081 "utc_time", 1082 "utc_timestamp", 1083 "values", 1084 "varbinary", 1085 "varchar", 1086 "varcharacter", 1087 "varying", 1088 "virtual", 1089 "when", 1090 "where", 1091 "while", 1092 "window", 1093 "with", 1094 "write", 1095 "xor", 1096 "year_month", 1097 "zerofill", 1098 } 1099 1100 def array_sql(self, expression: exp.Array) -> str: 1101 self.unsupported("Arrays are not supported by MySQL") 1102 return self.function_fallback_sql(expression) 1103 1104 def arraycontainsall_sql(self, expression: exp.ArrayContainsAll) -> str: 1105 self.unsupported("Array operations are not supported by MySQL") 1106 return self.function_fallback_sql(expression) 1107 1108 def dpipe_sql(self, expression: exp.DPipe) -> str: 1109 return self.func("CONCAT", *expression.flatten()) 1110 1111 def extract_sql(self, expression: exp.Extract) -> str: 1112 unit = expression.name 1113 if unit and unit.lower() == "epoch": 1114 return self.func("UNIX_TIMESTAMP", expression.expression) 1115 1116 return super().extract_sql(expression) 1117 1118 def datatype_sql(self, expression: exp.DataType) -> str: 1119 # https://dev.mysql.com/doc/refman/8.0/en/numeric-type-syntax.html 1120 result = super().datatype_sql(expression) 1121 if expression.this in self.UNSIGNED_TYPE_MAPPING: 1122 result = f"{result} UNSIGNED" 1123 return result 1124 1125 def jsonarraycontains_sql(self, expression: exp.JSONArrayContains) -> str: 1126 return f"{self.sql(expression, 'this')} MEMBER OF({self.sql(expression, 'expression')})" 1127 1128 def cast_sql(self, expression: exp.Cast, safe_prefix: t.Optional[str] = None) -> str: 1129 if expression.to.this in self.TIMESTAMP_FUNC_TYPES: 1130 return self.func("TIMESTAMP", expression.this) 1131 1132 to = self.CAST_MAPPING.get(expression.to.this) 1133 1134 if to: 1135 expression.to.set("this", to) 1136 return super().cast_sql(expression) 1137 1138 def show_sql(self, expression: exp.Show) -> str: 1139 this = f" {expression.name}" 1140 full = " FULL" if expression.args.get("full") else "" 1141 global_ = " GLOBAL" if expression.args.get("global") else "" 1142 1143 target = self.sql(expression, "target") 1144 target = f" {target}" if target else "" 1145 if expression.name in ("COLUMNS", "INDEX"): 1146 target = f" FROM{target}" 1147 elif expression.name == "GRANTS": 1148 target = f" FOR{target}" 1149 1150 db = self._prefixed_sql("FROM", expression, "db") 1151 1152 like = self._prefixed_sql("LIKE", expression, "like") 1153 where = self.sql(expression, "where") 1154 1155 types = self.expressions(expression, key="types") 1156 types = f" {types}" if types else types 1157 query = self._prefixed_sql("FOR QUERY", expression, "query") 1158 1159 if expression.name == "PROFILE": 1160 offset = self._prefixed_sql("OFFSET", expression, "offset") 1161 limit = self._prefixed_sql("LIMIT", expression, "limit") 1162 else: 1163 offset = "" 1164 limit = self._oldstyle_limit_sql(expression) 1165 1166 log = self._prefixed_sql("IN", expression, "log") 1167 position = self._prefixed_sql("FROM", expression, "position") 1168 1169 channel = self._prefixed_sql("FOR CHANNEL", expression, "channel") 1170 1171 if expression.name == "ENGINE": 1172 mutex_or_status = " MUTEX" if expression.args.get("mutex") else " STATUS" 1173 else: 1174 mutex_or_status = "" 1175 1176 return f"SHOW{full}{global_}{this}{target}{types}{db}{query}{log}{position}{channel}{mutex_or_status}{like}{where}{offset}{limit}" 1177 1178 def altercolumn_sql(self, expression: exp.AlterColumn) -> str: 1179 dtype = self.sql(expression, "dtype") 1180 if not dtype: 1181 return super().altercolumn_sql(expression) 1182 1183 this = self.sql(expression, "this") 1184 return f"MODIFY COLUMN {this} {dtype}" 1185 1186 def _prefixed_sql(self, prefix: str, expression: exp.Expression, arg: str) -> str: 1187 sql = self.sql(expression, arg) 1188 return f" {prefix} {sql}" if sql else "" 1189 1190 def _oldstyle_limit_sql(self, expression: exp.Show) -> str: 1191 limit = self.sql(expression, "limit") 1192 offset = self.sql(expression, "offset") 1193 if limit: 1194 limit_offset = f"{offset}, {limit}" if offset else limit 1195 return f" LIMIT {limit_offset}" 1196 return "" 1197 1198 def chr_sql(self, expression: exp.Chr) -> str: 1199 this = self.expressions(sqls=[expression.this] + expression.expressions) 1200 charset = expression.args.get("charset") 1201 using = f" USING {self.sql(charset)}" if charset else "" 1202 return f"CHAR({this}{using})" 1203 1204 def timestamptrunc_sql(self, expression: exp.TimestampTrunc) -> str: 1205 unit = expression.args.get("unit") 1206 1207 # Pick an old-enough date to avoid negative timestamp diffs 1208 start_ts = "'0000-01-01 00:00:00'" 1209 1210 # Source: https://stackoverflow.com/a/32955740 1211 timestamp_diff = build_date_delta(exp.TimestampDiff)([unit, start_ts, expression.this]) 1212 interval = exp.Interval(this=timestamp_diff, unit=unit) 1213 dateadd = build_date_delta_with_interval(exp.DateAdd)([start_ts, interval]) 1214 1215 return self.sql(dateadd)
TIME_SPECIFIERS =
{'p', 'k', 'l', 'S', 'H', 'h', 'T', 'r', 's', 'f', 'i', 'I'}
def
date_add_sql( kind: str) -> Callable[[sqlglot.generator.Generator, sqlglot.expressions.Expression], str]:
128def date_add_sql( 129 kind: str, 130) -> t.Callable[[generator.Generator, exp.Expression], str]: 131 def func(self: generator.Generator, expression: exp.Expression) -> str: 132 return self.func( 133 f"DATE_{kind}", 134 expression.this, 135 exp.Interval(this=expression.expression, unit=unit_to_var(expression)), 136 ) 137 138 return func
161class MySQL(Dialect): 162 # https://dev.mysql.com/doc/refman/8.0/en/identifiers.html 163 IDENTIFIERS_CAN_START_WITH_DIGIT = True 164 165 # We default to treating all identifiers as case-sensitive, since it matches MySQL's 166 # behavior on Linux systems. For MacOS and Windows systems, one can override this 167 # setting by specifying `dialect="mysql, normalization_strategy = lowercase"`. 168 # 169 # See also https://dev.mysql.com/doc/refman/8.2/en/identifier-case-sensitivity.html 170 NORMALIZATION_STRATEGY = NormalizationStrategy.CASE_SENSITIVE 171 172 TIME_FORMAT = "'%Y-%m-%d %T'" 173 DPIPE_IS_STRING_CONCAT = False 174 SUPPORTS_USER_DEFINED_TYPES = False 175 SUPPORTS_SEMI_ANTI_JOIN = False 176 SAFE_DIVISION = True 177 178 # https://prestodb.io/docs/current/functions/datetime.html#mysql-date-functions 179 TIME_MAPPING = { 180 "%M": "%B", 181 "%c": "%-m", 182 "%e": "%-d", 183 "%h": "%I", 184 "%i": "%M", 185 "%s": "%S", 186 "%u": "%W", 187 "%k": "%-H", 188 "%l": "%-I", 189 "%T": "%H:%M:%S", 190 "%W": "%a", 191 } 192 193 class Tokenizer(tokens.Tokenizer): 194 QUOTES = ["'", '"'] 195 COMMENTS = ["--", "#", ("/*", "*/")] 196 IDENTIFIERS = ["`"] 197 STRING_ESCAPES = ["'", '"', "\\"] 198 BIT_STRINGS = [("b'", "'"), ("B'", "'"), ("0b", "")] 199 HEX_STRINGS = [("x'", "'"), ("X'", "'"), ("0x", "")] 200 201 KEYWORDS = { 202 **tokens.Tokenizer.KEYWORDS, 203 "CHARSET": TokenType.CHARACTER_SET, 204 "FORCE": TokenType.FORCE, 205 "IGNORE": TokenType.IGNORE, 206 "KEY": TokenType.KEY, 207 "LOCK TABLES": TokenType.COMMAND, 208 "LONGBLOB": TokenType.LONGBLOB, 209 "LONGTEXT": TokenType.LONGTEXT, 210 "MEDIUMBLOB": TokenType.MEDIUMBLOB, 211 "TINYBLOB": TokenType.TINYBLOB, 212 "TINYTEXT": TokenType.TINYTEXT, 213 "MEDIUMTEXT": TokenType.MEDIUMTEXT, 214 "MEDIUMINT": TokenType.MEDIUMINT, 215 "MEMBER OF": TokenType.MEMBER_OF, 216 "SEPARATOR": TokenType.SEPARATOR, 217 "START": TokenType.BEGIN, 218 "SIGNED": TokenType.BIGINT, 219 "SIGNED INTEGER": TokenType.BIGINT, 220 "UNLOCK TABLES": TokenType.COMMAND, 221 "UNSIGNED": TokenType.UBIGINT, 222 "UNSIGNED INTEGER": TokenType.UBIGINT, 223 "YEAR": TokenType.YEAR, 224 "_ARMSCII8": TokenType.INTRODUCER, 225 "_ASCII": TokenType.INTRODUCER, 226 "_BIG5": TokenType.INTRODUCER, 227 "_BINARY": TokenType.INTRODUCER, 228 "_CP1250": TokenType.INTRODUCER, 229 "_CP1251": TokenType.INTRODUCER, 230 "_CP1256": TokenType.INTRODUCER, 231 "_CP1257": TokenType.INTRODUCER, 232 "_CP850": TokenType.INTRODUCER, 233 "_CP852": TokenType.INTRODUCER, 234 "_CP866": TokenType.INTRODUCER, 235 "_CP932": TokenType.INTRODUCER, 236 "_DEC8": TokenType.INTRODUCER, 237 "_EUCJPMS": TokenType.INTRODUCER, 238 "_EUCKR": TokenType.INTRODUCER, 239 "_GB18030": TokenType.INTRODUCER, 240 "_GB2312": TokenType.INTRODUCER, 241 "_GBK": TokenType.INTRODUCER, 242 "_GEOSTD8": TokenType.INTRODUCER, 243 "_GREEK": TokenType.INTRODUCER, 244 "_HEBREW": TokenType.INTRODUCER, 245 "_HP8": TokenType.INTRODUCER, 246 "_KEYBCS2": TokenType.INTRODUCER, 247 "_KOI8R": TokenType.INTRODUCER, 248 "_KOI8U": TokenType.INTRODUCER, 249 "_LATIN1": TokenType.INTRODUCER, 250 "_LATIN2": TokenType.INTRODUCER, 251 "_LATIN5": TokenType.INTRODUCER, 252 "_LATIN7": TokenType.INTRODUCER, 253 "_MACCE": TokenType.INTRODUCER, 254 "_MACROMAN": TokenType.INTRODUCER, 255 "_SJIS": TokenType.INTRODUCER, 256 "_SWE7": TokenType.INTRODUCER, 257 "_TIS620": TokenType.INTRODUCER, 258 "_UCS2": TokenType.INTRODUCER, 259 "_UJIS": TokenType.INTRODUCER, 260 # https://dev.mysql.com/doc/refman/8.0/en/string-literals.html 261 "_UTF8": TokenType.INTRODUCER, 262 "_UTF16": TokenType.INTRODUCER, 263 "_UTF16LE": TokenType.INTRODUCER, 264 "_UTF32": TokenType.INTRODUCER, 265 "_UTF8MB3": TokenType.INTRODUCER, 266 "_UTF8MB4": TokenType.INTRODUCER, 267 "@@": TokenType.SESSION_PARAMETER, 268 } 269 270 COMMANDS = {*tokens.Tokenizer.COMMANDS, TokenType.REPLACE} - {TokenType.SHOW} 271 272 class Parser(parser.Parser): 273 FUNC_TOKENS = { 274 *parser.Parser.FUNC_TOKENS, 275 TokenType.DATABASE, 276 TokenType.SCHEMA, 277 TokenType.VALUES, 278 } 279 280 CONJUNCTION = { 281 **parser.Parser.CONJUNCTION, 282 TokenType.DAMP: exp.And, 283 TokenType.XOR: exp.Xor, 284 } 285 286 DISJUNCTION = { 287 **parser.Parser.DISJUNCTION, 288 TokenType.DPIPE: exp.Or, 289 } 290 291 TABLE_ALIAS_TOKENS = ( 292 parser.Parser.TABLE_ALIAS_TOKENS - parser.Parser.TABLE_INDEX_HINT_TOKENS 293 ) 294 295 RANGE_PARSERS = { 296 **parser.Parser.RANGE_PARSERS, 297 TokenType.MEMBER_OF: lambda self, this: self.expression( 298 exp.JSONArrayContains, 299 this=this, 300 expression=self._parse_wrapped(self._parse_expression), 301 ), 302 } 303 304 FUNCTIONS = { 305 **parser.Parser.FUNCTIONS, 306 "DATE": lambda args: exp.TsOrDsToDate(this=seq_get(args, 0)), 307 "DATE_ADD": build_date_delta_with_interval(exp.DateAdd), 308 "DATE_FORMAT": build_formatted_time(exp.TimeToStr, "mysql"), 309 "DATE_SUB": build_date_delta_with_interval(exp.DateSub), 310 "DAY": lambda args: exp.Day(this=exp.TsOrDsToDate(this=seq_get(args, 0))), 311 "DAYOFMONTH": lambda args: exp.DayOfMonth(this=exp.TsOrDsToDate(this=seq_get(args, 0))), 312 "DAYOFWEEK": lambda args: exp.DayOfWeek(this=exp.TsOrDsToDate(this=seq_get(args, 0))), 313 "DAYOFYEAR": lambda args: exp.DayOfYear(this=exp.TsOrDsToDate(this=seq_get(args, 0))), 314 "INSTR": lambda args: exp.StrPosition(substr=seq_get(args, 1), this=seq_get(args, 0)), 315 "FROM_UNIXTIME": build_formatted_time(exp.UnixToTime, "mysql"), 316 "ISNULL": isnull_to_is_null, 317 "LOCATE": locate_to_strposition, 318 "MAKETIME": exp.TimeFromParts.from_arg_list, 319 "MONTH": lambda args: exp.Month(this=exp.TsOrDsToDate(this=seq_get(args, 0))), 320 "MONTHNAME": lambda args: exp.TimeToStr( 321 this=exp.TsOrDsToDate(this=seq_get(args, 0)), 322 format=exp.Literal.string("%B"), 323 ), 324 "STR_TO_DATE": _str_to_date, 325 "TIMESTAMPDIFF": build_date_delta(exp.TimestampDiff), 326 "TO_DAYS": lambda args: exp.paren( 327 exp.DateDiff( 328 this=exp.TsOrDsToDate(this=seq_get(args, 0)), 329 expression=exp.TsOrDsToDate(this=exp.Literal.string("0000-01-01")), 330 unit=exp.var("DAY"), 331 ) 332 + 1 333 ), 334 "WEEK": lambda args: exp.Week( 335 this=exp.TsOrDsToDate(this=seq_get(args, 0)), mode=seq_get(args, 1) 336 ), 337 "WEEKOFYEAR": lambda args: exp.WeekOfYear(this=exp.TsOrDsToDate(this=seq_get(args, 0))), 338 "YEAR": lambda args: exp.Year(this=exp.TsOrDsToDate(this=seq_get(args, 0))), 339 } 340 341 FUNCTION_PARSERS = { 342 **parser.Parser.FUNCTION_PARSERS, 343 "CHAR": lambda self: self._parse_chr(), 344 "GROUP_CONCAT": lambda self: self._parse_group_concat(), 345 # https://dev.mysql.com/doc/refman/5.7/en/miscellaneous-functions.html#function_values 346 "VALUES": lambda self: self.expression( 347 exp.Anonymous, this="VALUES", expressions=[self._parse_id_var()] 348 ), 349 } 350 351 STATEMENT_PARSERS = { 352 **parser.Parser.STATEMENT_PARSERS, 353 TokenType.SHOW: lambda self: self._parse_show(), 354 } 355 356 SHOW_PARSERS = { 357 "BINARY LOGS": _show_parser("BINARY LOGS"), 358 "MASTER LOGS": _show_parser("BINARY LOGS"), 359 "BINLOG EVENTS": _show_parser("BINLOG EVENTS"), 360 "CHARACTER SET": _show_parser("CHARACTER SET"), 361 "CHARSET": _show_parser("CHARACTER SET"), 362 "COLLATION": _show_parser("COLLATION"), 363 "FULL COLUMNS": _show_parser("COLUMNS", target="FROM", full=True), 364 "COLUMNS": _show_parser("COLUMNS", target="FROM"), 365 "CREATE DATABASE": _show_parser("CREATE DATABASE", target=True), 366 "CREATE EVENT": _show_parser("CREATE EVENT", target=True), 367 "CREATE FUNCTION": _show_parser("CREATE FUNCTION", target=True), 368 "CREATE PROCEDURE": _show_parser("CREATE PROCEDURE", target=True), 369 "CREATE TABLE": _show_parser("CREATE TABLE", target=True), 370 "CREATE TRIGGER": _show_parser("CREATE TRIGGER", target=True), 371 "CREATE VIEW": _show_parser("CREATE VIEW", target=True), 372 "DATABASES": _show_parser("DATABASES"), 373 "SCHEMAS": _show_parser("DATABASES"), 374 "ENGINE": _show_parser("ENGINE", target=True), 375 "STORAGE ENGINES": _show_parser("ENGINES"), 376 "ENGINES": _show_parser("ENGINES"), 377 "ERRORS": _show_parser("ERRORS"), 378 "EVENTS": _show_parser("EVENTS"), 379 "FUNCTION CODE": _show_parser("FUNCTION CODE", target=True), 380 "FUNCTION STATUS": _show_parser("FUNCTION STATUS"), 381 "GRANTS": _show_parser("GRANTS", target="FOR"), 382 "INDEX": _show_parser("INDEX", target="FROM"), 383 "MASTER STATUS": _show_parser("MASTER STATUS"), 384 "OPEN TABLES": _show_parser("OPEN TABLES"), 385 "PLUGINS": _show_parser("PLUGINS"), 386 "PROCEDURE CODE": _show_parser("PROCEDURE CODE", target=True), 387 "PROCEDURE STATUS": _show_parser("PROCEDURE STATUS"), 388 "PRIVILEGES": _show_parser("PRIVILEGES"), 389 "FULL PROCESSLIST": _show_parser("PROCESSLIST", full=True), 390 "PROCESSLIST": _show_parser("PROCESSLIST"), 391 "PROFILE": _show_parser("PROFILE"), 392 "PROFILES": _show_parser("PROFILES"), 393 "RELAYLOG EVENTS": _show_parser("RELAYLOG EVENTS"), 394 "REPLICAS": _show_parser("REPLICAS"), 395 "SLAVE HOSTS": _show_parser("REPLICAS"), 396 "REPLICA STATUS": _show_parser("REPLICA STATUS"), 397 "SLAVE STATUS": _show_parser("REPLICA STATUS"), 398 "GLOBAL STATUS": _show_parser("STATUS", global_=True), 399 "SESSION STATUS": _show_parser("STATUS"), 400 "STATUS": _show_parser("STATUS"), 401 "TABLE STATUS": _show_parser("TABLE STATUS"), 402 "FULL TABLES": _show_parser("TABLES", full=True), 403 "TABLES": _show_parser("TABLES"), 404 "TRIGGERS": _show_parser("TRIGGERS"), 405 "GLOBAL VARIABLES": _show_parser("VARIABLES", global_=True), 406 "SESSION VARIABLES": _show_parser("VARIABLES"), 407 "VARIABLES": _show_parser("VARIABLES"), 408 "WARNINGS": _show_parser("WARNINGS"), 409 } 410 411 PROPERTY_PARSERS = { 412 **parser.Parser.PROPERTY_PARSERS, 413 "LOCK": lambda self: self._parse_property_assignment(exp.LockProperty), 414 } 415 416 SET_PARSERS = { 417 **parser.Parser.SET_PARSERS, 418 "PERSIST": lambda self: self._parse_set_item_assignment("PERSIST"), 419 "PERSIST_ONLY": lambda self: self._parse_set_item_assignment("PERSIST_ONLY"), 420 "CHARACTER SET": lambda self: self._parse_set_item_charset("CHARACTER SET"), 421 "CHARSET": lambda self: self._parse_set_item_charset("CHARACTER SET"), 422 "NAMES": lambda self: self._parse_set_item_names(), 423 } 424 425 CONSTRAINT_PARSERS = { 426 **parser.Parser.CONSTRAINT_PARSERS, 427 "FULLTEXT": lambda self: self._parse_index_constraint(kind="FULLTEXT"), 428 "INDEX": lambda self: self._parse_index_constraint(), 429 "KEY": lambda self: self._parse_index_constraint(), 430 "SPATIAL": lambda self: self._parse_index_constraint(kind="SPATIAL"), 431 } 432 433 ALTER_PARSERS = { 434 **parser.Parser.ALTER_PARSERS, 435 "MODIFY": lambda self: self._parse_alter_table_alter(), 436 } 437 438 SCHEMA_UNNAMED_CONSTRAINTS = { 439 *parser.Parser.SCHEMA_UNNAMED_CONSTRAINTS, 440 "FULLTEXT", 441 "INDEX", 442 "KEY", 443 "SPATIAL", 444 } 445 446 PROFILE_TYPES: parser.OPTIONS_TYPE = { 447 **dict.fromkeys(("ALL", "CPU", "IPC", "MEMORY", "SOURCE", "SWAPS"), tuple()), 448 "BLOCK": ("IO",), 449 "CONTEXT": ("SWITCHES",), 450 "PAGE": ("FAULTS",), 451 } 452 453 TYPE_TOKENS = { 454 *parser.Parser.TYPE_TOKENS, 455 TokenType.SET, 456 } 457 458 ENUM_TYPE_TOKENS = { 459 *parser.Parser.ENUM_TYPE_TOKENS, 460 TokenType.SET, 461 } 462 463 LOG_DEFAULTS_TO_LN = True 464 STRING_ALIASES = True 465 VALUES_FOLLOWED_BY_PAREN = False 466 SUPPORTS_PARTITION_SELECTION = True 467 468 def _parse_primary_key_part(self) -> t.Optional[exp.Expression]: 469 this = self._parse_id_var() 470 if not self._match(TokenType.L_PAREN): 471 return this 472 473 expression = self._parse_number() 474 self._match_r_paren() 475 return self.expression(exp.ColumnPrefix, this=this, expression=expression) 476 477 def _parse_index_constraint( 478 self, kind: t.Optional[str] = None 479 ) -> exp.IndexColumnConstraint: 480 if kind: 481 self._match_texts(("INDEX", "KEY")) 482 483 this = self._parse_id_var(any_token=False) 484 index_type = self._match(TokenType.USING) and self._advance_any() and self._prev.text 485 expressions = self._parse_wrapped_csv(self._parse_ordered) 486 487 options = [] 488 while True: 489 if self._match_text_seq("KEY_BLOCK_SIZE"): 490 self._match(TokenType.EQ) 491 opt = exp.IndexConstraintOption(key_block_size=self._parse_number()) 492 elif self._match(TokenType.USING): 493 opt = exp.IndexConstraintOption(using=self._advance_any() and self._prev.text) 494 elif self._match_text_seq("WITH", "PARSER"): 495 opt = exp.IndexConstraintOption(parser=self._parse_var(any_token=True)) 496 elif self._match(TokenType.COMMENT): 497 opt = exp.IndexConstraintOption(comment=self._parse_string()) 498 elif self._match_text_seq("VISIBLE"): 499 opt = exp.IndexConstraintOption(visible=True) 500 elif self._match_text_seq("INVISIBLE"): 501 opt = exp.IndexConstraintOption(visible=False) 502 elif self._match_text_seq("ENGINE_ATTRIBUTE"): 503 self._match(TokenType.EQ) 504 opt = exp.IndexConstraintOption(engine_attr=self._parse_string()) 505 elif self._match_text_seq("SECONDARY_ENGINE_ATTRIBUTE"): 506 self._match(TokenType.EQ) 507 opt = exp.IndexConstraintOption(secondary_engine_attr=self._parse_string()) 508 else: 509 opt = None 510 511 if not opt: 512 break 513 514 options.append(opt) 515 516 return self.expression( 517 exp.IndexColumnConstraint, 518 this=this, 519 expressions=expressions, 520 kind=kind, 521 index_type=index_type, 522 options=options, 523 ) 524 525 def _parse_show_mysql( 526 self, 527 this: str, 528 target: bool | str = False, 529 full: t.Optional[bool] = None, 530 global_: t.Optional[bool] = None, 531 ) -> exp.Show: 532 if target: 533 if isinstance(target, str): 534 self._match_text_seq(target) 535 target_id = self._parse_id_var() 536 else: 537 target_id = None 538 539 log = self._parse_string() if self._match_text_seq("IN") else None 540 541 if this in ("BINLOG EVENTS", "RELAYLOG EVENTS"): 542 position = self._parse_number() if self._match_text_seq("FROM") else None 543 db = None 544 else: 545 position = None 546 db = None 547 548 if self._match(TokenType.FROM): 549 db = self._parse_id_var() 550 elif self._match(TokenType.DOT): 551 db = target_id 552 target_id = self._parse_id_var() 553 554 channel = self._parse_id_var() if self._match_text_seq("FOR", "CHANNEL") else None 555 556 like = self._parse_string() if self._match_text_seq("LIKE") else None 557 where = self._parse_where() 558 559 if this == "PROFILE": 560 types = self._parse_csv(lambda: self._parse_var_from_options(self.PROFILE_TYPES)) 561 query = self._parse_number() if self._match_text_seq("FOR", "QUERY") else None 562 offset = self._parse_number() if self._match_text_seq("OFFSET") else None 563 limit = self._parse_number() if self._match_text_seq("LIMIT") else None 564 else: 565 types, query = None, None 566 offset, limit = self._parse_oldstyle_limit() 567 568 mutex = True if self._match_text_seq("MUTEX") else None 569 mutex = False if self._match_text_seq("STATUS") else mutex 570 571 return self.expression( 572 exp.Show, 573 this=this, 574 target=target_id, 575 full=full, 576 log=log, 577 position=position, 578 db=db, 579 channel=channel, 580 like=like, 581 where=where, 582 types=types, 583 query=query, 584 offset=offset, 585 limit=limit, 586 mutex=mutex, 587 **{"global": global_}, # type: ignore 588 ) 589 590 def _parse_oldstyle_limit( 591 self, 592 ) -> t.Tuple[t.Optional[exp.Expression], t.Optional[exp.Expression]]: 593 limit = None 594 offset = None 595 if self._match_text_seq("LIMIT"): 596 parts = self._parse_csv(self._parse_number) 597 if len(parts) == 1: 598 limit = parts[0] 599 elif len(parts) == 2: 600 limit = parts[1] 601 offset = parts[0] 602 603 return offset, limit 604 605 def _parse_set_item_charset(self, kind: str) -> exp.Expression: 606 this = self._parse_string() or self._parse_unquoted_field() 607 return self.expression(exp.SetItem, this=this, kind=kind) 608 609 def _parse_set_item_names(self) -> exp.Expression: 610 charset = self._parse_string() or self._parse_unquoted_field() 611 if self._match_text_seq("COLLATE"): 612 collate = self._parse_string() or self._parse_unquoted_field() 613 else: 614 collate = None 615 616 return self.expression(exp.SetItem, this=charset, collate=collate, kind="NAMES") 617 618 def _parse_type( 619 self, parse_interval: bool = True, fallback_to_identifier: bool = False 620 ) -> t.Optional[exp.Expression]: 621 # mysql binary is special and can work anywhere, even in order by operations 622 # it operates like a no paren func 623 if self._match(TokenType.BINARY, advance=False): 624 data_type = self._parse_types(check_func=True, allow_identifiers=False) 625 626 if isinstance(data_type, exp.DataType): 627 return self.expression(exp.Cast, this=self._parse_column(), to=data_type) 628 629 return super()._parse_type( 630 parse_interval=parse_interval, fallback_to_identifier=fallback_to_identifier 631 ) 632 633 def _parse_chr(self) -> t.Optional[exp.Expression]: 634 expressions = self._parse_csv(self._parse_assignment) 635 kwargs: t.Dict[str, t.Any] = {"this": seq_get(expressions, 0)} 636 637 if len(expressions) > 1: 638 kwargs["expressions"] = expressions[1:] 639 640 if self._match(TokenType.USING): 641 kwargs["charset"] = self._parse_var() 642 643 return self.expression(exp.Chr, **kwargs) 644 645 def _parse_group_concat(self) -> t.Optional[exp.Expression]: 646 def concat_exprs( 647 node: t.Optional[exp.Expression], exprs: t.List[exp.Expression] 648 ) -> exp.Expression: 649 if isinstance(node, exp.Distinct) and len(node.expressions) > 1: 650 concat_exprs = [ 651 self.expression(exp.Concat, expressions=node.expressions, safe=True) 652 ] 653 node.set("expressions", concat_exprs) 654 return node 655 if len(exprs) == 1: 656 return exprs[0] 657 return self.expression(exp.Concat, expressions=args, safe=True) 658 659 args = self._parse_csv(self._parse_lambda) 660 661 if args: 662 order = args[-1] if isinstance(args[-1], exp.Order) else None 663 664 if order: 665 # Order By is the last (or only) expression in the list and has consumed the 'expr' before it, 666 # remove 'expr' from exp.Order and add it back to args 667 args[-1] = order.this 668 order.set("this", concat_exprs(order.this, args)) 669 670 this = order or concat_exprs(args[0], args) 671 else: 672 this = None 673 674 separator = self._parse_field() if self._match(TokenType.SEPARATOR) else None 675 676 return self.expression(exp.GroupConcat, this=this, separator=separator) 677 678 class Generator(generator.Generator): 679 INTERVAL_ALLOWS_PLURAL_FORM = False 680 LOCKING_READS_SUPPORTED = True 681 NULL_ORDERING_SUPPORTED = None 682 JOIN_HINTS = False 683 TABLE_HINTS = True 684 DUPLICATE_KEY_UPDATE_WITH_SET = False 685 QUERY_HINT_SEP = " " 686 VALUES_AS_TABLE = False 687 NVL2_SUPPORTED = False 688 LAST_DAY_SUPPORTS_DATE_PART = False 689 JSON_TYPE_REQUIRED_FOR_EXTRACTION = True 690 JSON_PATH_BRACKETED_KEY_SUPPORTED = False 691 JSON_KEY_VALUE_PAIR_SEP = "," 692 SUPPORTS_TO_NUMBER = False 693 PARSE_JSON_NAME = None 694 PAD_FILL_PATTERN_IS_REQUIRED = True 695 WRAP_DERIVED_VALUES = False 696 697 TRANSFORMS = { 698 **generator.Generator.TRANSFORMS, 699 exp.ArrayAgg: rename_func("GROUP_CONCAT"), 700 exp.CurrentDate: no_paren_current_date_sql, 701 exp.DateDiff: _remove_ts_or_ds_to_date( 702 lambda self, e: self.func("DATEDIFF", e.this, e.expression), ("this", "expression") 703 ), 704 exp.DateAdd: _remove_ts_or_ds_to_date(date_add_sql("ADD")), 705 exp.DateStrToDate: datestrtodate_sql, 706 exp.DateSub: _remove_ts_or_ds_to_date(date_add_sql("SUB")), 707 exp.DateTrunc: _date_trunc_sql, 708 exp.Day: _remove_ts_or_ds_to_date(), 709 exp.DayOfMonth: _remove_ts_or_ds_to_date(rename_func("DAYOFMONTH")), 710 exp.DayOfWeek: _remove_ts_or_ds_to_date(rename_func("DAYOFWEEK")), 711 exp.DayOfYear: _remove_ts_or_ds_to_date(rename_func("DAYOFYEAR")), 712 exp.GroupConcat: lambda self, 713 e: f"""GROUP_CONCAT({self.sql(e, "this")} SEPARATOR {self.sql(e, "separator") or "','"})""", 714 exp.ILike: no_ilike_sql, 715 exp.JSONExtractScalar: arrow_json_extract_sql, 716 exp.Max: max_or_greatest, 717 exp.Min: min_or_least, 718 exp.Month: _remove_ts_or_ds_to_date(), 719 exp.NullSafeEQ: lambda self, e: self.binary(e, "<=>"), 720 exp.NullSafeNEQ: lambda self, e: f"NOT {self.binary(e, '<=>')}", 721 exp.Pivot: no_pivot_sql, 722 exp.Select: transforms.preprocess( 723 [ 724 transforms.eliminate_distinct_on, 725 transforms.eliminate_semi_and_anti_joins, 726 transforms.eliminate_qualify, 727 transforms.eliminate_full_outer_join, 728 ] 729 ), 730 exp.StrPosition: strposition_to_locate_sql, 731 exp.StrToDate: _str_to_date_sql, 732 exp.StrToTime: _str_to_date_sql, 733 exp.Stuff: rename_func("INSERT"), 734 exp.TableSample: no_tablesample_sql, 735 exp.TimeFromParts: rename_func("MAKETIME"), 736 exp.TimestampAdd: date_add_interval_sql("DATE", "ADD"), 737 exp.TimestampDiff: lambda self, e: self.func( 738 "TIMESTAMPDIFF", unit_to_var(e), e.expression, e.this 739 ), 740 exp.TimestampSub: date_add_interval_sql("DATE", "SUB"), 741 exp.TimeStrToUnix: rename_func("UNIX_TIMESTAMP"), 742 exp.TimeStrToTime: lambda self, e: self.sql( 743 exp.cast(e.this, exp.DataType.Type.DATETIME, copy=True) 744 ), 745 exp.TimeToStr: _remove_ts_or_ds_to_date( 746 lambda self, e: self.func("DATE_FORMAT", e.this, self.format_time(e)) 747 ), 748 exp.Trim: _trim_sql, 749 exp.TryCast: no_trycast_sql, 750 exp.TsOrDsAdd: date_add_sql("ADD"), 751 exp.TsOrDsDiff: lambda self, e: self.func("DATEDIFF", e.this, e.expression), 752 exp.TsOrDsToDate: _ts_or_ds_to_date_sql, 753 exp.UnixToTime: _unix_to_time_sql, 754 exp.Week: _remove_ts_or_ds_to_date(), 755 exp.WeekOfYear: _remove_ts_or_ds_to_date(rename_func("WEEKOFYEAR")), 756 exp.Year: _remove_ts_or_ds_to_date(), 757 } 758 759 UNSIGNED_TYPE_MAPPING = { 760 exp.DataType.Type.UBIGINT: "BIGINT", 761 exp.DataType.Type.UINT: "INT", 762 exp.DataType.Type.UMEDIUMINT: "MEDIUMINT", 763 exp.DataType.Type.USMALLINT: "SMALLINT", 764 exp.DataType.Type.UTINYINT: "TINYINT", 765 exp.DataType.Type.UDECIMAL: "DECIMAL", 766 } 767 768 TIMESTAMP_TYPE_MAPPING = { 769 exp.DataType.Type.TIMESTAMP: "DATETIME", 770 exp.DataType.Type.TIMESTAMPTZ: "TIMESTAMP", 771 exp.DataType.Type.TIMESTAMPLTZ: "TIMESTAMP", 772 } 773 774 TYPE_MAPPING = { 775 **generator.Generator.TYPE_MAPPING, 776 **UNSIGNED_TYPE_MAPPING, 777 **TIMESTAMP_TYPE_MAPPING, 778 } 779 780 TYPE_MAPPING.pop(exp.DataType.Type.MEDIUMTEXT) 781 TYPE_MAPPING.pop(exp.DataType.Type.LONGTEXT) 782 TYPE_MAPPING.pop(exp.DataType.Type.TINYTEXT) 783 TYPE_MAPPING.pop(exp.DataType.Type.MEDIUMBLOB) 784 TYPE_MAPPING.pop(exp.DataType.Type.LONGBLOB) 785 TYPE_MAPPING.pop(exp.DataType.Type.TINYBLOB) 786 787 PROPERTIES_LOCATION = { 788 **generator.Generator.PROPERTIES_LOCATION, 789 exp.TransientProperty: exp.Properties.Location.UNSUPPORTED, 790 exp.VolatileProperty: exp.Properties.Location.UNSUPPORTED, 791 } 792 793 LIMIT_FETCH = "LIMIT" 794 795 LIMIT_ONLY_LITERALS = True 796 797 CHAR_CAST_MAPPING = dict.fromkeys( 798 ( 799 exp.DataType.Type.LONGTEXT, 800 exp.DataType.Type.LONGBLOB, 801 exp.DataType.Type.MEDIUMBLOB, 802 exp.DataType.Type.MEDIUMTEXT, 803 exp.DataType.Type.TEXT, 804 exp.DataType.Type.TINYBLOB, 805 exp.DataType.Type.TINYTEXT, 806 exp.DataType.Type.VARCHAR, 807 ), 808 "CHAR", 809 ) 810 SIGNED_CAST_MAPPING = dict.fromkeys( 811 ( 812 exp.DataType.Type.BIGINT, 813 exp.DataType.Type.BOOLEAN, 814 exp.DataType.Type.INT, 815 exp.DataType.Type.SMALLINT, 816 exp.DataType.Type.TINYINT, 817 exp.DataType.Type.MEDIUMINT, 818 ), 819 "SIGNED", 820 ) 821 822 # MySQL doesn't support many datatypes in cast. 823 # https://dev.mysql.com/doc/refman/8.0/en/cast-functions.html#function_cast 824 CAST_MAPPING = { 825 **CHAR_CAST_MAPPING, 826 **SIGNED_CAST_MAPPING, 827 exp.DataType.Type.UBIGINT: "UNSIGNED", 828 } 829 830 TIMESTAMP_FUNC_TYPES = { 831 exp.DataType.Type.TIMESTAMPTZ, 832 exp.DataType.Type.TIMESTAMPLTZ, 833 } 834 835 # https://dev.mysql.com/doc/refman/8.0/en/keywords.html 836 RESERVED_KEYWORDS = { 837 "accessible", 838 "add", 839 "all", 840 "alter", 841 "analyze", 842 "and", 843 "as", 844 "asc", 845 "asensitive", 846 "before", 847 "between", 848 "bigint", 849 "binary", 850 "blob", 851 "both", 852 "by", 853 "call", 854 "cascade", 855 "case", 856 "change", 857 "char", 858 "character", 859 "check", 860 "collate", 861 "column", 862 "condition", 863 "constraint", 864 "continue", 865 "convert", 866 "create", 867 "cross", 868 "cube", 869 "cume_dist", 870 "current_date", 871 "current_time", 872 "current_timestamp", 873 "current_user", 874 "cursor", 875 "database", 876 "databases", 877 "day_hour", 878 "day_microsecond", 879 "day_minute", 880 "day_second", 881 "dec", 882 "decimal", 883 "declare", 884 "default", 885 "delayed", 886 "delete", 887 "dense_rank", 888 "desc", 889 "describe", 890 "deterministic", 891 "distinct", 892 "distinctrow", 893 "div", 894 "double", 895 "drop", 896 "dual", 897 "each", 898 "else", 899 "elseif", 900 "empty", 901 "enclosed", 902 "escaped", 903 "except", 904 "exists", 905 "exit", 906 "explain", 907 "false", 908 "fetch", 909 "first_value", 910 "float", 911 "float4", 912 "float8", 913 "for", 914 "force", 915 "foreign", 916 "from", 917 "fulltext", 918 "function", 919 "generated", 920 "get", 921 "grant", 922 "group", 923 "grouping", 924 "groups", 925 "having", 926 "high_priority", 927 "hour_microsecond", 928 "hour_minute", 929 "hour_second", 930 "if", 931 "ignore", 932 "in", 933 "index", 934 "infile", 935 "inner", 936 "inout", 937 "insensitive", 938 "insert", 939 "int", 940 "int1", 941 "int2", 942 "int3", 943 "int4", 944 "int8", 945 "integer", 946 "intersect", 947 "interval", 948 "into", 949 "io_after_gtids", 950 "io_before_gtids", 951 "is", 952 "iterate", 953 "join", 954 "json_table", 955 "key", 956 "keys", 957 "kill", 958 "lag", 959 "last_value", 960 "lateral", 961 "lead", 962 "leading", 963 "leave", 964 "left", 965 "like", 966 "limit", 967 "linear", 968 "lines", 969 "load", 970 "localtime", 971 "localtimestamp", 972 "lock", 973 "long", 974 "longblob", 975 "longtext", 976 "loop", 977 "low_priority", 978 "master_bind", 979 "master_ssl_verify_server_cert", 980 "match", 981 "maxvalue", 982 "mediumblob", 983 "mediumint", 984 "mediumtext", 985 "middleint", 986 "minute_microsecond", 987 "minute_second", 988 "mod", 989 "modifies", 990 "natural", 991 "not", 992 "no_write_to_binlog", 993 "nth_value", 994 "ntile", 995 "null", 996 "numeric", 997 "of", 998 "on", 999 "optimize", 1000 "optimizer_costs", 1001 "option", 1002 "optionally", 1003 "or", 1004 "order", 1005 "out", 1006 "outer", 1007 "outfile", 1008 "over", 1009 "partition", 1010 "percent_rank", 1011 "precision", 1012 "primary", 1013 "procedure", 1014 "purge", 1015 "range", 1016 "rank", 1017 "read", 1018 "reads", 1019 "read_write", 1020 "real", 1021 "recursive", 1022 "references", 1023 "regexp", 1024 "release", 1025 "rename", 1026 "repeat", 1027 "replace", 1028 "require", 1029 "resignal", 1030 "restrict", 1031 "return", 1032 "revoke", 1033 "right", 1034 "rlike", 1035 "row", 1036 "rows", 1037 "row_number", 1038 "schema", 1039 "schemas", 1040 "second_microsecond", 1041 "select", 1042 "sensitive", 1043 "separator", 1044 "set", 1045 "show", 1046 "signal", 1047 "smallint", 1048 "spatial", 1049 "specific", 1050 "sql", 1051 "sqlexception", 1052 "sqlstate", 1053 "sqlwarning", 1054 "sql_big_result", 1055 "sql_calc_found_rows", 1056 "sql_small_result", 1057 "ssl", 1058 "starting", 1059 "stored", 1060 "straight_join", 1061 "system", 1062 "table", 1063 "terminated", 1064 "then", 1065 "tinyblob", 1066 "tinyint", 1067 "tinytext", 1068 "to", 1069 "trailing", 1070 "trigger", 1071 "true", 1072 "undo", 1073 "union", 1074 "unique", 1075 "unlock", 1076 "unsigned", 1077 "update", 1078 "usage", 1079 "use", 1080 "using", 1081 "utc_date", 1082 "utc_time", 1083 "utc_timestamp", 1084 "values", 1085 "varbinary", 1086 "varchar", 1087 "varcharacter", 1088 "varying", 1089 "virtual", 1090 "when", 1091 "where", 1092 "while", 1093 "window", 1094 "with", 1095 "write", 1096 "xor", 1097 "year_month", 1098 "zerofill", 1099 } 1100 1101 def array_sql(self, expression: exp.Array) -> str: 1102 self.unsupported("Arrays are not supported by MySQL") 1103 return self.function_fallback_sql(expression) 1104 1105 def arraycontainsall_sql(self, expression: exp.ArrayContainsAll) -> str: 1106 self.unsupported("Array operations are not supported by MySQL") 1107 return self.function_fallback_sql(expression) 1108 1109 def dpipe_sql(self, expression: exp.DPipe) -> str: 1110 return self.func("CONCAT", *expression.flatten()) 1111 1112 def extract_sql(self, expression: exp.Extract) -> str: 1113 unit = expression.name 1114 if unit and unit.lower() == "epoch": 1115 return self.func("UNIX_TIMESTAMP", expression.expression) 1116 1117 return super().extract_sql(expression) 1118 1119 def datatype_sql(self, expression: exp.DataType) -> str: 1120 # https://dev.mysql.com/doc/refman/8.0/en/numeric-type-syntax.html 1121 result = super().datatype_sql(expression) 1122 if expression.this in self.UNSIGNED_TYPE_MAPPING: 1123 result = f"{result} UNSIGNED" 1124 return result 1125 1126 def jsonarraycontains_sql(self, expression: exp.JSONArrayContains) -> str: 1127 return f"{self.sql(expression, 'this')} MEMBER OF({self.sql(expression, 'expression')})" 1128 1129 def cast_sql(self, expression: exp.Cast, safe_prefix: t.Optional[str] = None) -> str: 1130 if expression.to.this in self.TIMESTAMP_FUNC_TYPES: 1131 return self.func("TIMESTAMP", expression.this) 1132 1133 to = self.CAST_MAPPING.get(expression.to.this) 1134 1135 if to: 1136 expression.to.set("this", to) 1137 return super().cast_sql(expression) 1138 1139 def show_sql(self, expression: exp.Show) -> str: 1140 this = f" {expression.name}" 1141 full = " FULL" if expression.args.get("full") else "" 1142 global_ = " GLOBAL" if expression.args.get("global") else "" 1143 1144 target = self.sql(expression, "target") 1145 target = f" {target}" if target else "" 1146 if expression.name in ("COLUMNS", "INDEX"): 1147 target = f" FROM{target}" 1148 elif expression.name == "GRANTS": 1149 target = f" FOR{target}" 1150 1151 db = self._prefixed_sql("FROM", expression, "db") 1152 1153 like = self._prefixed_sql("LIKE", expression, "like") 1154 where = self.sql(expression, "where") 1155 1156 types = self.expressions(expression, key="types") 1157 types = f" {types}" if types else types 1158 query = self._prefixed_sql("FOR QUERY", expression, "query") 1159 1160 if expression.name == "PROFILE": 1161 offset = self._prefixed_sql("OFFSET", expression, "offset") 1162 limit = self._prefixed_sql("LIMIT", expression, "limit") 1163 else: 1164 offset = "" 1165 limit = self._oldstyle_limit_sql(expression) 1166 1167 log = self._prefixed_sql("IN", expression, "log") 1168 position = self._prefixed_sql("FROM", expression, "position") 1169 1170 channel = self._prefixed_sql("FOR CHANNEL", expression, "channel") 1171 1172 if expression.name == "ENGINE": 1173 mutex_or_status = " MUTEX" if expression.args.get("mutex") else " STATUS" 1174 else: 1175 mutex_or_status = "" 1176 1177 return f"SHOW{full}{global_}{this}{target}{types}{db}{query}{log}{position}{channel}{mutex_or_status}{like}{where}{offset}{limit}" 1178 1179 def altercolumn_sql(self, expression: exp.AlterColumn) -> str: 1180 dtype = self.sql(expression, "dtype") 1181 if not dtype: 1182 return super().altercolumn_sql(expression) 1183 1184 this = self.sql(expression, "this") 1185 return f"MODIFY COLUMN {this} {dtype}" 1186 1187 def _prefixed_sql(self, prefix: str, expression: exp.Expression, arg: str) -> str: 1188 sql = self.sql(expression, arg) 1189 return f" {prefix} {sql}" if sql else "" 1190 1191 def _oldstyle_limit_sql(self, expression: exp.Show) -> str: 1192 limit = self.sql(expression, "limit") 1193 offset = self.sql(expression, "offset") 1194 if limit: 1195 limit_offset = f"{offset}, {limit}" if offset else limit 1196 return f" LIMIT {limit_offset}" 1197 return "" 1198 1199 def chr_sql(self, expression: exp.Chr) -> str: 1200 this = self.expressions(sqls=[expression.this] + expression.expressions) 1201 charset = expression.args.get("charset") 1202 using = f" USING {self.sql(charset)}" if charset else "" 1203 return f"CHAR({this}{using})" 1204 1205 def timestamptrunc_sql(self, expression: exp.TimestampTrunc) -> str: 1206 unit = expression.args.get("unit") 1207 1208 # Pick an old-enough date to avoid negative timestamp diffs 1209 start_ts = "'0000-01-01 00:00:00'" 1210 1211 # Source: https://stackoverflow.com/a/32955740 1212 timestamp_diff = build_date_delta(exp.TimestampDiff)([unit, start_ts, expression.this]) 1213 interval = exp.Interval(this=timestamp_diff, unit=unit) 1214 dateadd = build_date_delta_with_interval(exp.DateAdd)([start_ts, interval]) 1215 1216 return self.sql(dateadd)
NORMALIZATION_STRATEGY =
<NormalizationStrategy.CASE_SENSITIVE: 'CASE_SENSITIVE'>
Specifies the strategy according to which identifiers should be normalized.
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.
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'>
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}}}
ESCAPED_SEQUENCES: Dict[str, str] =
{'\x07': '\\a', '\x08': '\\b', '\x0c': '\\f', '\n': '\\n', '\r': '\\r', '\t': '\\t', '\x0b': '\\v', '\\': '\\\\'}
Inherited Members
- sqlglot.dialects.dialect.Dialect
- Dialect
- INDEX_OFFSET
- WEEK_OFFSET
- UNNEST_COLUMN_ONLY
- ALIAS_POST_TABLESAMPLE
- TABLESAMPLE_SIZE_IS_PERCENT
- STRICT_STRING_CONCAT
- COPY_PARAMS_ARE_CSV
- NORMALIZE_FUNCTIONS
- LOG_BASE_FIRST
- NULL_ORDERING
- TYPED_DIVISION
- CONCAT_COALESCE
- HEX_LOWERCASE
- DATE_FORMAT
- DATEINT_FORMAT
- FORMAT_MAPPING
- PSEUDOCOLUMNS
- PREFER_CTE_ALIAS_COLUMN
- FORCE_EARLY_ALIAS_REF_EXPANSION
- EXPAND_ALIAS_REFS_EARLY_ONLY_IN_GROUP_BY
- SUPPORTS_ORDER_BY_ALL
- DATE_PART_MAPPING
- TYPE_TO_EXPRESSIONS
- ANNOTATORS
- get_or_raise
- format_time
- settings
- normalize_identifier
- case_sensitive
- can_identify
- quote_identifier
- to_json_path
- parse
- parse_into
- generate
- transpile
- tokenize
- tokenizer
- jsonpath_tokenizer
- parser
- generator
193 class Tokenizer(tokens.Tokenizer): 194 QUOTES = ["'", '"'] 195 COMMENTS = ["--", "#", ("/*", "*/")] 196 IDENTIFIERS = ["`"] 197 STRING_ESCAPES = ["'", '"', "\\"] 198 BIT_STRINGS = [("b'", "'"), ("B'", "'"), ("0b", "")] 199 HEX_STRINGS = [("x'", "'"), ("X'", "'"), ("0x", "")] 200 201 KEYWORDS = { 202 **tokens.Tokenizer.KEYWORDS, 203 "CHARSET": TokenType.CHARACTER_SET, 204 "FORCE": TokenType.FORCE, 205 "IGNORE": TokenType.IGNORE, 206 "KEY": TokenType.KEY, 207 "LOCK TABLES": TokenType.COMMAND, 208 "LONGBLOB": TokenType.LONGBLOB, 209 "LONGTEXT": TokenType.LONGTEXT, 210 "MEDIUMBLOB": TokenType.MEDIUMBLOB, 211 "TINYBLOB": TokenType.TINYBLOB, 212 "TINYTEXT": TokenType.TINYTEXT, 213 "MEDIUMTEXT": TokenType.MEDIUMTEXT, 214 "MEDIUMINT": TokenType.MEDIUMINT, 215 "MEMBER OF": TokenType.MEMBER_OF, 216 "SEPARATOR": TokenType.SEPARATOR, 217 "START": TokenType.BEGIN, 218 "SIGNED": TokenType.BIGINT, 219 "SIGNED INTEGER": TokenType.BIGINT, 220 "UNLOCK TABLES": TokenType.COMMAND, 221 "UNSIGNED": TokenType.UBIGINT, 222 "UNSIGNED INTEGER": TokenType.UBIGINT, 223 "YEAR": TokenType.YEAR, 224 "_ARMSCII8": TokenType.INTRODUCER, 225 "_ASCII": TokenType.INTRODUCER, 226 "_BIG5": TokenType.INTRODUCER, 227 "_BINARY": TokenType.INTRODUCER, 228 "_CP1250": TokenType.INTRODUCER, 229 "_CP1251": TokenType.INTRODUCER, 230 "_CP1256": TokenType.INTRODUCER, 231 "_CP1257": TokenType.INTRODUCER, 232 "_CP850": TokenType.INTRODUCER, 233 "_CP852": TokenType.INTRODUCER, 234 "_CP866": TokenType.INTRODUCER, 235 "_CP932": TokenType.INTRODUCER, 236 "_DEC8": TokenType.INTRODUCER, 237 "_EUCJPMS": TokenType.INTRODUCER, 238 "_EUCKR": TokenType.INTRODUCER, 239 "_GB18030": TokenType.INTRODUCER, 240 "_GB2312": TokenType.INTRODUCER, 241 "_GBK": TokenType.INTRODUCER, 242 "_GEOSTD8": TokenType.INTRODUCER, 243 "_GREEK": TokenType.INTRODUCER, 244 "_HEBREW": TokenType.INTRODUCER, 245 "_HP8": TokenType.INTRODUCER, 246 "_KEYBCS2": TokenType.INTRODUCER, 247 "_KOI8R": TokenType.INTRODUCER, 248 "_KOI8U": TokenType.INTRODUCER, 249 "_LATIN1": TokenType.INTRODUCER, 250 "_LATIN2": TokenType.INTRODUCER, 251 "_LATIN5": TokenType.INTRODUCER, 252 "_LATIN7": TokenType.INTRODUCER, 253 "_MACCE": TokenType.INTRODUCER, 254 "_MACROMAN": TokenType.INTRODUCER, 255 "_SJIS": TokenType.INTRODUCER, 256 "_SWE7": TokenType.INTRODUCER, 257 "_TIS620": TokenType.INTRODUCER, 258 "_UCS2": TokenType.INTRODUCER, 259 "_UJIS": TokenType.INTRODUCER, 260 # https://dev.mysql.com/doc/refman/8.0/en/string-literals.html 261 "_UTF8": TokenType.INTRODUCER, 262 "_UTF16": TokenType.INTRODUCER, 263 "_UTF16LE": TokenType.INTRODUCER, 264 "_UTF32": TokenType.INTRODUCER, 265 "_UTF8MB3": TokenType.INTRODUCER, 266 "_UTF8MB4": TokenType.INTRODUCER, 267 "@@": TokenType.SESSION_PARAMETER, 268 } 269 270 COMMANDS = {*tokens.Tokenizer.COMMANDS, TokenType.REPLACE} - {TokenType.SHOW}
KEYWORDS =
{'{%': <TokenType.BLOCK_START: 'BLOCK_START'>, '{%+': <TokenType.BLOCK_START: 'BLOCK_START'>, '{%-': <TokenType.BLOCK_START: 'BLOCK_START'>, '%}': <TokenType.BLOCK_END: 'BLOCK_END'>, '+%}': <TokenType.BLOCK_END: 'BLOCK_END'>, '-%}': <TokenType.BLOCK_END: 'BLOCK_END'>, '{{+': <TokenType.BLOCK_START: 'BLOCK_START'>, '{{-': <TokenType.BLOCK_START: 'BLOCK_START'>, '+}}': <TokenType.BLOCK_END: 'BLOCK_END'>, '-}}': <TokenType.BLOCK_END: 'BLOCK_END'>, '/*+': <TokenType.HINT: 'HINT'>, '==': <TokenType.EQ: 'EQ'>, '::': <TokenType.DCOLON: 'DCOLON'>, '||': <TokenType.DPIPE: 'DPIPE'>, '>=': <TokenType.GTE: 'GTE'>, '<=': <TokenType.LTE: 'LTE'>, '<>': <TokenType.NEQ: 'NEQ'>, '!=': <TokenType.NEQ: 'NEQ'>, ':=': <TokenType.COLON_EQ: 'COLON_EQ'>, '<=>': <TokenType.NULLSAFE_EQ: 'NULLSAFE_EQ'>, '->': <TokenType.ARROW: 'ARROW'>, '->>': <TokenType.DARROW: 'DARROW'>, '=>': <TokenType.FARROW: 'FARROW'>, '#>': <TokenType.HASH_ARROW: 'HASH_ARROW'>, '#>>': <TokenType.DHASH_ARROW: 'DHASH_ARROW'>, '<->': <TokenType.LR_ARROW: 'LR_ARROW'>, '&&': <TokenType.DAMP: 'DAMP'>, '??': <TokenType.DQMARK: 'DQMARK'>, 'ALL': <TokenType.ALL: 'ALL'>, 'ALWAYS': <TokenType.ALWAYS: 'ALWAYS'>, 'AND': <TokenType.AND: 'AND'>, 'ANTI': <TokenType.ANTI: 'ANTI'>, 'ANY': <TokenType.ANY: 'ANY'>, 'ASC': <TokenType.ASC: 'ASC'>, 'AS': <TokenType.ALIAS: 'ALIAS'>, 'ASOF': <TokenType.ASOF: 'ASOF'>, 'AUTOINCREMENT': <TokenType.AUTO_INCREMENT: 'AUTO_INCREMENT'>, 'AUTO_INCREMENT': <TokenType.AUTO_INCREMENT: 'AUTO_INCREMENT'>, 'BEGIN': <TokenType.BEGIN: 'BEGIN'>, 'BETWEEN': <TokenType.BETWEEN: 'BETWEEN'>, 'CACHE': <TokenType.CACHE: 'CACHE'>, 'UNCACHE': <TokenType.UNCACHE: 'UNCACHE'>, 'CASE': <TokenType.CASE: 'CASE'>, 'CHARACTER SET': <TokenType.CHARACTER_SET: 'CHARACTER_SET'>, 'CLUSTER BY': <TokenType.CLUSTER_BY: 'CLUSTER_BY'>, 'COLLATE': <TokenType.COLLATE: 'COLLATE'>, 'COLUMN': <TokenType.COLUMN: 'COLUMN'>, 'COMMIT': <TokenType.COMMIT: 'COMMIT'>, 'CONNECT BY': <TokenType.CONNECT_BY: 'CONNECT_BY'>, 'CONSTRAINT': <TokenType.CONSTRAINT: 'CONSTRAINT'>, 'COPY': <TokenType.COPY: 'COPY'>, 'CREATE': <TokenType.CREATE: 'CREATE'>, 'CROSS': <TokenType.CROSS: 'CROSS'>, 'CUBE': <TokenType.CUBE: 'CUBE'>, 'CURRENT_DATE': <TokenType.CURRENT_DATE: 'CURRENT_DATE'>, 'CURRENT_TIME': <TokenType.CURRENT_TIME: 'CURRENT_TIME'>, 'CURRENT_TIMESTAMP': <TokenType.CURRENT_TIMESTAMP: 'CURRENT_TIMESTAMP'>, 'CURRENT_USER': <TokenType.CURRENT_USER: 'CURRENT_USER'>, 'DATABASE': <TokenType.DATABASE: 'DATABASE'>, 'DEFAULT': <TokenType.DEFAULT: 'DEFAULT'>, 'DELETE': <TokenType.DELETE: 'DELETE'>, 'DESC': <TokenType.DESC: 'DESC'>, 'DESCRIBE': <TokenType.DESCRIBE: 'DESCRIBE'>, 'DISTINCT': <TokenType.DISTINCT: 'DISTINCT'>, 'DISTRIBUTE BY': <TokenType.DISTRIBUTE_BY: 'DISTRIBUTE_BY'>, 'DIV': <TokenType.DIV: 'DIV'>, 'DROP': <TokenType.DROP: 'DROP'>, 'ELSE': <TokenType.ELSE: 'ELSE'>, 'END': <TokenType.END: 'END'>, 'ENUM': <TokenType.ENUM: 'ENUM'>, 'ESCAPE': <TokenType.ESCAPE: 'ESCAPE'>, 'EXCEPT': <TokenType.EXCEPT: 'EXCEPT'>, 'EXECUTE': <TokenType.EXECUTE: 'EXECUTE'>, 'EXISTS': <TokenType.EXISTS: 'EXISTS'>, 'FALSE': <TokenType.FALSE: 'FALSE'>, 'FETCH': <TokenType.FETCH: 'FETCH'>, 'FILTER': <TokenType.FILTER: 'FILTER'>, 'FIRST': <TokenType.FIRST: 'FIRST'>, 'FULL': <TokenType.FULL: 'FULL'>, 'FUNCTION': <TokenType.FUNCTION: 'FUNCTION'>, 'FOR': <TokenType.FOR: 'FOR'>, 'FOREIGN KEY': <TokenType.FOREIGN_KEY: 'FOREIGN_KEY'>, 'FORMAT': <TokenType.FORMAT: 'FORMAT'>, 'FROM': <TokenType.FROM: 'FROM'>, 'GEOGRAPHY': <TokenType.GEOGRAPHY: 'GEOGRAPHY'>, 'GEOMETRY': <TokenType.GEOMETRY: 'GEOMETRY'>, 'GLOB': <TokenType.GLOB: 'GLOB'>, 'GROUP BY': <TokenType.GROUP_BY: 'GROUP_BY'>, 'GROUPING SETS': <TokenType.GROUPING_SETS: 'GROUPING_SETS'>, 'HAVING': <TokenType.HAVING: 'HAVING'>, 'ILIKE': <TokenType.ILIKE: 'ILIKE'>, 'IN': <TokenType.IN: 'IN'>, 'INDEX': <TokenType.INDEX: 'INDEX'>, 'INET': <TokenType.INET: 'INET'>, 'INNER': <TokenType.INNER: 'INNER'>, 'INSERT': <TokenType.INSERT: 'INSERT'>, 'INTERVAL': <TokenType.INTERVAL: 'INTERVAL'>, 'INTERSECT': <TokenType.INTERSECT: 'INTERSECT'>, 'INTO': <TokenType.INTO: 'INTO'>, 'IS': <TokenType.IS: 'IS'>, 'ISNULL': <TokenType.ISNULL: 'ISNULL'>, 'JOIN': <TokenType.JOIN: 'JOIN'>, 'KEEP': <TokenType.KEEP: 'KEEP'>, 'KILL': <TokenType.KILL: 'KILL'>, 'LATERAL': <TokenType.LATERAL: 'LATERAL'>, 'LEFT': <TokenType.LEFT: 'LEFT'>, 'LIKE': <TokenType.LIKE: 'LIKE'>, 'LIMIT': <TokenType.LIMIT: 'LIMIT'>, 'LOAD': <TokenType.LOAD: 'LOAD'>, 'LOCK': <TokenType.LOCK: 'LOCK'>, 'MERGE': <TokenType.MERGE: 'MERGE'>, 'NATURAL': <TokenType.NATURAL: 'NATURAL'>, 'NEXT': <TokenType.NEXT: 'NEXT'>, 'NOT': <TokenType.NOT: 'NOT'>, 'NOTNULL': <TokenType.NOTNULL: 'NOTNULL'>, 'NULL': <TokenType.NULL: 'NULL'>, 'OBJECT': <TokenType.OBJECT: 'OBJECT'>, 'OFFSET': <TokenType.OFFSET: 'OFFSET'>, 'ON': <TokenType.ON: 'ON'>, 'OR': <TokenType.OR: 'OR'>, 'XOR': <TokenType.XOR: 'XOR'>, 'ORDER BY': <TokenType.ORDER_BY: 'ORDER_BY'>, 'ORDINALITY': <TokenType.ORDINALITY: 'ORDINALITY'>, 'OUTER': <TokenType.OUTER: 'OUTER'>, 'OVER': <TokenType.OVER: 'OVER'>, 'OVERLAPS': <TokenType.OVERLAPS: 'OVERLAPS'>, 'OVERWRITE': <TokenType.OVERWRITE: 'OVERWRITE'>, 'PARTITION': <TokenType.PARTITION: 'PARTITION'>, 'PARTITION BY': <TokenType.PARTITION_BY: 'PARTITION_BY'>, 'PARTITIONED BY': <TokenType.PARTITION_BY: 'PARTITION_BY'>, 'PARTITIONED_BY': <TokenType.PARTITION_BY: 'PARTITION_BY'>, 'PERCENT': <TokenType.PERCENT: 'PERCENT'>, 'PIVOT': <TokenType.PIVOT: 'PIVOT'>, 'PRAGMA': <TokenType.PRAGMA: 'PRAGMA'>, 'PRIMARY KEY': <TokenType.PRIMARY_KEY: 'PRIMARY_KEY'>, 'PROCEDURE': <TokenType.PROCEDURE: 'PROCEDURE'>, 'QUALIFY': <TokenType.QUALIFY: 'QUALIFY'>, 'RANGE': <TokenType.RANGE: 'RANGE'>, 'RECURSIVE': <TokenType.RECURSIVE: 'RECURSIVE'>, 'REGEXP': <TokenType.RLIKE: 'RLIKE'>, 'REPLACE': <TokenType.REPLACE: 'REPLACE'>, 'RETURNING': <TokenType.RETURNING: 'RETURNING'>, 'REFERENCES': <TokenType.REFERENCES: 'REFERENCES'>, 'RIGHT': <TokenType.RIGHT: 'RIGHT'>, 'RLIKE': <TokenType.RLIKE: 'RLIKE'>, 'ROLLBACK': <TokenType.ROLLBACK: 'ROLLBACK'>, 'ROLLUP': <TokenType.ROLLUP: 'ROLLUP'>, 'ROW': <TokenType.ROW: 'ROW'>, 'ROWS': <TokenType.ROWS: 'ROWS'>, 'SCHEMA': <TokenType.SCHEMA: 'SCHEMA'>, 'SELECT': <TokenType.SELECT: 'SELECT'>, 'SEMI': <TokenType.SEMI: 'SEMI'>, 'SET': <TokenType.SET: 'SET'>, 'SETTINGS': <TokenType.SETTINGS: 'SETTINGS'>, 'SHOW': <TokenType.SHOW: 'SHOW'>, 'SIMILAR TO': <TokenType.SIMILAR_TO: 'SIMILAR_TO'>, 'SOME': <TokenType.SOME: 'SOME'>, 'SORT BY': <TokenType.SORT_BY: 'SORT_BY'>, 'START WITH': <TokenType.START_WITH: 'START_WITH'>, 'STRAIGHT_JOIN': <TokenType.STRAIGHT_JOIN: 'STRAIGHT_JOIN'>, 'TABLE': <TokenType.TABLE: 'TABLE'>, 'TABLESAMPLE': <TokenType.TABLE_SAMPLE: 'TABLE_SAMPLE'>, 'TEMP': <TokenType.TEMPORARY: 'TEMPORARY'>, 'TEMPORARY': <TokenType.TEMPORARY: 'TEMPORARY'>, 'THEN': <TokenType.THEN: 'THEN'>, 'TRUE': <TokenType.TRUE: 'TRUE'>, 'TRUNCATE': <TokenType.TRUNCATE: 'TRUNCATE'>, 'UNION': <TokenType.UNION: 'UNION'>, 'UNKNOWN': <TokenType.UNKNOWN: 'UNKNOWN'>, 'UNNEST': <TokenType.UNNEST: 'UNNEST'>, 'UNPIVOT': <TokenType.UNPIVOT: 'UNPIVOT'>, 'UPDATE': <TokenType.UPDATE: 'UPDATE'>, 'USE': <TokenType.USE: 'USE'>, 'USING': <TokenType.USING: 'USING'>, 'UUID': <TokenType.UUID: 'UUID'>, 'VALUES': <TokenType.VALUES: 'VALUES'>, 'VIEW': <TokenType.VIEW: 'VIEW'>, 'VOLATILE': <TokenType.VOLATILE: 'VOLATILE'>, 'WHEN': <TokenType.WHEN: 'WHEN'>, 'WHERE': <TokenType.WHERE: 'WHERE'>, 'WINDOW': <TokenType.WINDOW: 'WINDOW'>, 'WITH': <TokenType.WITH: 'WITH'>, 'APPLY': <TokenType.APPLY: 'APPLY'>, 'ARRAY': <TokenType.ARRAY: 'ARRAY'>, 'BIT': <TokenType.BIT: 'BIT'>, 'BOOL': <TokenType.BOOLEAN: 'BOOLEAN'>, 'BOOLEAN': <TokenType.BOOLEAN: 'BOOLEAN'>, 'BYTE': <TokenType.TINYINT: 'TINYINT'>, 'MEDIUMINT': <TokenType.MEDIUMINT: 'MEDIUMINT'>, 'INT1': <TokenType.TINYINT: 'TINYINT'>, 'TINYINT': <TokenType.TINYINT: 'TINYINT'>, 'INT16': <TokenType.SMALLINT: 'SMALLINT'>, 'SHORT': <TokenType.SMALLINT: 'SMALLINT'>, 'SMALLINT': <TokenType.SMALLINT: 'SMALLINT'>, 'INT128': <TokenType.INT128: 'INT128'>, 'HUGEINT': <TokenType.INT128: 'INT128'>, 'INT2': <TokenType.SMALLINT: 'SMALLINT'>, 'INTEGER': <TokenType.INT: 'INT'>, 'INT': <TokenType.INT: 'INT'>, 'INT4': <TokenType.INT: 'INT'>, 'INT32': <TokenType.INT: 'INT'>, 'INT64': <TokenType.BIGINT: 'BIGINT'>, 'LONG': <TokenType.BIGINT: 'BIGINT'>, 'BIGINT': <TokenType.BIGINT: 'BIGINT'>, 'INT8': <TokenType.TINYINT: 'TINYINT'>, 'UINT': <TokenType.UINT: 'UINT'>, 'DEC': <TokenType.DECIMAL: 'DECIMAL'>, 'DECIMAL': <TokenType.DECIMAL: 'DECIMAL'>, 'BIGDECIMAL': <TokenType.BIGDECIMAL: 'BIGDECIMAL'>, 'BIGNUMERIC': <TokenType.BIGDECIMAL: 'BIGDECIMAL'>, 'LIST': <TokenType.LIST: 'LIST'>, 'MAP': <TokenType.MAP: 'MAP'>, 'NULLABLE': <TokenType.NULLABLE: 'NULLABLE'>, 'NUMBER': <TokenType.DECIMAL: 'DECIMAL'>, 'NUMERIC': <TokenType.DECIMAL: 'DECIMAL'>, 'FIXED': <TokenType.DECIMAL: 'DECIMAL'>, 'REAL': <TokenType.FLOAT: 'FLOAT'>, 'FLOAT': <TokenType.FLOAT: 'FLOAT'>, 'FLOAT4': <TokenType.FLOAT: 'FLOAT'>, 'FLOAT8': <TokenType.DOUBLE: 'DOUBLE'>, 'DOUBLE': <TokenType.DOUBLE: 'DOUBLE'>, 'DOUBLE PRECISION': <TokenType.DOUBLE: 'DOUBLE'>, 'JSON': <TokenType.JSON: 'JSON'>, 'JSONB': <TokenType.JSONB: 'JSONB'>, 'CHAR': <TokenType.CHAR: 'CHAR'>, 'CHARACTER': <TokenType.CHAR: 'CHAR'>, 'NCHAR': <TokenType.NCHAR: 'NCHAR'>, 'VARCHAR': <TokenType.VARCHAR: 'VARCHAR'>, 'VARCHAR2': <TokenType.VARCHAR: 'VARCHAR'>, 'NVARCHAR': <TokenType.NVARCHAR: 'NVARCHAR'>, 'NVARCHAR2': <TokenType.NVARCHAR: 'NVARCHAR'>, 'BPCHAR': <TokenType.BPCHAR: 'BPCHAR'>, 'STR': <TokenType.TEXT: 'TEXT'>, 'STRING': <TokenType.TEXT: 'TEXT'>, 'TEXT': <TokenType.TEXT: 'TEXT'>, 'LONGTEXT': <TokenType.LONGTEXT: 'LONGTEXT'>, 'MEDIUMTEXT': <TokenType.MEDIUMTEXT: 'MEDIUMTEXT'>, 'TINYTEXT': <TokenType.TINYTEXT: 'TINYTEXT'>, 'CLOB': <TokenType.TEXT: 'TEXT'>, 'LONGVARCHAR': <TokenType.TEXT: 'TEXT'>, 'BINARY': <TokenType.BINARY: 'BINARY'>, 'BLOB': <TokenType.VARBINARY: 'VARBINARY'>, 'LONGBLOB': <TokenType.LONGBLOB: 'LONGBLOB'>, 'MEDIUMBLOB': <TokenType.MEDIUMBLOB: 'MEDIUMBLOB'>, 'TINYBLOB': <TokenType.TINYBLOB: 'TINYBLOB'>, 'BYTEA': <TokenType.VARBINARY: 'VARBINARY'>, 'VARBINARY': <TokenType.VARBINARY: 'VARBINARY'>, 'TIME': <TokenType.TIME: 'TIME'>, 'TIMETZ': <TokenType.TIMETZ: 'TIMETZ'>, 'TIMESTAMP': <TokenType.TIMESTAMP: 'TIMESTAMP'>, 'TIMESTAMPTZ': <TokenType.TIMESTAMPTZ: 'TIMESTAMPTZ'>, 'TIMESTAMPLTZ': <TokenType.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, 'TIMESTAMP_LTZ': <TokenType.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, 'TIMESTAMPNTZ': <TokenType.TIMESTAMPNTZ: 'TIMESTAMPNTZ'>, 'TIMESTAMP_NTZ': <TokenType.TIMESTAMPNTZ: 'TIMESTAMPNTZ'>, 'DATE': <TokenType.DATE: 'DATE'>, 'DATETIME': <TokenType.DATETIME: 'DATETIME'>, 'INT4RANGE': <TokenType.INT4RANGE: 'INT4RANGE'>, 'INT4MULTIRANGE': <TokenType.INT4MULTIRANGE: 'INT4MULTIRANGE'>, 'INT8RANGE': <TokenType.INT8RANGE: 'INT8RANGE'>, 'INT8MULTIRANGE': <TokenType.INT8MULTIRANGE: 'INT8MULTIRANGE'>, 'NUMRANGE': <TokenType.NUMRANGE: 'NUMRANGE'>, 'NUMMULTIRANGE': <TokenType.NUMMULTIRANGE: 'NUMMULTIRANGE'>, 'TSRANGE': <TokenType.TSRANGE: 'TSRANGE'>, 'TSMULTIRANGE': <TokenType.TSMULTIRANGE: 'TSMULTIRANGE'>, 'TSTZRANGE': <TokenType.TSTZRANGE: 'TSTZRANGE'>, 'TSTZMULTIRANGE': <TokenType.TSTZMULTIRANGE: 'TSTZMULTIRANGE'>, 'DATERANGE': <TokenType.DATERANGE: 'DATERANGE'>, 'DATEMULTIRANGE': <TokenType.DATEMULTIRANGE: 'DATEMULTIRANGE'>, 'UNIQUE': <TokenType.UNIQUE: 'UNIQUE'>, 'VECTOR': <TokenType.VECTOR: 'VECTOR'>, 'STRUCT': <TokenType.STRUCT: 'STRUCT'>, 'SEQUENCE': <TokenType.SEQUENCE: 'SEQUENCE'>, 'VARIANT': <TokenType.VARIANT: 'VARIANT'>, 'ALTER': <TokenType.ALTER: 'ALTER'>, 'ANALYZE': <TokenType.COMMAND: 'COMMAND'>, 'CALL': <TokenType.COMMAND: 'COMMAND'>, 'COMMENT': <TokenType.COMMENT: 'COMMENT'>, 'EXPLAIN': <TokenType.COMMAND: 'COMMAND'>, 'GRANT': <TokenType.COMMAND: 'COMMAND'>, 'OPTIMIZE': <TokenType.COMMAND: 'COMMAND'>, 'PREPARE': <TokenType.COMMAND: 'COMMAND'>, 'VACUUM': <TokenType.COMMAND: 'COMMAND'>, 'USER-DEFINED': <TokenType.USERDEFINED: 'USERDEFINED'>, 'FOR VERSION': <TokenType.VERSION_SNAPSHOT: 'VERSION_SNAPSHOT'>, 'FOR TIMESTAMP': <TokenType.TIMESTAMP_SNAPSHOT: 'TIMESTAMP_SNAPSHOT'>, 'CHARSET': <TokenType.CHARACTER_SET: 'CHARACTER_SET'>, 'FORCE': <TokenType.FORCE: 'FORCE'>, 'IGNORE': <TokenType.IGNORE: 'IGNORE'>, 'KEY': <TokenType.KEY: 'KEY'>, 'LOCK TABLES': <TokenType.COMMAND: 'COMMAND'>, 'MEMBER OF': <TokenType.MEMBER_OF: 'MEMBER_OF'>, 'SEPARATOR': <TokenType.SEPARATOR: 'SEPARATOR'>, 'START': <TokenType.BEGIN: 'BEGIN'>, 'SIGNED': <TokenType.BIGINT: 'BIGINT'>, 'SIGNED INTEGER': <TokenType.BIGINT: 'BIGINT'>, 'UNLOCK TABLES': <TokenType.COMMAND: 'COMMAND'>, 'UNSIGNED': <TokenType.UBIGINT: 'UBIGINT'>, 'UNSIGNED INTEGER': <TokenType.UBIGINT: 'UBIGINT'>, 'YEAR': <TokenType.YEAR: 'YEAR'>, '_ARMSCII8': <TokenType.INTRODUCER: 'INTRODUCER'>, '_ASCII': <TokenType.INTRODUCER: 'INTRODUCER'>, '_BIG5': <TokenType.INTRODUCER: 'INTRODUCER'>, '_BINARY': <TokenType.INTRODUCER: 'INTRODUCER'>, '_CP1250': <TokenType.INTRODUCER: 'INTRODUCER'>, '_CP1251': <TokenType.INTRODUCER: 'INTRODUCER'>, '_CP1256': <TokenType.INTRODUCER: 'INTRODUCER'>, '_CP1257': <TokenType.INTRODUCER: 'INTRODUCER'>, '_CP850': <TokenType.INTRODUCER: 'INTRODUCER'>, '_CP852': <TokenType.INTRODUCER: 'INTRODUCER'>, '_CP866': <TokenType.INTRODUCER: 'INTRODUCER'>, '_CP932': <TokenType.INTRODUCER: 'INTRODUCER'>, '_DEC8': <TokenType.INTRODUCER: 'INTRODUCER'>, '_EUCJPMS': <TokenType.INTRODUCER: 'INTRODUCER'>, '_EUCKR': <TokenType.INTRODUCER: 'INTRODUCER'>, '_GB18030': <TokenType.INTRODUCER: 'INTRODUCER'>, '_GB2312': <TokenType.INTRODUCER: 'INTRODUCER'>, '_GBK': <TokenType.INTRODUCER: 'INTRODUCER'>, '_GEOSTD8': <TokenType.INTRODUCER: 'INTRODUCER'>, '_GREEK': <TokenType.INTRODUCER: 'INTRODUCER'>, '_HEBREW': <TokenType.INTRODUCER: 'INTRODUCER'>, '_HP8': <TokenType.INTRODUCER: 'INTRODUCER'>, '_KEYBCS2': <TokenType.INTRODUCER: 'INTRODUCER'>, '_KOI8R': <TokenType.INTRODUCER: 'INTRODUCER'>, '_KOI8U': <TokenType.INTRODUCER: 'INTRODUCER'>, '_LATIN1': <TokenType.INTRODUCER: 'INTRODUCER'>, '_LATIN2': <TokenType.INTRODUCER: 'INTRODUCER'>, '_LATIN5': <TokenType.INTRODUCER: 'INTRODUCER'>, '_LATIN7': <TokenType.INTRODUCER: 'INTRODUCER'>, '_MACCE': <TokenType.INTRODUCER: 'INTRODUCER'>, '_MACROMAN': <TokenType.INTRODUCER: 'INTRODUCER'>, '_SJIS': <TokenType.INTRODUCER: 'INTRODUCER'>, '_SWE7': <TokenType.INTRODUCER: 'INTRODUCER'>, '_TIS620': <TokenType.INTRODUCER: 'INTRODUCER'>, '_UCS2': <TokenType.INTRODUCER: 'INTRODUCER'>, '_UJIS': <TokenType.INTRODUCER: 'INTRODUCER'>, '_UTF8': <TokenType.INTRODUCER: 'INTRODUCER'>, '_UTF16': <TokenType.INTRODUCER: 'INTRODUCER'>, '_UTF16LE': <TokenType.INTRODUCER: 'INTRODUCER'>, '_UTF32': <TokenType.INTRODUCER: 'INTRODUCER'>, '_UTF8MB3': <TokenType.INTRODUCER: 'INTRODUCER'>, '_UTF8MB4': <TokenType.INTRODUCER: 'INTRODUCER'>, '@@': <TokenType.SESSION_PARAMETER: 'SESSION_PARAMETER'>}
COMMANDS =
{<TokenType.FETCH: 'FETCH'>, <TokenType.REPLACE: 'REPLACE'>, <TokenType.COMMAND: 'COMMAND'>, <TokenType.EXECUTE: 'EXECUTE'>}
Inherited Members
- sqlglot.tokens.Tokenizer
- Tokenizer
- SINGLE_TOKENS
- BYTE_STRINGS
- RAW_STRINGS
- HEREDOC_STRINGS
- UNICODE_STRINGS
- IDENTIFIER_ESCAPES
- VAR_SINGLE_TOKENS
- HEREDOC_TAG_IS_IDENTIFIER
- HEREDOC_STRING_ALTERNATIVE
- STRING_ESCAPES_ALLOWED_IN_RAW_STRINGS
- WHITE_SPACE
- COMMAND_PREFIX_TOKENS
- NUMERIC_LITERALS
- dialect
- reset
- tokenize
- tokenize_rs
- size
- sql
- tokens
272 class Parser(parser.Parser): 273 FUNC_TOKENS = { 274 *parser.Parser.FUNC_TOKENS, 275 TokenType.DATABASE, 276 TokenType.SCHEMA, 277 TokenType.VALUES, 278 } 279 280 CONJUNCTION = { 281 **parser.Parser.CONJUNCTION, 282 TokenType.DAMP: exp.And, 283 TokenType.XOR: exp.Xor, 284 } 285 286 DISJUNCTION = { 287 **parser.Parser.DISJUNCTION, 288 TokenType.DPIPE: exp.Or, 289 } 290 291 TABLE_ALIAS_TOKENS = ( 292 parser.Parser.TABLE_ALIAS_TOKENS - parser.Parser.TABLE_INDEX_HINT_TOKENS 293 ) 294 295 RANGE_PARSERS = { 296 **parser.Parser.RANGE_PARSERS, 297 TokenType.MEMBER_OF: lambda self, this: self.expression( 298 exp.JSONArrayContains, 299 this=this, 300 expression=self._parse_wrapped(self._parse_expression), 301 ), 302 } 303 304 FUNCTIONS = { 305 **parser.Parser.FUNCTIONS, 306 "DATE": lambda args: exp.TsOrDsToDate(this=seq_get(args, 0)), 307 "DATE_ADD": build_date_delta_with_interval(exp.DateAdd), 308 "DATE_FORMAT": build_formatted_time(exp.TimeToStr, "mysql"), 309 "DATE_SUB": build_date_delta_with_interval(exp.DateSub), 310 "DAY": lambda args: exp.Day(this=exp.TsOrDsToDate(this=seq_get(args, 0))), 311 "DAYOFMONTH": lambda args: exp.DayOfMonth(this=exp.TsOrDsToDate(this=seq_get(args, 0))), 312 "DAYOFWEEK": lambda args: exp.DayOfWeek(this=exp.TsOrDsToDate(this=seq_get(args, 0))), 313 "DAYOFYEAR": lambda args: exp.DayOfYear(this=exp.TsOrDsToDate(this=seq_get(args, 0))), 314 "INSTR": lambda args: exp.StrPosition(substr=seq_get(args, 1), this=seq_get(args, 0)), 315 "FROM_UNIXTIME": build_formatted_time(exp.UnixToTime, "mysql"), 316 "ISNULL": isnull_to_is_null, 317 "LOCATE": locate_to_strposition, 318 "MAKETIME": exp.TimeFromParts.from_arg_list, 319 "MONTH": lambda args: exp.Month(this=exp.TsOrDsToDate(this=seq_get(args, 0))), 320 "MONTHNAME": lambda args: exp.TimeToStr( 321 this=exp.TsOrDsToDate(this=seq_get(args, 0)), 322 format=exp.Literal.string("%B"), 323 ), 324 "STR_TO_DATE": _str_to_date, 325 "TIMESTAMPDIFF": build_date_delta(exp.TimestampDiff), 326 "TO_DAYS": lambda args: exp.paren( 327 exp.DateDiff( 328 this=exp.TsOrDsToDate(this=seq_get(args, 0)), 329 expression=exp.TsOrDsToDate(this=exp.Literal.string("0000-01-01")), 330 unit=exp.var("DAY"), 331 ) 332 + 1 333 ), 334 "WEEK": lambda args: exp.Week( 335 this=exp.TsOrDsToDate(this=seq_get(args, 0)), mode=seq_get(args, 1) 336 ), 337 "WEEKOFYEAR": lambda args: exp.WeekOfYear(this=exp.TsOrDsToDate(this=seq_get(args, 0))), 338 "YEAR": lambda args: exp.Year(this=exp.TsOrDsToDate(this=seq_get(args, 0))), 339 } 340 341 FUNCTION_PARSERS = { 342 **parser.Parser.FUNCTION_PARSERS, 343 "CHAR": lambda self: self._parse_chr(), 344 "GROUP_CONCAT": lambda self: self._parse_group_concat(), 345 # https://dev.mysql.com/doc/refman/5.7/en/miscellaneous-functions.html#function_values 346 "VALUES": lambda self: self.expression( 347 exp.Anonymous, this="VALUES", expressions=[self._parse_id_var()] 348 ), 349 } 350 351 STATEMENT_PARSERS = { 352 **parser.Parser.STATEMENT_PARSERS, 353 TokenType.SHOW: lambda self: self._parse_show(), 354 } 355 356 SHOW_PARSERS = { 357 "BINARY LOGS": _show_parser("BINARY LOGS"), 358 "MASTER LOGS": _show_parser("BINARY LOGS"), 359 "BINLOG EVENTS": _show_parser("BINLOG EVENTS"), 360 "CHARACTER SET": _show_parser("CHARACTER SET"), 361 "CHARSET": _show_parser("CHARACTER SET"), 362 "COLLATION": _show_parser("COLLATION"), 363 "FULL COLUMNS": _show_parser("COLUMNS", target="FROM", full=True), 364 "COLUMNS": _show_parser("COLUMNS", target="FROM"), 365 "CREATE DATABASE": _show_parser("CREATE DATABASE", target=True), 366 "CREATE EVENT": _show_parser("CREATE EVENT", target=True), 367 "CREATE FUNCTION": _show_parser("CREATE FUNCTION", target=True), 368 "CREATE PROCEDURE": _show_parser("CREATE PROCEDURE", target=True), 369 "CREATE TABLE": _show_parser("CREATE TABLE", target=True), 370 "CREATE TRIGGER": _show_parser("CREATE TRIGGER", target=True), 371 "CREATE VIEW": _show_parser("CREATE VIEW", target=True), 372 "DATABASES": _show_parser("DATABASES"), 373 "SCHEMAS": _show_parser("DATABASES"), 374 "ENGINE": _show_parser("ENGINE", target=True), 375 "STORAGE ENGINES": _show_parser("ENGINES"), 376 "ENGINES": _show_parser("ENGINES"), 377 "ERRORS": _show_parser("ERRORS"), 378 "EVENTS": _show_parser("EVENTS"), 379 "FUNCTION CODE": _show_parser("FUNCTION CODE", target=True), 380 "FUNCTION STATUS": _show_parser("FUNCTION STATUS"), 381 "GRANTS": _show_parser("GRANTS", target="FOR"), 382 "INDEX": _show_parser("INDEX", target="FROM"), 383 "MASTER STATUS": _show_parser("MASTER STATUS"), 384 "OPEN TABLES": _show_parser("OPEN TABLES"), 385 "PLUGINS": _show_parser("PLUGINS"), 386 "PROCEDURE CODE": _show_parser("PROCEDURE CODE", target=True), 387 "PROCEDURE STATUS": _show_parser("PROCEDURE STATUS"), 388 "PRIVILEGES": _show_parser("PRIVILEGES"), 389 "FULL PROCESSLIST": _show_parser("PROCESSLIST", full=True), 390 "PROCESSLIST": _show_parser("PROCESSLIST"), 391 "PROFILE": _show_parser("PROFILE"), 392 "PROFILES": _show_parser("PROFILES"), 393 "RELAYLOG EVENTS": _show_parser("RELAYLOG EVENTS"), 394 "REPLICAS": _show_parser("REPLICAS"), 395 "SLAVE HOSTS": _show_parser("REPLICAS"), 396 "REPLICA STATUS": _show_parser("REPLICA STATUS"), 397 "SLAVE STATUS": _show_parser("REPLICA STATUS"), 398 "GLOBAL STATUS": _show_parser("STATUS", global_=True), 399 "SESSION STATUS": _show_parser("STATUS"), 400 "STATUS": _show_parser("STATUS"), 401 "TABLE STATUS": _show_parser("TABLE STATUS"), 402 "FULL TABLES": _show_parser("TABLES", full=True), 403 "TABLES": _show_parser("TABLES"), 404 "TRIGGERS": _show_parser("TRIGGERS"), 405 "GLOBAL VARIABLES": _show_parser("VARIABLES", global_=True), 406 "SESSION VARIABLES": _show_parser("VARIABLES"), 407 "VARIABLES": _show_parser("VARIABLES"), 408 "WARNINGS": _show_parser("WARNINGS"), 409 } 410 411 PROPERTY_PARSERS = { 412 **parser.Parser.PROPERTY_PARSERS, 413 "LOCK": lambda self: self._parse_property_assignment(exp.LockProperty), 414 } 415 416 SET_PARSERS = { 417 **parser.Parser.SET_PARSERS, 418 "PERSIST": lambda self: self._parse_set_item_assignment("PERSIST"), 419 "PERSIST_ONLY": lambda self: self._parse_set_item_assignment("PERSIST_ONLY"), 420 "CHARACTER SET": lambda self: self._parse_set_item_charset("CHARACTER SET"), 421 "CHARSET": lambda self: self._parse_set_item_charset("CHARACTER SET"), 422 "NAMES": lambda self: self._parse_set_item_names(), 423 } 424 425 CONSTRAINT_PARSERS = { 426 **parser.Parser.CONSTRAINT_PARSERS, 427 "FULLTEXT": lambda self: self._parse_index_constraint(kind="FULLTEXT"), 428 "INDEX": lambda self: self._parse_index_constraint(), 429 "KEY": lambda self: self._parse_index_constraint(), 430 "SPATIAL": lambda self: self._parse_index_constraint(kind="SPATIAL"), 431 } 432 433 ALTER_PARSERS = { 434 **parser.Parser.ALTER_PARSERS, 435 "MODIFY": lambda self: self._parse_alter_table_alter(), 436 } 437 438 SCHEMA_UNNAMED_CONSTRAINTS = { 439 *parser.Parser.SCHEMA_UNNAMED_CONSTRAINTS, 440 "FULLTEXT", 441 "INDEX", 442 "KEY", 443 "SPATIAL", 444 } 445 446 PROFILE_TYPES: parser.OPTIONS_TYPE = { 447 **dict.fromkeys(("ALL", "CPU", "IPC", "MEMORY", "SOURCE", "SWAPS"), tuple()), 448 "BLOCK": ("IO",), 449 "CONTEXT": ("SWITCHES",), 450 "PAGE": ("FAULTS",), 451 } 452 453 TYPE_TOKENS = { 454 *parser.Parser.TYPE_TOKENS, 455 TokenType.SET, 456 } 457 458 ENUM_TYPE_TOKENS = { 459 *parser.Parser.ENUM_TYPE_TOKENS, 460 TokenType.SET, 461 } 462 463 LOG_DEFAULTS_TO_LN = True 464 STRING_ALIASES = True 465 VALUES_FOLLOWED_BY_PAREN = False 466 SUPPORTS_PARTITION_SELECTION = True 467 468 def _parse_primary_key_part(self) -> t.Optional[exp.Expression]: 469 this = self._parse_id_var() 470 if not self._match(TokenType.L_PAREN): 471 return this 472 473 expression = self._parse_number() 474 self._match_r_paren() 475 return self.expression(exp.ColumnPrefix, this=this, expression=expression) 476 477 def _parse_index_constraint( 478 self, kind: t.Optional[str] = None 479 ) -> exp.IndexColumnConstraint: 480 if kind: 481 self._match_texts(("INDEX", "KEY")) 482 483 this = self._parse_id_var(any_token=False) 484 index_type = self._match(TokenType.USING) and self._advance_any() and self._prev.text 485 expressions = self._parse_wrapped_csv(self._parse_ordered) 486 487 options = [] 488 while True: 489 if self._match_text_seq("KEY_BLOCK_SIZE"): 490 self._match(TokenType.EQ) 491 opt = exp.IndexConstraintOption(key_block_size=self._parse_number()) 492 elif self._match(TokenType.USING): 493 opt = exp.IndexConstraintOption(using=self._advance_any() and self._prev.text) 494 elif self._match_text_seq("WITH", "PARSER"): 495 opt = exp.IndexConstraintOption(parser=self._parse_var(any_token=True)) 496 elif self._match(TokenType.COMMENT): 497 opt = exp.IndexConstraintOption(comment=self._parse_string()) 498 elif self._match_text_seq("VISIBLE"): 499 opt = exp.IndexConstraintOption(visible=True) 500 elif self._match_text_seq("INVISIBLE"): 501 opt = exp.IndexConstraintOption(visible=False) 502 elif self._match_text_seq("ENGINE_ATTRIBUTE"): 503 self._match(TokenType.EQ) 504 opt = exp.IndexConstraintOption(engine_attr=self._parse_string()) 505 elif self._match_text_seq("SECONDARY_ENGINE_ATTRIBUTE"): 506 self._match(TokenType.EQ) 507 opt = exp.IndexConstraintOption(secondary_engine_attr=self._parse_string()) 508 else: 509 opt = None 510 511 if not opt: 512 break 513 514 options.append(opt) 515 516 return self.expression( 517 exp.IndexColumnConstraint, 518 this=this, 519 expressions=expressions, 520 kind=kind, 521 index_type=index_type, 522 options=options, 523 ) 524 525 def _parse_show_mysql( 526 self, 527 this: str, 528 target: bool | str = False, 529 full: t.Optional[bool] = None, 530 global_: t.Optional[bool] = None, 531 ) -> exp.Show: 532 if target: 533 if isinstance(target, str): 534 self._match_text_seq(target) 535 target_id = self._parse_id_var() 536 else: 537 target_id = None 538 539 log = self._parse_string() if self._match_text_seq("IN") else None 540 541 if this in ("BINLOG EVENTS", "RELAYLOG EVENTS"): 542 position = self._parse_number() if self._match_text_seq("FROM") else None 543 db = None 544 else: 545 position = None 546 db = None 547 548 if self._match(TokenType.FROM): 549 db = self._parse_id_var() 550 elif self._match(TokenType.DOT): 551 db = target_id 552 target_id = self._parse_id_var() 553 554 channel = self._parse_id_var() if self._match_text_seq("FOR", "CHANNEL") else None 555 556 like = self._parse_string() if self._match_text_seq("LIKE") else None 557 where = self._parse_where() 558 559 if this == "PROFILE": 560 types = self._parse_csv(lambda: self._parse_var_from_options(self.PROFILE_TYPES)) 561 query = self._parse_number() if self._match_text_seq("FOR", "QUERY") else None 562 offset = self._parse_number() if self._match_text_seq("OFFSET") else None 563 limit = self._parse_number() if self._match_text_seq("LIMIT") else None 564 else: 565 types, query = None, None 566 offset, limit = self._parse_oldstyle_limit() 567 568 mutex = True if self._match_text_seq("MUTEX") else None 569 mutex = False if self._match_text_seq("STATUS") else mutex 570 571 return self.expression( 572 exp.Show, 573 this=this, 574 target=target_id, 575 full=full, 576 log=log, 577 position=position, 578 db=db, 579 channel=channel, 580 like=like, 581 where=where, 582 types=types, 583 query=query, 584 offset=offset, 585 limit=limit, 586 mutex=mutex, 587 **{"global": global_}, # type: ignore 588 ) 589 590 def _parse_oldstyle_limit( 591 self, 592 ) -> t.Tuple[t.Optional[exp.Expression], t.Optional[exp.Expression]]: 593 limit = None 594 offset = None 595 if self._match_text_seq("LIMIT"): 596 parts = self._parse_csv(self._parse_number) 597 if len(parts) == 1: 598 limit = parts[0] 599 elif len(parts) == 2: 600 limit = parts[1] 601 offset = parts[0] 602 603 return offset, limit 604 605 def _parse_set_item_charset(self, kind: str) -> exp.Expression: 606 this = self._parse_string() or self._parse_unquoted_field() 607 return self.expression(exp.SetItem, this=this, kind=kind) 608 609 def _parse_set_item_names(self) -> exp.Expression: 610 charset = self._parse_string() or self._parse_unquoted_field() 611 if self._match_text_seq("COLLATE"): 612 collate = self._parse_string() or self._parse_unquoted_field() 613 else: 614 collate = None 615 616 return self.expression(exp.SetItem, this=charset, collate=collate, kind="NAMES") 617 618 def _parse_type( 619 self, parse_interval: bool = True, fallback_to_identifier: bool = False 620 ) -> t.Optional[exp.Expression]: 621 # mysql binary is special and can work anywhere, even in order by operations 622 # it operates like a no paren func 623 if self._match(TokenType.BINARY, advance=False): 624 data_type = self._parse_types(check_func=True, allow_identifiers=False) 625 626 if isinstance(data_type, exp.DataType): 627 return self.expression(exp.Cast, this=self._parse_column(), to=data_type) 628 629 return super()._parse_type( 630 parse_interval=parse_interval, fallback_to_identifier=fallback_to_identifier 631 ) 632 633 def _parse_chr(self) -> t.Optional[exp.Expression]: 634 expressions = self._parse_csv(self._parse_assignment) 635 kwargs: t.Dict[str, t.Any] = {"this": seq_get(expressions, 0)} 636 637 if len(expressions) > 1: 638 kwargs["expressions"] = expressions[1:] 639 640 if self._match(TokenType.USING): 641 kwargs["charset"] = self._parse_var() 642 643 return self.expression(exp.Chr, **kwargs) 644 645 def _parse_group_concat(self) -> t.Optional[exp.Expression]: 646 def concat_exprs( 647 node: t.Optional[exp.Expression], exprs: t.List[exp.Expression] 648 ) -> exp.Expression: 649 if isinstance(node, exp.Distinct) and len(node.expressions) > 1: 650 concat_exprs = [ 651 self.expression(exp.Concat, expressions=node.expressions, safe=True) 652 ] 653 node.set("expressions", concat_exprs) 654 return node 655 if len(exprs) == 1: 656 return exprs[0] 657 return self.expression(exp.Concat, expressions=args, safe=True) 658 659 args = self._parse_csv(self._parse_lambda) 660 661 if args: 662 order = args[-1] if isinstance(args[-1], exp.Order) else None 663 664 if order: 665 # Order By is the last (or only) expression in the list and has consumed the 'expr' before it, 666 # remove 'expr' from exp.Order and add it back to args 667 args[-1] = order.this 668 order.set("this", concat_exprs(order.this, args)) 669 670 this = order or concat_exprs(args[0], args) 671 else: 672 this = None 673 674 separator = self._parse_field() if self._match(TokenType.SEPARATOR) else None 675 676 return self.expression(exp.GroupConcat, this=this, separator=separator)
Parser consumes a list of tokens produced by the Tokenizer and produces a parsed syntax tree.
Arguments:
- error_level: The desired error level. Default: ErrorLevel.IMMEDIATE
- error_message_context: The amount of context to capture from a query string when displaying the error message (in number of characters). Default: 100
- max_errors: Maximum number of error messages to include in a raised ParseError. This is only relevant if error_level is ErrorLevel.RAISE. Default: 3
FUNC_TOKENS =
{<TokenType.TIMESTAMPNTZ: 'TIMESTAMPNTZ'>, <TokenType.MEDIUMINT: 'MEDIUMINT'>, <TokenType.DATERANGE: 'DATERANGE'>, <TokenType.PRIMARY_KEY: 'PRIMARY_KEY'>, <TokenType.GEOGRAPHY: 'GEOGRAPHY'>, <TokenType.TIME: 'TIME'>, <TokenType.INT256: 'INT256'>, <TokenType.FLOAT: 'FLOAT'>, <TokenType.GLOB: 'GLOB'>, <TokenType.TINYINT: 'TINYINT'>, <TokenType.TIMESTAMP_S: 'TIMESTAMP_S'>, <TokenType.FILTER: 'FILTER'>, <TokenType.CURRENT_DATETIME: 'CURRENT_DATETIME'>, <TokenType.VECTOR: 'VECTOR'>, <TokenType.OBJECT_IDENTIFIER: 'OBJECT_IDENTIFIER'>, <TokenType.NESTED: 'NESTED'>, <TokenType.UINT128: 'UINT128'>, <TokenType.INSERT: 'INSERT'>, <TokenType.ROWVERSION: 'ROWVERSION'>, <TokenType.IPV6: 'IPV6'>, <TokenType.GEOMETRY: 'GEOMETRY'>, <TokenType.IDENTIFIER: 'IDENTIFIER'>, <TokenType.TINYTEXT: 'TINYTEXT'>, <TokenType.BINARY: 'BINARY'>, <TokenType.WINDOW: 'WINDOW'>, <TokenType.BOOLEAN: 'BOOLEAN'>, <TokenType.ROW: 'ROW'>, <TokenType.TEXT: 'TEXT'>, <TokenType.IPPREFIX: 'IPPREFIX'>, <TokenType.ISNULL: 'ISNULL'>, <TokenType.CURRENT_TIME: 'CURRENT_TIME'>, <TokenType.ENUM16: 'ENUM16'>, <TokenType.SCHEMA: 'SCHEMA'>, <TokenType.UTINYINT: 'UTINYINT'>, <TokenType.INDEX: 'INDEX'>, <TokenType.IPV4: 'IPV4'>, <TokenType.INT128: 'INT128'>, <TokenType.DECIMAL: 'DECIMAL'>, <TokenType.TABLE: 'TABLE'>, <TokenType.LONGTEXT: 'LONGTEXT'>, <TokenType.TIMESTAMP_MS: 'TIMESTAMP_MS'>, <TokenType.TINYBLOB: 'TINYBLOB'>, <TokenType.NUMRANGE: 'NUMRANGE'>, <TokenType.NULLABLE: 'NULLABLE'>, <TokenType.IMAGE: 'IMAGE'>, <TokenType.TSTZMULTIRANGE: 'TSTZMULTIRANGE'>, <TokenType.LIST: 'LIST'>, <TokenType.INT4MULTIRANGE: 'INT4MULTIRANGE'>, <TokenType.SEQUENCE: 'SEQUENCE'>, <TokenType.ALL: 'ALL'>, <TokenType.MAP: 'MAP'>, <TokenType.LOWCARDINALITY: 'LOWCARDINALITY'>, <TokenType.UNKNOWN: 'UNKNOWN'>, <TokenType.NULL: 'NULL'>, <TokenType.LEFT: 'LEFT'>, <TokenType.INT4RANGE: 'INT4RANGE'>, <TokenType.CURRENT_TIMESTAMP: 'CURRENT_TIMESTAMP'>, <TokenType.TDIGEST: 'TDIGEST'>, <TokenType.MONEY: 'MONEY'>, <TokenType.TIMESTAMP_NS: 'TIMESTAMP_NS'>, <TokenType.STRUCT: 'STRUCT'>, <TokenType.SMALLINT: 'SMALLINT'>, <TokenType.SMALLMONEY: 'SMALLMONEY'>, <TokenType.SIMPLEAGGREGATEFUNCTION: 'SIMPLEAGGREGATEFUNCTION'>, <TokenType.VARCHAR: 'VARCHAR'>, <TokenType.COLLATE: 'COLLATE'>, <TokenType.NCHAR: 'NCHAR'>, <TokenType.MEDIUMTEXT: 'MEDIUMTEXT'>, <TokenType.LIKE: 'LIKE'>, <TokenType.OFFSET: 'OFFSET'>, <TokenType.BPCHAR: 'BPCHAR'>, <TokenType.SUPER: 'SUPER'>, <TokenType.USMALLINT: 'USMALLINT'>, <TokenType.TSTZRANGE: 'TSTZRANGE'>, <TokenType.CHAR: 'CHAR'>, <TokenType.EXISTS: 'EXISTS'>, <TokenType.LONGBLOB: 'LONGBLOB'>, <TokenType.CURRENT_USER: 'CURRENT_USER'>, <TokenType.UINT: 'UINT'>, <TokenType.VARIANT: 'VARIANT'>, <TokenType.ENUM8: 'ENUM8'>, <TokenType.BIGINT: 'BIGINT'>, <TokenType.TIMESTAMP: 'TIMESTAMP'>, <TokenType.SOME: 'SOME'>, <TokenType.UMEDIUMINT: 'UMEDIUMINT'>, <TokenType.DATEMULTIRANGE: 'DATEMULTIRANGE'>, <TokenType.USERDEFINED: 'USERDEFINED'>, <TokenType.ILIKE: 'ILIKE'>, <TokenType.NUMMULTIRANGE: 'NUMMULTIRANGE'>, <TokenType.RANGE: 'RANGE'>, <TokenType.FIRST: 'FIRST'>, <TokenType.UUID: 'UUID'>, <TokenType.AGGREGATEFUNCTION: 'AGGREGATEFUNCTION'>, <TokenType.MERGE: 'MERGE'>, <TokenType.INT8MULTIRANGE: 'INT8MULTIRANGE'>, <TokenType.VAR: 'VAR'>, <TokenType.NVARCHAR: 'NVARCHAR'>, <TokenType.NAME: 'NAME'>, <TokenType.JSON: 'JSON'>, <TokenType.TSMULTIRANGE: 'TSMULTIRANGE'>, <TokenType.YEAR: 'YEAR'>, <TokenType.XML: 'XML'>, <TokenType.OBJECT: 'OBJECT'>, <TokenType.DATE32: 'DATE32'>, <TokenType.DATETIME64: 'DATETIME64'>, <TokenType.DATETIME: 'DATETIME'>, <TokenType.JSONB: 'JSONB'>, <TokenType.BIT: 'BIT'>, <TokenType.FORMAT: 'FORMAT'>, <TokenType.UNIQUEIDENTIFIER: 'UNIQUEIDENTIFIER'>, <TokenType.TSRANGE: 'TSRANGE'>, <TokenType.RIGHT: 'RIGHT'>, <TokenType.BIGSERIAL: 'BIGSERIAL'>, <TokenType.VARBINARY: 'VARBINARY'>, <TokenType.RLIKE: 'RLIKE'>, <TokenType.UINT256: 'UINT256'>, <TokenType.ARRAY: 'ARRAY'>, <TokenType.XOR: 'XOR'>, <TokenType.INT: 'INT'>, <TokenType.IPADDRESS: 'IPADDRESS'>, <TokenType.INET: 'INET'>, <TokenType.INT8RANGE: 'INT8RANGE'>, <TokenType.SMALLSERIAL: 'SMALLSERIAL'>, <TokenType.ANY: 'ANY'>, <TokenType.HLLSKETCH: 'HLLSKETCH'>, <TokenType.TIMESTAMPTZ: 'TIMESTAMPTZ'>, <TokenType.FIXEDSTRING: 'FIXEDSTRING'>, <TokenType.TRUNCATE: 'TRUNCATE'>, <TokenType.DOUBLE: 'DOUBLE'>, <TokenType.UBIGINT: 'UBIGINT'>, <TokenType.UDECIMAL: 'UDECIMAL'>, <TokenType.REPLACE: 'REPLACE'>, <TokenType.HSTORE: 'HSTORE'>, <TokenType.DATABASE: 'DATABASE'>, <TokenType.UNNEST: 'UNNEST'>, <TokenType.ENUM: 'ENUM'>, <TokenType.CURRENT_DATE: 'CURRENT_DATE'>, <TokenType.COMMAND: 'COMMAND'>, <TokenType.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, <TokenType.INTERVAL: 'INTERVAL'>, <TokenType.PSEUDO_TYPE: 'PSEUDO_TYPE'>, <TokenType.MEDIUMBLOB: 'MEDIUMBLOB'>, <TokenType.TIMETZ: 'TIMETZ'>, <TokenType.SERIAL: 'SERIAL'>, <TokenType.DATE: 'DATE'>, <TokenType.BIGDECIMAL: 'BIGDECIMAL'>, <TokenType.VALUES: 'VALUES'>}
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.TIMESTAMPNTZ: 'TIMESTAMPNTZ'>, <TokenType.FINAL: 'FINAL'>, <TokenType.MEDIUMINT: 'MEDIUMINT'>, <TokenType.DATERANGE: 'DATERANGE'>, <TokenType.TAG: 'TAG'>, <TokenType.GEOGRAPHY: 'GEOGRAPHY'>, <TokenType.TIME: 'TIME'>, <TokenType.COPY: 'COPY'>, <TokenType.DELETE: 'DELETE'>, <TokenType.INT256: 'INT256'>, <TokenType.TRUE: 'TRUE'>, <TokenType.FLOAT: 'FLOAT'>, <TokenType.ANTI: 'ANTI'>, <TokenType.TINYINT: 'TINYINT'>, <TokenType.TIMESTAMP_S: 'TIMESTAMP_S'>, <TokenType.FILTER: 'FILTER'>, <TokenType.CACHE: 'CACHE'>, <TokenType.VECTOR: 'VECTOR'>, <TokenType.OBJECT_IDENTIFIER: 'OBJECT_IDENTIFIER'>, <TokenType.ROWS: 'ROWS'>, <TokenType.NESTED: 'NESTED'>, <TokenType.CURRENT_DATETIME: 'CURRENT_DATETIME'>, <TokenType.KEEP: 'KEEP'>, <TokenType.CASE: 'CASE'>, <TokenType.KILL: 'KILL'>, <TokenType.TEMPORARY: 'TEMPORARY'>, <TokenType.UINT128: 'UINT128'>, <TokenType.COMMIT: 'COMMIT'>, <TokenType.ROWVERSION: 'ROWVERSION'>, <TokenType.IDENTIFIER: 'IDENTIFIER'>, <TokenType.STREAMLIT: 'STREAMLIT'>, <TokenType.IPV6: 'IPV6'>, <TokenType.GEOMETRY: 'GEOMETRY'>, <TokenType.COLUMN: 'COLUMN'>, <TokenType.TINYTEXT: 'TINYTEXT'>, <TokenType.BINARY: 'BINARY'>, <TokenType.BOOLEAN: 'BOOLEAN'>, <TokenType.ROW: 'ROW'>, <TokenType.TEXT: 'TEXT'>, <TokenType.IPPREFIX: 'IPPREFIX'>, <TokenType.DICTIONARY: 'DICTIONARY'>, <TokenType.ISNULL: 'ISNULL'>, <TokenType.PERCENT: 'PERCENT'>, <TokenType.SCHEMA: 'SCHEMA'>, <TokenType.ENUM16: 'ENUM16'>, <TokenType.UTINYINT: 'UTINYINT'>, <TokenType.CURRENT_TIME: 'CURRENT_TIME'>, <TokenType.INDEX: 'INDEX'>, <TokenType.IPV4: 'IPV4'>, <TokenType.INT128: 'INT128'>, <TokenType.EXECUTE: 'EXECUTE'>, <TokenType.TABLE: 'TABLE'>, <TokenType.UNPIVOT: 'UNPIVOT'>, <TokenType.DECIMAL: 'DECIMAL'>, <TokenType.LONGTEXT: 'LONGTEXT'>, <TokenType.TIMESTAMP_MS: 'TIMESTAMP_MS'>, <TokenType.TINYBLOB: 'TINYBLOB'>, <TokenType.CONSTRAINT: 'CONSTRAINT'>, <TokenType.NUMRANGE: 'NUMRANGE'>, <TokenType.SETTINGS: 'SETTINGS'>, <TokenType.NULLABLE: 'NULLABLE'>, <TokenType.IMAGE: 'IMAGE'>, <TokenType.TSTZMULTIRANGE: 'TSTZMULTIRANGE'>, <TokenType.LIST: 'LIST'>, <TokenType.INT4MULTIRANGE: 'INT4MULTIRANGE'>, <TokenType.SEQUENCE: 'SEQUENCE'>, <TokenType.ALL: 'ALL'>, <TokenType.MAP: 'MAP'>, <TokenType.OPERATOR: 'OPERATOR'>, <TokenType.LOWCARDINALITY: 'LOWCARDINALITY'>, <TokenType.UNKNOWN: 'UNKNOWN'>, <TokenType.NULL: 'NULL'>, <TokenType.SEMI: 'SEMI'>, <TokenType.ROLLUP: 'ROLLUP'>, <TokenType.INT4RANGE: 'INT4RANGE'>, <TokenType.TDIGEST: 'TDIGEST'>, <TokenType.CURRENT_TIMESTAMP: 'CURRENT_TIMESTAMP'>, <TokenType.MONEY: 'MONEY'>, <TokenType.TIMESTAMP_NS: 'TIMESTAMP_NS'>, <TokenType.STRUCT: 'STRUCT'>, <TokenType.SMALLINT: 'SMALLINT'>, <TokenType.VIEW: 'VIEW'>, <TokenType.SMALLMONEY: 'SMALLMONEY'>, <TokenType.SIMPLEAGGREGATEFUNCTION: 'SIMPLEAGGREGATEFUNCTION'>, <TokenType.VARCHAR: 'VARCHAR'>, <TokenType.COLLATE: 'COLLATE'>, <TokenType.NEXT: 'NEXT'>, <TokenType.PARTITION: 'PARTITION'>, <TokenType.OVERLAPS: 'OVERLAPS'>, <TokenType.NCHAR: 'NCHAR'>, <TokenType.MEDIUMTEXT: 'MEDIUMTEXT'>, <TokenType.ORDINALITY: 'ORDINALITY'>, <TokenType.BPCHAR: 'BPCHAR'>, <TokenType.SUPER: 'SUPER'>, <TokenType.END: 'END'>, <TokenType.USMALLINT: 'USMALLINT'>, <TokenType.TSTZRANGE: 'TSTZRANGE'>, <TokenType.COMMENT: 'COMMENT'>, <TokenType.UPDATE: 'UPDATE'>, <TokenType.EXISTS: 'EXISTS'>, <TokenType.CHAR: 'CHAR'>, <TokenType.WAREHOUSE: 'WAREHOUSE'>, <TokenType.ESCAPE: 'ESCAPE'>, <TokenType.LONGBLOB: 'LONGBLOB'>, <TokenType.CURRENT_USER: 'CURRENT_USER'>, <TokenType.UINT: 'UINT'>, <TokenType.VARIANT: 'VARIANT'>, <TokenType.ENUM8: 'ENUM8'>, <TokenType.BIGINT: 'BIGINT'>, <TokenType.TOP: 'TOP'>, <TokenType.TIMESTAMP: 'TIMESTAMP'>, <TokenType.SOME: 'SOME'>, <TokenType.UMEDIUMINT: 'UMEDIUMINT'>, <TokenType.DATEMULTIRANGE: 'DATEMULTIRANGE'>, <TokenType.USERDEFINED: 'USERDEFINED'>, <TokenType.DESC: 'DESC'>, <TokenType.NUMMULTIRANGE: 'NUMMULTIRANGE'>, <TokenType.RANGE: 'RANGE'>, <TokenType.FIRST: 'FIRST'>, <TokenType.UUID: 'UUID'>, <TokenType.DESCRIBE: 'DESCRIBE'>, <TokenType.MODEL: 'MODEL'>, <TokenType.AGGREGATEFUNCTION: 'AGGREGATEFUNCTION'>, <TokenType.MERGE: 'MERGE'>, <TokenType.INT8MULTIRANGE: 'INT8MULTIRANGE'>, <TokenType.RECURSIVE: 'RECURSIVE'>, <TokenType.VAR: 'VAR'>, <TokenType.NVARCHAR: 'NVARCHAR'>, <TokenType.NAME: 'NAME'>, <TokenType.JSON: 'JSON'>, <TokenType.BEGIN: 'BEGIN'>, <TokenType.IS: 'IS'>, <TokenType.TSMULTIRANGE: 'TSMULTIRANGE'>, <TokenType.YEAR: 'YEAR'>, <TokenType.XML: 'XML'>, <TokenType.OBJECT: 'OBJECT'>, <TokenType.DATE32: 'DATE32'>, <TokenType.DATETIME64: 'DATETIME64'>, <TokenType.DATETIME: 'DATETIME'>, <TokenType.JSONB: 'JSONB'>, <TokenType.PIVOT: 'PIVOT'>, <TokenType.BIT: 'BIT'>, <TokenType.FORMAT: 'FORMAT'>, <TokenType.PRAGMA: 'PRAGMA'>, <TokenType.FOREIGN_KEY: 'FOREIGN_KEY'>, <TokenType.UNIQUEIDENTIFIER: 'UNIQUEIDENTIFIER'>, <TokenType.TSRANGE: 'TSRANGE'>, <TokenType.LOAD: 'LOAD'>, <TokenType.BIGSERIAL: 'BIGSERIAL'>, <TokenType.VARBINARY: 'VARBINARY'>, <TokenType.UINT256: 'UINT256'>, <TokenType.DIV: 'DIV'>, <TokenType.ARRAY: 'ARRAY'>, <TokenType.SHOW: 'SHOW'>, <TokenType.ASC: 'ASC'>, <TokenType.INT: 'INT'>, <TokenType.IPADDRESS: 'IPADDRESS'>, <TokenType.INET: 'INET'>, <TokenType.INT8RANGE: 'INT8RANGE'>, <TokenType.SMALLSERIAL: 'SMALLSERIAL'>, <TokenType.DEFAULT: 'DEFAULT'>, <TokenType.ANY: 'ANY'>, <TokenType.HLLSKETCH: 'HLLSKETCH'>, <TokenType.VOLATILE: 'VOLATILE'>, <TokenType.TIMESTAMPTZ: 'TIMESTAMPTZ'>, <TokenType.FIXEDSTRING: 'FIXEDSTRING'>, <TokenType.TRUNCATE: 'TRUNCATE'>, <TokenType.DOUBLE: 'DOUBLE'>, <TokenType.UBIGINT: 'UBIGINT'>, <TokenType.FUNCTION: 'FUNCTION'>, <TokenType.UDECIMAL: 'UDECIMAL'>, <TokenType.REPLACE: 'REPLACE'>, <TokenType.OVERWRITE: 'OVERWRITE'>, <TokenType.REFERENCES: 'REFERENCES'>, <TokenType.HSTORE: 'HSTORE'>, <TokenType.DATABASE: 'DATABASE'>, <TokenType.FALSE: 'FALSE'>, <TokenType.UNNEST: 'UNNEST'>, <TokenType.ENUM: 'ENUM'>, <TokenType.REFRESH: 'REFRESH'>, <TokenType.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, <TokenType.COMMAND: 'COMMAND'>, <TokenType.INTERVAL: 'INTERVAL'>, <TokenType.CURRENT_DATE: 'CURRENT_DATE'>, <TokenType.BIGDECIMAL: 'BIGDECIMAL'>, <TokenType.UNIQUE: 'UNIQUE'>, <TokenType.PSEUDO_TYPE: 'PSEUDO_TYPE'>, <TokenType.MEDIUMBLOB: 'MEDIUMBLOB'>, <TokenType.AUTO_INCREMENT: 'AUTO_INCREMENT'>, <TokenType.TIMETZ: 'TIMETZ'>, <TokenType.SET: 'SET'>, <TokenType.SERIAL: 'SERIAL'>, <TokenType.DATE: 'DATE'>, <TokenType.STORAGE_INTEGRATION: 'STORAGE_INTEGRATION'>, <TokenType.PROCEDURE: 'PROCEDURE'>}
RANGE_PARSERS =
{<TokenType.BETWEEN: 'BETWEEN'>: <function Parser.<lambda>>, <TokenType.GLOB: 'GLOB'>: <function binary_range_parser.<locals>._parse_binary_range>, <TokenType.ILIKE: 'ILIKE'>: <function binary_range_parser.<locals>._parse_binary_range>, <TokenType.IN: 'IN'>: <function Parser.<lambda>>, <TokenType.IRLIKE: 'IRLIKE'>: <function binary_range_parser.<locals>._parse_binary_range>, <TokenType.IS: 'IS'>: <function Parser.<lambda>>, <TokenType.LIKE: 'LIKE'>: <function binary_range_parser.<locals>._parse_binary_range>, <TokenType.OVERLAPS: 'OVERLAPS'>: <function binary_range_parser.<locals>._parse_binary_range>, <TokenType.RLIKE: 'RLIKE'>: <function binary_range_parser.<locals>._parse_binary_range>, <TokenType.SIMILAR_TO: 'SIMILAR_TO'>: <function binary_range_parser.<locals>._parse_binary_range>, <TokenType.FOR: 'FOR'>: <function Parser.<lambda>>, <TokenType.MEMBER_OF: 'MEMBER_OF'>: <function MySQL.Parser.<lambda>>}
FUNCTIONS =
{'ABS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Abs'>>, 'ADD_MONTHS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.AddMonths'>>, 'ANONYMOUS_AGG_FUNC': <bound method Func.from_arg_list of <class 'sqlglot.expressions.AnonymousAggFunc'>>, 'ANY_VALUE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.AnyValue'>>, 'APPROX_DISTINCT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ApproxDistinct'>>, 'APPROX_COUNT_DISTINCT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ApproxDistinct'>>, 'APPROX_QUANTILE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ApproxQuantile'>>, 'APPROX_TOP_K': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ApproxTopK'>>, 'ARG_MAX': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArgMax'>>, 'ARGMAX': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArgMax'>>, 'MAX_BY': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArgMax'>>, 'ARG_MIN': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArgMin'>>, 'ARGMIN': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArgMin'>>, 'MIN_BY': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArgMin'>>, 'ARRAY': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Array'>>, 'ARRAY_AGG': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArrayAgg'>>, 'ARRAY_ALL': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArrayAll'>>, 'ARRAY_ANY': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArrayAny'>>, 'ARRAY_CONCAT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArrayConcat'>>, 'ARRAY_CAT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArrayConcat'>>, 'ARRAY_CONSTRUCT_COMPACT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArrayConstructCompact'>>, 'ARRAY_CONTAINS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArrayContains'>>, 'ARRAY_HAS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArrayContains'>>, 'ARRAY_CONTAINS_ALL': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArrayContainsAll'>>, 'ARRAY_HAS_ALL': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArrayContainsAll'>>, 'FILTER': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArrayFilter'>>, 'ARRAY_FILTER': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArrayFilter'>>, 'ARRAY_OVERLAPS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArrayOverlaps'>>, 'ARRAY_SIZE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArraySize'>>, 'ARRAY_LENGTH': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArraySize'>>, 'ARRAY_SORT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArraySort'>>, 'ARRAY_SUM': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArraySum'>>, 'ARRAY_TO_STRING': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArrayToString'>>, 'ARRAY_JOIN': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArrayToString'>>, 'ARRAY_UNION_AGG': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArrayUnionAgg'>>, 'ARRAY_UNIQUE_AGG': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArrayUniqueAgg'>>, 'AVG': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Avg'>>, 'CASE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Case'>>, 'CAST': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Cast'>>, 'CAST_TO_STR_TYPE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CastToStrType'>>, 'CBRT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Cbrt'>>, 'CEIL': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Ceil'>>, 'CEILING': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Ceil'>>, 'CHR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Chr'>>, 'CHAR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Chr'>>, 'COALESCE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Coalesce'>>, 'IFNULL': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Coalesce'>>, 'NVL': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Coalesce'>>, 'COLLATE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Collate'>>, 'COMBINED_AGG_FUNC': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CombinedAggFunc'>>, 'COMBINED_PARAMETERIZED_AGG': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CombinedParameterizedAgg'>>, 'CONCAT': <function Parser.<lambda>>, 'CONCAT_WS': <function Parser.<lambda>>, 'CONNECT_BY_ROOT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ConnectByRoot'>>, 'CONVERT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Convert'>>, 'CORR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Corr'>>, 'COUNT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Count'>>, 'COUNT_IF': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CountIf'>>, 'COUNTIF': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CountIf'>>, 'COVAR_POP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CovarPop'>>, 'COVAR_SAMP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CovarSamp'>>, 'CURRENT_DATE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CurrentDate'>>, 'CURRENT_DATETIME': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CurrentDatetime'>>, 'CURRENT_TIME': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CurrentTime'>>, 'CURRENT_TIMESTAMP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CurrentTimestamp'>>, 'CURRENT_USER': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CurrentUser'>>, 'DATE': <function MySQL.Parser.<lambda>>, 'DATE_ADD': <function build_date_delta_with_interval.<locals>._builder>, 'DATEDIFF': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DateDiff'>>, 'DATE_DIFF': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DateDiff'>>, 'DATE_FROM_PARTS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DateFromParts'>>, 'DATEFROMPARTS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DateFromParts'>>, 'DATE_STR_TO_DATE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DateStrToDate'>>, 'DATE_SUB': <function build_date_delta_with_interval.<locals>._builder>, 'DATE_TO_DATE_STR': <function Parser.<lambda>>, 'DATE_TO_DI': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DateToDi'>>, 'DATE_TRUNC': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DateTrunc'>>, 'DATETIME': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Datetime'>>, 'DATETIME_ADD': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DatetimeAdd'>>, 'DATETIME_DIFF': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DatetimeDiff'>>, 'DATETIME_SUB': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DatetimeSub'>>, 'DATETIME_TRUNC': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DatetimeTrunc'>>, 'DAY': <function MySQL.Parser.<lambda>>, 'DAY_OF_MONTH': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DayOfMonth'>>, 'DAYOFMONTH': <function MySQL.Parser.<lambda>>, 'DAY_OF_WEEK': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DayOfWeek'>>, 'DAYOFWEEK': <function MySQL.Parser.<lambda>>, 'DAY_OF_YEAR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DayOfYear'>>, 'DAYOFYEAR': <function MySQL.Parser.<lambda>>, 'DECODE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Decode'>>, 'DI_TO_DATE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DiToDate'>>, 'ENCODE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Encode'>>, 'EXP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Exp'>>, 'EXPLODE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Explode'>>, 'EXPLODE_OUTER': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ExplodeOuter'>>, 'EXTRACT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Extract'>>, 'FIRST': <bound method Func.from_arg_list of <class 'sqlglot.expressions.First'>>, 'FIRST_VALUE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.FirstValue'>>, 'FLATTEN': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Flatten'>>, 'FLOOR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Floor'>>, 'FROM_BASE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.FromBase'>>, 'FROM_BASE64': <bound method Func.from_arg_list of <class 'sqlglot.expressions.FromBase64'>>, 'GAP_FILL': <bound method Func.from_arg_list of <class 'sqlglot.expressions.GapFill'>>, 'GENERATE_DATE_ARRAY': <bound method Func.from_arg_list of <class 'sqlglot.expressions.GenerateDateArray'>>, 'GENERATE_SERIES': <bound method Func.from_arg_list of <class 'sqlglot.expressions.GenerateSeries'>>, 'GREATEST': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Greatest'>>, 'GROUP_CONCAT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.GroupConcat'>>, 'HEX': <function build_hex>, 'HLL': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Hll'>>, 'IF': <bound method Func.from_arg_list of <class 'sqlglot.expressions.If'>>, 'IIF': <bound method Func.from_arg_list of <class 'sqlglot.expressions.If'>>, 'INITCAP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Initcap'>>, 'IS_INF': <bound method Func.from_arg_list of <class 'sqlglot.expressions.IsInf'>>, 'ISINF': <bound method Func.from_arg_list of <class 'sqlglot.expressions.IsInf'>>, 'IS_NAN': <bound method Func.from_arg_list of <class 'sqlglot.expressions.IsNan'>>, 'ISNAN': <bound method Func.from_arg_list of <class 'sqlglot.expressions.IsNan'>>, 'J_S_O_N_ARRAY': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONArray'>>, 'J_S_O_N_ARRAY_AGG': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONArrayAgg'>>, 'JSON_ARRAY_CONTAINS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONArrayContains'>>, 'JSONB_CONTAINS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONBContains'>>, 'JSONB_EXTRACT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONBExtract'>>, 'JSONB_EXTRACT_SCALAR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONBExtractScalar'>>, 'JSON_EXTRACT': <function build_extract_json_with_path.<locals>._builder>, 'JSON_EXTRACT_SCALAR': <function build_extract_json_with_path.<locals>._builder>, 'JSON_FORMAT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONFormat'>>, 'J_S_O_N_OBJECT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONObject'>>, 'J_S_O_N_OBJECT_AGG': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONObjectAgg'>>, 'J_S_O_N_TABLE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONTable'>>, 'LAG': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Lag'>>, 'LAST': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Last'>>, 'LAST_DAY': <bound method Func.from_arg_list of <class 'sqlglot.expressions.LastDay'>>, 'LAST_DAY_OF_MONTH': <bound method Func.from_arg_list of <class 'sqlglot.expressions.LastDay'>>, 'LAST_VALUE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.LastValue'>>, 'LEAD': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Lead'>>, 'LEAST': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Least'>>, 'LEFT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Left'>>, 'LENGTH': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Length'>>, 'LEN': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Length'>>, 'LEVENSHTEIN': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Levenshtein'>>, 'LIST': <bound method Func.from_arg_list of <class 'sqlglot.expressions.List'>>, 'LN': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Ln'>>, 'LOG': <function build_logarithm>, 'LOGICAL_AND': <bound method Func.from_arg_list of <class 'sqlglot.expressions.LogicalAnd'>>, 'BOOL_AND': <bound method Func.from_arg_list of <class 'sqlglot.expressions.LogicalAnd'>>, 'BOOLAND_AGG': <bound method Func.from_arg_list of <class 'sqlglot.expressions.LogicalAnd'>>, 'LOGICAL_OR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.LogicalOr'>>, 'BOOL_OR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.LogicalOr'>>, 'BOOLOR_AGG': <bound method Func.from_arg_list of <class 'sqlglot.expressions.LogicalOr'>>, 'LOWER': <function build_lower>, 'LCASE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Lower'>>, 'LOWER_HEX': <bound method Func.from_arg_list of <class 'sqlglot.expressions.LowerHex'>>, 'MD5': <bound method Func.from_arg_list of <class 'sqlglot.expressions.MD5'>>, 'MD5_DIGEST': <bound method Func.from_arg_list of <class 'sqlglot.expressions.MD5Digest'>>, 'MAP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Map'>>, 'MAP_FROM_ENTRIES': <bound method Func.from_arg_list of <class 'sqlglot.expressions.MapFromEntries'>>, 'MATCH_AGAINST': <bound method Func.from_arg_list of <class 'sqlglot.expressions.MatchAgainst'>>, 'MAX': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Max'>>, 'MIN': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Min'>>, 'MONTH': <function MySQL.Parser.<lambda>>, 'MONTHS_BETWEEN': <bound method Func.from_arg_list of <class 'sqlglot.expressions.MonthsBetween'>>, 'NEXT_VALUE_FOR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.NextValueFor'>>, 'NTH_VALUE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.NthValue'>>, 'NULLIF': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Nullif'>>, 'NUMBER_TO_STR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.NumberToStr'>>, 'NVL2': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Nvl2'>>, 'OBJECT_INSERT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ObjectInsert'>>, 'OPEN_J_S_O_N': <bound method Func.from_arg_list of <class 'sqlglot.expressions.OpenJSON'>>, 'PAD': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Pad'>>, 'PARAMETERIZED_AGG': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ParameterizedAgg'>>, 'PARSE_JSON': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ParseJSON'>>, 'JSON_PARSE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ParseJSON'>>, 'PERCENTILE_CONT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.PercentileCont'>>, 'PERCENTILE_DISC': <bound method Func.from_arg_list of <class 'sqlglot.expressions.PercentileDisc'>>, 'POSEXPLODE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Posexplode'>>, 'POSEXPLODE_OUTER': <bound method Func.from_arg_list of <class 'sqlglot.expressions.PosexplodeOuter'>>, 'POWER': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Pow'>>, 'POW': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Pow'>>, 'PREDICT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Predict'>>, 'QUANTILE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Quantile'>>, 'QUARTER': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Quarter'>>, 'RAND': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Rand'>>, 'RANDOM': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Rand'>>, 'RANDN': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Randn'>>, 'RANGE_N': <bound method Func.from_arg_list of <class 'sqlglot.expressions.RangeN'>>, 'READ_CSV': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ReadCSV'>>, 'REDUCE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Reduce'>>, 'REGEXP_EXTRACT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.RegexpExtract'>>, 'REGEXP_I_LIKE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.RegexpILike'>>, 'REGEXP_LIKE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.RegexpLike'>>, 'REGEXP_REPLACE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.RegexpReplace'>>, 'REGEXP_SPLIT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.RegexpSplit'>>, 'REPEAT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Repeat'>>, 'RIGHT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Right'>>, 'ROUND': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Round'>>, 'ROW_NUMBER': <bound method Func.from_arg_list of <class 'sqlglot.expressions.RowNumber'>>, 'SHA': <bound method Func.from_arg_list of <class 'sqlglot.expressions.SHA'>>, 'SHA1': <bound method Func.from_arg_list of <class 'sqlglot.expressions.SHA'>>, 'SHA2': <bound method Func.from_arg_list of <class 'sqlglot.expressions.SHA2'>>, 'SAFE_DIVIDE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.SafeDivide'>>, 'SIGN': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Sign'>>, 'SIGNUM': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Sign'>>, 'SORT_ARRAY': <bound method Func.from_arg_list of <class 'sqlglot.expressions.SortArray'>>, 'SPLIT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Split'>>, 'SQRT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Sqrt'>>, 'STANDARD_HASH': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StandardHash'>>, 'STAR_MAP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StarMap'>>, 'STARTS_WITH': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StartsWith'>>, 'STARTSWITH': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StartsWith'>>, 'STDDEV': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Stddev'>>, 'STDEV': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Stddev'>>, 'STDDEV_POP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StddevPop'>>, 'STDDEV_SAMP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StddevSamp'>>, 'STR_POSITION': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StrPosition'>>, 'STR_TO_DATE': <function _str_to_date>, 'STR_TO_MAP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StrToMap'>>, 'STR_TO_TIME': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StrToTime'>>, 'STR_TO_UNIX': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StrToUnix'>>, 'STRING_TO_ARRAY': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StringToArray'>>, 'SPLIT_BY_STRING': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StringToArray'>>, 'STRUCT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Struct'>>, 'STRUCT_EXTRACT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StructExtract'>>, 'STUFF': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Stuff'>>, 'INSERT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Stuff'>>, 'SUBSTRING': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Substring'>>, 'SUM': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Sum'>>, 'TIME': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Time'>>, 'TIME_ADD': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimeAdd'>>, 'TIME_DIFF': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimeDiff'>>, 'TIME_FROM_PARTS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimeFromParts'>>, 'TIMEFROMPARTS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimeFromParts'>>, 'TIME_STR_TO_DATE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimeStrToDate'>>, 'TIME_STR_TO_TIME': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimeStrToTime'>>, 'TIME_STR_TO_UNIX': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimeStrToUnix'>>, 'TIME_SUB': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimeSub'>>, 'TIME_TO_STR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimeToStr'>>, 'TIME_TO_TIME_STR': <function Parser.<lambda>>, 'TIME_TO_UNIX': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimeToUnix'>>, 'TIME_TRUNC': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimeTrunc'>>, 'TIMESTAMP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Timestamp'>>, 'TIMESTAMP_ADD': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimestampAdd'>>, 'TIMESTAMPDIFF': <function build_date_delta.<locals>._builder>, 'TIMESTAMP_DIFF': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimestampDiff'>>, 'TIMESTAMP_FROM_PARTS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimestampFromParts'>>, 'TIMESTAMPFROMPARTS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimestampFromParts'>>, 'TIMESTAMP_SUB': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimestampSub'>>, 'TIMESTAMP_TRUNC': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimestampTrunc'>>, 'TO_ARRAY': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ToArray'>>, 'TO_BASE64': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ToBase64'>>, 'TO_CHAR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ToChar'>>, 'TO_DAYS': <function MySQL.Parser.<lambda>>, 'TO_MAP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ToMap'>>, 'TO_NUMBER': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ToNumber'>>, 'TRANSFORM': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Transform'>>, 'TRIM': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Trim'>>, 'TRY': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Try'>>, 'TRY_CAST': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TryCast'>>, 'TS_OR_DI_TO_DI': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TsOrDiToDi'>>, 'TS_OR_DS_ADD': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TsOrDsAdd'>>, 'TS_OR_DS_DIFF': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TsOrDsDiff'>>, 'TS_OR_DS_TO_DATE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TsOrDsToDate'>>, 'TS_OR_DS_TO_DATE_STR': <function Parser.<lambda>>, 'TS_OR_DS_TO_TIME': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TsOrDsToTime'>>, 'TS_OR_DS_TO_TIMESTAMP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TsOrDsToTimestamp'>>, 'UNHEX': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Unhex'>>, 'UNIX_DATE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.UnixDate'>>, 'UNIX_TO_STR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.UnixToStr'>>, 'UNIX_TO_TIME': <bound method Func.from_arg_list of <class 'sqlglot.expressions.UnixToTime'>>, 'UNIX_TO_TIME_STR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.UnixToTimeStr'>>, 'UNNEST': <function Parser.<lambda>>, 'UPPER': <function build_upper>, 'UCASE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Upper'>>, 'VAR_MAP': <function build_var_map>, 'VARIANCE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Variance'>>, 'VARIANCE_SAMP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Variance'>>, 'VAR_SAMP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Variance'>>, 'VARIANCE_POP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.VariancePop'>>, 'VAR_POP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.VariancePop'>>, 'WEEK': <function MySQL.Parser.<lambda>>, 'WEEK_OF_YEAR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.WeekOfYear'>>, 'WEEKOFYEAR': <function MySQL.Parser.<lambda>>, 'WHEN': <bound method Func.from_arg_list of <class 'sqlglot.expressions.When'>>, 'X_M_L_TABLE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.XMLTable'>>, 'XOR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Xor'>>, 'YEAR': <function MySQL.Parser.<lambda>>, 'GLOB': <function Parser.<lambda>>, 'JSON_EXTRACT_PATH_TEXT': <function build_extract_json_with_path.<locals>._builder>, 'LIKE': <function build_like>, 'LOG2': <function Parser.<lambda>>, 'LOG10': <function Parser.<lambda>>, 'LPAD': <function Parser.<lambda>>, 'LEFTPAD': <function Parser.<lambda>>, 'MOD': <function build_mod>, 'RPAD': <function Parser.<lambda>>, 'RIGHTPAD': <function Parser.<lambda>>, 'SCOPE_RESOLUTION': <function Parser.<lambda>>, 'TO_HEX': <function build_hex>, 'DATE_FORMAT': <function build_formatted_time.<locals>._builder>, 'INSTR': <function MySQL.Parser.<lambda>>, 'FROM_UNIXTIME': <function build_formatted_time.<locals>._builder>, 'ISNULL': <function isnull_to_is_null>, 'LOCATE': <function locate_to_strposition>, 'MAKETIME': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimeFromParts'>>, 'MONTHNAME': <function MySQL.Parser.<lambda>>}
FUNCTION_PARSERS =
{'CAST': <function Parser.<lambda>>, 'CONVERT': <function Parser.<lambda>>, 'DECODE': <function Parser.<lambda>>, 'EXTRACT': <function Parser.<lambda>>, 'GAP_FILL': <function Parser.<lambda>>, 'JSON_OBJECT': <function Parser.<lambda>>, 'JSON_OBJECTAGG': <function Parser.<lambda>>, 'JSON_TABLE': <function Parser.<lambda>>, 'MATCH': <function Parser.<lambda>>, 'OPENJSON': <function Parser.<lambda>>, 'POSITION': <function Parser.<lambda>>, 'PREDICT': <function Parser.<lambda>>, 'SAFE_CAST': <function Parser.<lambda>>, 'STRING_AGG': <function Parser.<lambda>>, 'SUBSTRING': <function Parser.<lambda>>, 'TRIM': <function Parser.<lambda>>, 'TRY_CAST': <function Parser.<lambda>>, 'TRY_CONVERT': <function Parser.<lambda>>, 'CHAR': <function MySQL.Parser.<lambda>>, 'GROUP_CONCAT': <function MySQL.Parser.<lambda>>, 'VALUES': <function MySQL.Parser.<lambda>>}
STATEMENT_PARSERS =
{<TokenType.ALTER: 'ALTER'>: <function Parser.<lambda>>, <TokenType.BEGIN: 'BEGIN'>: <function Parser.<lambda>>, <TokenType.CACHE: 'CACHE'>: <function Parser.<lambda>>, <TokenType.COMMENT: 'COMMENT'>: <function Parser.<lambda>>, <TokenType.COMMIT: 'COMMIT'>: <function Parser.<lambda>>, <TokenType.COPY: 'COPY'>: <function Parser.<lambda>>, <TokenType.CREATE: 'CREATE'>: <function Parser.<lambda>>, <TokenType.DELETE: 'DELETE'>: <function Parser.<lambda>>, <TokenType.DESC: 'DESC'>: <function Parser.<lambda>>, <TokenType.DESCRIBE: 'DESCRIBE'>: <function Parser.<lambda>>, <TokenType.DROP: 'DROP'>: <function Parser.<lambda>>, <TokenType.INSERT: 'INSERT'>: <function Parser.<lambda>>, <TokenType.KILL: 'KILL'>: <function Parser.<lambda>>, <TokenType.LOAD: 'LOAD'>: <function Parser.<lambda>>, <TokenType.MERGE: 'MERGE'>: <function Parser.<lambda>>, <TokenType.PIVOT: 'PIVOT'>: <function Parser.<lambda>>, <TokenType.PRAGMA: 'PRAGMA'>: <function Parser.<lambda>>, <TokenType.REFRESH: 'REFRESH'>: <function Parser.<lambda>>, <TokenType.ROLLBACK: 'ROLLBACK'>: <function Parser.<lambda>>, <TokenType.SET: 'SET'>: <function Parser.<lambda>>, <TokenType.TRUNCATE: 'TRUNCATE'>: <function Parser.<lambda>>, <TokenType.UNCACHE: 'UNCACHE'>: <function Parser.<lambda>>, <TokenType.UPDATE: 'UPDATE'>: <function Parser.<lambda>>, <TokenType.USE: 'USE'>: <function Parser.<lambda>>, <TokenType.SEMICOLON: 'SEMICOLON'>: <function Parser.<lambda>>, <TokenType.SHOW: 'SHOW'>: <function MySQL.Parser.<lambda>>}
SHOW_PARSERS =
{'BINARY LOGS': <function _show_parser.<locals>._parse>, 'MASTER LOGS': <function _show_parser.<locals>._parse>, 'BINLOG EVENTS': <function _show_parser.<locals>._parse>, 'CHARACTER SET': <function _show_parser.<locals>._parse>, 'CHARSET': <function _show_parser.<locals>._parse>, 'COLLATION': <function _show_parser.<locals>._parse>, 'FULL COLUMNS': <function _show_parser.<locals>._parse>, 'COLUMNS': <function _show_parser.<locals>._parse>, 'CREATE DATABASE': <function _show_parser.<locals>._parse>, 'CREATE EVENT': <function _show_parser.<locals>._parse>, 'CREATE FUNCTION': <function _show_parser.<locals>._parse>, 'CREATE PROCEDURE': <function _show_parser.<locals>._parse>, 'CREATE TABLE': <function _show_parser.<locals>._parse>, 'CREATE TRIGGER': <function _show_parser.<locals>._parse>, 'CREATE VIEW': <function _show_parser.<locals>._parse>, 'DATABASES': <function _show_parser.<locals>._parse>, 'SCHEMAS': <function _show_parser.<locals>._parse>, 'ENGINE': <function _show_parser.<locals>._parse>, 'STORAGE ENGINES': <function _show_parser.<locals>._parse>, 'ENGINES': <function _show_parser.<locals>._parse>, 'ERRORS': <function _show_parser.<locals>._parse>, 'EVENTS': <function _show_parser.<locals>._parse>, 'FUNCTION CODE': <function _show_parser.<locals>._parse>, 'FUNCTION STATUS': <function _show_parser.<locals>._parse>, 'GRANTS': <function _show_parser.<locals>._parse>, 'INDEX': <function _show_parser.<locals>._parse>, 'MASTER STATUS': <function _show_parser.<locals>._parse>, 'OPEN TABLES': <function _show_parser.<locals>._parse>, 'PLUGINS': <function _show_parser.<locals>._parse>, 'PROCEDURE CODE': <function _show_parser.<locals>._parse>, 'PROCEDURE STATUS': <function _show_parser.<locals>._parse>, 'PRIVILEGES': <function _show_parser.<locals>._parse>, 'FULL PROCESSLIST': <function _show_parser.<locals>._parse>, 'PROCESSLIST': <function _show_parser.<locals>._parse>, 'PROFILE': <function _show_parser.<locals>._parse>, 'PROFILES': <function _show_parser.<locals>._parse>, 'RELAYLOG EVENTS': <function _show_parser.<locals>._parse>, 'REPLICAS': <function _show_parser.<locals>._parse>, 'SLAVE HOSTS': <function _show_parser.<locals>._parse>, 'REPLICA STATUS': <function _show_parser.<locals>._parse>, 'SLAVE STATUS': <function _show_parser.<locals>._parse>, 'GLOBAL STATUS': <function _show_parser.<locals>._parse>, 'SESSION STATUS': <function _show_parser.<locals>._parse>, 'STATUS': <function _show_parser.<locals>._parse>, 'TABLE STATUS': <function _show_parser.<locals>._parse>, 'FULL TABLES': <function _show_parser.<locals>._parse>, 'TABLES': <function _show_parser.<locals>._parse>, 'TRIGGERS': <function _show_parser.<locals>._parse>, 'GLOBAL VARIABLES': <function _show_parser.<locals>._parse>, 'SESSION VARIABLES': <function _show_parser.<locals>._parse>, 'VARIABLES': <function _show_parser.<locals>._parse>, 'WARNINGS': <function _show_parser.<locals>._parse>}
PROPERTY_PARSERS =
{'ALLOWED_VALUES': <function Parser.<lambda>>, 'ALGORITHM': <function Parser.<lambda>>, 'AUTO': <function Parser.<lambda>>, 'AUTO_INCREMENT': <function Parser.<lambda>>, 'BACKUP': <function Parser.<lambda>>, 'BLOCKCOMPRESSION': <function Parser.<lambda>>, 'CHARSET': <function Parser.<lambda>>, 'CHARACTER SET': <function Parser.<lambda>>, 'CHECKSUM': <function Parser.<lambda>>, 'CLUSTER BY': <function Parser.<lambda>>, 'CLUSTERED': <function Parser.<lambda>>, 'COLLATE': <function Parser.<lambda>>, 'COMMENT': <function Parser.<lambda>>, 'CONTAINS': <function Parser.<lambda>>, 'COPY': <function Parser.<lambda>>, 'DATABLOCKSIZE': <function Parser.<lambda>>, 'DATA_DELETION': <function Parser.<lambda>>, 'DEFINER': <function Parser.<lambda>>, 'DETERMINISTIC': <function Parser.<lambda>>, 'DYNAMIC': <function Parser.<lambda>>, 'DISTKEY': <function Parser.<lambda>>, 'DISTSTYLE': <function Parser.<lambda>>, 'ENGINE': <function Parser.<lambda>>, 'EXECUTE': <function Parser.<lambda>>, 'EXTERNAL': <function Parser.<lambda>>, 'FALLBACK': <function Parser.<lambda>>, 'FORMAT': <function Parser.<lambda>>, 'FREESPACE': <function Parser.<lambda>>, 'GLOBAL': <function Parser.<lambda>>, 'HEAP': <function Parser.<lambda>>, 'ICEBERG': <function Parser.<lambda>>, 'IMMUTABLE': <function Parser.<lambda>>, 'INHERITS': <function Parser.<lambda>>, 'INPUT': <function Parser.<lambda>>, 'JOURNAL': <function Parser.<lambda>>, 'LANGUAGE': <function Parser.<lambda>>, 'LAYOUT': <function Parser.<lambda>>, 'LIFETIME': <function Parser.<lambda>>, 'LIKE': <function Parser.<lambda>>, 'LOCATION': <function Parser.<lambda>>, 'LOCK': <function MySQL.Parser.<lambda>>, 'LOCKING': <function Parser.<lambda>>, 'LOG': <function Parser.<lambda>>, 'MATERIALIZED': <function Parser.<lambda>>, 'MERGEBLOCKRATIO': <function Parser.<lambda>>, 'MODIFIES': <function Parser.<lambda>>, 'MULTISET': <function Parser.<lambda>>, 'NO': <function Parser.<lambda>>, 'ON': <function Parser.<lambda>>, 'ORDER BY': <function Parser.<lambda>>, 'OUTPUT': <function Parser.<lambda>>, 'PARTITION': <function Parser.<lambda>>, 'PARTITION BY': <function Parser.<lambda>>, 'PARTITIONED BY': <function Parser.<lambda>>, 'PARTITIONED_BY': <function Parser.<lambda>>, 'PRIMARY KEY': <function Parser.<lambda>>, 'RANGE': <function Parser.<lambda>>, 'READS': <function Parser.<lambda>>, 'REMOTE': <function Parser.<lambda>>, 'RETURNS': <function Parser.<lambda>>, 'STRICT': <function Parser.<lambda>>, 'ROW': <function Parser.<lambda>>, 'ROW_FORMAT': <function Parser.<lambda>>, 'SAMPLE': <function Parser.<lambda>>, 'SECURE': <function Parser.<lambda>>, 'SET': <function Parser.<lambda>>, 'SETTINGS': <function Parser.<lambda>>, 'SHARING': <function Parser.<lambda>>, 'SORTKEY': <function Parser.<lambda>>, 'SOURCE': <function Parser.<lambda>>, 'STABLE': <function Parser.<lambda>>, 'STORED': <function Parser.<lambda>>, 'SYSTEM_VERSIONING': <function Parser.<lambda>>, 'TBLPROPERTIES': <function Parser.<lambda>>, 'TEMP': <function Parser.<lambda>>, 'TEMPORARY': <function Parser.<lambda>>, 'TO': <function Parser.<lambda>>, 'TRANSIENT': <function Parser.<lambda>>, 'TRANSFORM': <function Parser.<lambda>>, 'TTL': <function Parser.<lambda>>, 'USING': <function Parser.<lambda>>, 'UNLOGGED': <function Parser.<lambda>>, 'VOLATILE': <function Parser.<lambda>>, 'WITH': <function Parser.<lambda>>}
SET_PARSERS =
{'GLOBAL': <function Parser.<lambda>>, 'LOCAL': <function Parser.<lambda>>, 'SESSION': <function Parser.<lambda>>, 'TRANSACTION': <function Parser.<lambda>>, 'PERSIST': <function MySQL.Parser.<lambda>>, 'PERSIST_ONLY': <function MySQL.Parser.<lambda>>, 'CHARACTER SET': <function MySQL.Parser.<lambda>>, 'CHARSET': <function MySQL.Parser.<lambda>>, 'NAMES': <function MySQL.Parser.<lambda>>}
CONSTRAINT_PARSERS =
{'AUTOINCREMENT': <function Parser.<lambda>>, 'AUTO_INCREMENT': <function Parser.<lambda>>, 'CASESPECIFIC': <function Parser.<lambda>>, 'CHARACTER SET': <function Parser.<lambda>>, 'CHECK': <function Parser.<lambda>>, 'COLLATE': <function Parser.<lambda>>, 'COMMENT': <function Parser.<lambda>>, 'COMPRESS': <function Parser.<lambda>>, 'CLUSTERED': <function Parser.<lambda>>, 'NONCLUSTERED': <function Parser.<lambda>>, 'DEFAULT': <function Parser.<lambda>>, 'ENCODE': <function Parser.<lambda>>, 'EPHEMERAL': <function Parser.<lambda>>, 'EXCLUDE': <function Parser.<lambda>>, 'FOREIGN KEY': <function Parser.<lambda>>, 'FORMAT': <function Parser.<lambda>>, 'GENERATED': <function Parser.<lambda>>, 'IDENTITY': <function Parser.<lambda>>, 'INLINE': <function Parser.<lambda>>, 'LIKE': <function Parser.<lambda>>, 'NOT': <function Parser.<lambda>>, 'NULL': <function Parser.<lambda>>, 'ON': <function Parser.<lambda>>, 'PATH': <function Parser.<lambda>>, 'PERIOD': <function Parser.<lambda>>, 'PRIMARY KEY': <function Parser.<lambda>>, 'REFERENCES': <function Parser.<lambda>>, 'TITLE': <function Parser.<lambda>>, 'TTL': <function Parser.<lambda>>, 'UNIQUE': <function Parser.<lambda>>, 'UPPERCASE': <function Parser.<lambda>>, 'WITH': <function Parser.<lambda>>, 'FULLTEXT': <function MySQL.Parser.<lambda>>, 'INDEX': <function MySQL.Parser.<lambda>>, 'KEY': <function MySQL.Parser.<lambda>>, 'SPATIAL': <function MySQL.Parser.<lambda>>}
ALTER_PARSERS =
{'ADD': <function Parser.<lambda>>, 'ALTER': <function Parser.<lambda>>, 'CLUSTER BY': <function Parser.<lambda>>, 'DELETE': <function Parser.<lambda>>, 'DROP': <function Parser.<lambda>>, 'RENAME': <function Parser.<lambda>>, 'SET': <function Parser.<lambda>>, 'MODIFY': <function MySQL.Parser.<lambda>>}
SCHEMA_UNNAMED_CONSTRAINTS =
{'KEY', 'SPATIAL', 'CHECK', 'FOREIGN KEY', 'EXCLUDE', 'LIKE', 'UNIQUE', 'INDEX', 'FULLTEXT', 'PERIOD', 'PRIMARY KEY'}
PROFILE_TYPES: Dict[str, Sequence[Union[Sequence[str], str]]] =
{'ALL': (), 'CPU': (), 'IPC': (), 'MEMORY': (), 'SOURCE': (), 'SWAPS': (), 'BLOCK': ('IO',), 'CONTEXT': ('SWITCHES',), 'PAGE': ('FAULTS',)}
TYPE_TOKENS =
{<TokenType.TSTZRANGE: 'TSTZRANGE'>, <TokenType.TIMESTAMPNTZ: 'TIMESTAMPNTZ'>, <TokenType.CHAR: 'CHAR'>, <TokenType.MEDIUMINT: 'MEDIUMINT'>, <TokenType.DATERANGE: 'DATERANGE'>, <TokenType.LONGBLOB: 'LONGBLOB'>, <TokenType.UINT: 'UINT'>, <TokenType.VARIANT: 'VARIANT'>, <TokenType.ENUM8: 'ENUM8'>, <TokenType.BIGINT: 'BIGINT'>, <TokenType.GEOGRAPHY: 'GEOGRAPHY'>, <TokenType.TIMESTAMP: 'TIMESTAMP'>, <TokenType.UMEDIUMINT: 'UMEDIUMINT'>, <TokenType.DATEMULTIRANGE: 'DATEMULTIRANGE'>, <TokenType.USERDEFINED: 'USERDEFINED'>, <TokenType.TIME: 'TIME'>, <TokenType.INT256: 'INT256'>, <TokenType.FLOAT: 'FLOAT'>, <TokenType.NUMMULTIRANGE: 'NUMMULTIRANGE'>, <TokenType.UUID: 'UUID'>, <TokenType.TINYINT: 'TINYINT'>, <TokenType.TIMESTAMP_S: 'TIMESTAMP_S'>, <TokenType.AGGREGATEFUNCTION: 'AGGREGATEFUNCTION'>, <TokenType.VECTOR: 'VECTOR'>, <TokenType.OBJECT_IDENTIFIER: 'OBJECT_IDENTIFIER'>, <TokenType.NESTED: 'NESTED'>, <TokenType.UINT128: 'UINT128'>, <TokenType.ROWVERSION: 'ROWVERSION'>, <TokenType.IPV6: 'IPV6'>, <TokenType.GEOMETRY: 'GEOMETRY'>, <TokenType.INT8MULTIRANGE: 'INT8MULTIRANGE'>, <TokenType.NVARCHAR: 'NVARCHAR'>, <TokenType.NAME: 'NAME'>, <TokenType.TINYTEXT: 'TINYTEXT'>, <TokenType.BINARY: 'BINARY'>, <TokenType.JSON: 'JSON'>, <TokenType.BOOLEAN: 'BOOLEAN'>, <TokenType.TEXT: 'TEXT'>, <TokenType.IPPREFIX: 'IPPREFIX'>, <TokenType.TSMULTIRANGE: 'TSMULTIRANGE'>, <TokenType.YEAR: 'YEAR'>, <TokenType.XML: 'XML'>, <TokenType.OBJECT: 'OBJECT'>, <TokenType.ENUM16: 'ENUM16'>, <TokenType.DATE32: 'DATE32'>, <TokenType.UTINYINT: 'UTINYINT'>, <TokenType.DATETIME64: 'DATETIME64'>, <TokenType.DATETIME: 'DATETIME'>, <TokenType.JSONB: 'JSONB'>, <TokenType.BIT: 'BIT'>, <TokenType.IPV4: 'IPV4'>, <TokenType.INT128: 'INT128'>, <TokenType.DECIMAL: 'DECIMAL'>, <TokenType.UNIQUEIDENTIFIER: 'UNIQUEIDENTIFIER'>, <TokenType.TSRANGE: 'TSRANGE'>, <TokenType.LONGTEXT: 'LONGTEXT'>, <TokenType.TIMESTAMP_MS: 'TIMESTAMP_MS'>, <TokenType.BIGSERIAL: 'BIGSERIAL'>, <TokenType.TINYBLOB: 'TINYBLOB'>, <TokenType.VARBINARY: 'VARBINARY'>, <TokenType.NUMRANGE: 'NUMRANGE'>, <TokenType.NULLABLE: 'NULLABLE'>, <TokenType.UINT256: 'UINT256'>, <TokenType.ARRAY: 'ARRAY'>, <TokenType.IMAGE: 'IMAGE'>, <TokenType.TSTZMULTIRANGE: 'TSTZMULTIRANGE'>, <TokenType.LIST: 'LIST'>, <TokenType.INT4MULTIRANGE: 'INT4MULTIRANGE'>, <TokenType.MAP: 'MAP'>, <TokenType.INT: 'INT'>, <TokenType.IPADDRESS: 'IPADDRESS'>, <TokenType.LOWCARDINALITY: 'LOWCARDINALITY'>, <TokenType.UNKNOWN: 'UNKNOWN'>, <TokenType.NULL: 'NULL'>, <TokenType.INET: 'INET'>, <TokenType.INT8RANGE: 'INT8RANGE'>, <TokenType.SMALLSERIAL: 'SMALLSERIAL'>, <TokenType.HLLSKETCH: 'HLLSKETCH'>, <TokenType.TIMESTAMPTZ: 'TIMESTAMPTZ'>, <TokenType.INT4RANGE: 'INT4RANGE'>, <TokenType.FIXEDSTRING: 'FIXEDSTRING'>, <TokenType.TDIGEST: 'TDIGEST'>, <TokenType.DOUBLE: 'DOUBLE'>, <TokenType.MONEY: 'MONEY'>, <TokenType.UBIGINT: 'UBIGINT'>, <TokenType.TIMESTAMP_NS: 'TIMESTAMP_NS'>, <TokenType.UDECIMAL: 'UDECIMAL'>, <TokenType.STRUCT: 'STRUCT'>, <TokenType.HSTORE: 'HSTORE'>, <TokenType.SMALLINT: 'SMALLINT'>, <TokenType.ENUM: 'ENUM'>, <TokenType.SMALLMONEY: 'SMALLMONEY'>, <TokenType.SIMPLEAGGREGATEFUNCTION: 'SIMPLEAGGREGATEFUNCTION'>, <TokenType.VARCHAR: 'VARCHAR'>, <TokenType.NCHAR: 'NCHAR'>, <TokenType.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, <TokenType.MEDIUMTEXT: 'MEDIUMTEXT'>, <TokenType.INTERVAL: 'INTERVAL'>, <TokenType.PSEUDO_TYPE: 'PSEUDO_TYPE'>, <TokenType.MEDIUMBLOB: 'MEDIUMBLOB'>, <TokenType.TIMETZ: 'TIMETZ'>, <TokenType.SET: 'SET'>, <TokenType.BPCHAR: 'BPCHAR'>, <TokenType.SERIAL: 'SERIAL'>, <TokenType.DATE: 'DATE'>, <TokenType.SUPER: 'SUPER'>, <TokenType.BIGDECIMAL: 'BIGDECIMAL'>, <TokenType.USMALLINT: 'USMALLINT'>}
ENUM_TYPE_TOKENS =
{<TokenType.SET: 'SET'>, <TokenType.ENUM16: 'ENUM16'>, <TokenType.ENUM: 'ENUM'>, <TokenType.ENUM8: 'ENUM8'>}
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
- ID_VAR_TOKENS
- INTERVAL_VARS
- ALIAS_TOKENS
- ARRAY_CONSTRUCTORS
- COMMENT_TABLE_ALIAS_TOKENS
- UPDATE_ALIAS_TOKENS
- TRIM_TYPES
- ASSIGNMENT
- EQUALITY
- COMPARISON
- BITWISE
- TERM
- FACTOR
- EXPONENT
- TIMES
- TIMESTAMPS
- SET_OPERATIONS
- JOIN_METHODS
- JOIN_SIDES
- JOIN_KINDS
- JOIN_HINTS
- LAMBDAS
- COLUMN_OPERATORS
- EXPRESSION_PARSERS
- UNARY_PARSERS
- STRING_PARSERS
- NUMERIC_PARSERS
- PRIMARY_PARSERS
- PLACEHOLDER_PARSERS
- ALTER_ALTER_PARSERS
- NO_PAREN_FUNCTION_PARSERS
- INVALID_FUNC_NAME_TOKENS
- FUNCTIONS_WITH_ALIASED_ARGS
- KEY_VALUE_DEFINITIONS
- QUERY_MODIFIER_PARSERS
- TYPE_LITERAL_PARSERS
- TYPE_CONVERTERS
- DDL_SELECT_TOKENS
- PRE_VOLATILE_TOKENS
- TRANSACTION_KIND
- TRANSACTION_CHARACTERISTICS
- CONFLICT_ACTIONS
- CREATE_SEQUENCE
- ISOLATED_LOADING_OPTIONS
- USABLES
- CAST_ACTIONS
- SCHEMA_BINDING_OPTIONS
- KEY_CONSTRAINT_OPTIONS
- INSERT_ALTERNATIVES
- CLONE_KEYWORDS
- HISTORICAL_DATA_PREFIX
- HISTORICAL_DATA_KIND
- OPCLASS_FOLLOW_KEYWORDS
- OPTYPE_FOLLOW_TOKENS
- TABLE_INDEX_HINT_TOKENS
- VIEW_ATTRIBUTES
- WINDOW_ALIAS_TOKENS
- WINDOW_BEFORE_PAREN_TOKENS
- WINDOW_SIDES
- JSON_KEY_VALUE_SEPARATOR_TOKENS
- FETCH_TOKENS
- ADD_CONSTRAINT_TOKENS
- DISTINCT_TOKENS
- NULL_TOKENS
- UNNEST_OFFSET_ALIAS_TOKENS
- SELECT_START_TOKENS
- COPY_INTO_VARLEN_OPTIONS
- STRICT_CAST
- PREFIXED_PIVOT_COLUMNS
- IDENTIFY_PIVOT_STRINGS
- ALTER_TABLE_ADD_REQUIRED_FOR_EACH_COLUMN
- TABLESAMPLE_CSV
- DEFAULT_SAMPLING_METHOD
- SET_REQUIRES_ASSIGNMENT_DELIMITER
- TRIM_PATTERN_FIRST
- MODIFIERS_ATTACHED_TO_SET_OP
- SET_OP_MODIFIERS
- NO_PAREN_IF_COMMANDS
- JSON_ARROWS_REQUIRE_JSON_TYPE
- COLON_IS_VARIANT_EXTRACT
- SUPPORTS_IMPLICIT_UNNEST
- INTERVAL_SPANS
- error_level
- error_message_context
- max_errors
- dialect
- reset
- parse
- parse_into
- check_errors
- raise_error
- expression
- validate_expression
- errors
- sql
678 class Generator(generator.Generator): 679 INTERVAL_ALLOWS_PLURAL_FORM = False 680 LOCKING_READS_SUPPORTED = True 681 NULL_ORDERING_SUPPORTED = None 682 JOIN_HINTS = False 683 TABLE_HINTS = True 684 DUPLICATE_KEY_UPDATE_WITH_SET = False 685 QUERY_HINT_SEP = " " 686 VALUES_AS_TABLE = False 687 NVL2_SUPPORTED = False 688 LAST_DAY_SUPPORTS_DATE_PART = False 689 JSON_TYPE_REQUIRED_FOR_EXTRACTION = True 690 JSON_PATH_BRACKETED_KEY_SUPPORTED = False 691 JSON_KEY_VALUE_PAIR_SEP = "," 692 SUPPORTS_TO_NUMBER = False 693 PARSE_JSON_NAME = None 694 PAD_FILL_PATTERN_IS_REQUIRED = True 695 WRAP_DERIVED_VALUES = False 696 697 TRANSFORMS = { 698 **generator.Generator.TRANSFORMS, 699 exp.ArrayAgg: rename_func("GROUP_CONCAT"), 700 exp.CurrentDate: no_paren_current_date_sql, 701 exp.DateDiff: _remove_ts_or_ds_to_date( 702 lambda self, e: self.func("DATEDIFF", e.this, e.expression), ("this", "expression") 703 ), 704 exp.DateAdd: _remove_ts_or_ds_to_date(date_add_sql("ADD")), 705 exp.DateStrToDate: datestrtodate_sql, 706 exp.DateSub: _remove_ts_or_ds_to_date(date_add_sql("SUB")), 707 exp.DateTrunc: _date_trunc_sql, 708 exp.Day: _remove_ts_or_ds_to_date(), 709 exp.DayOfMonth: _remove_ts_or_ds_to_date(rename_func("DAYOFMONTH")), 710 exp.DayOfWeek: _remove_ts_or_ds_to_date(rename_func("DAYOFWEEK")), 711 exp.DayOfYear: _remove_ts_or_ds_to_date(rename_func("DAYOFYEAR")), 712 exp.GroupConcat: lambda self, 713 e: f"""GROUP_CONCAT({self.sql(e, "this")} SEPARATOR {self.sql(e, "separator") or "','"})""", 714 exp.ILike: no_ilike_sql, 715 exp.JSONExtractScalar: arrow_json_extract_sql, 716 exp.Max: max_or_greatest, 717 exp.Min: min_or_least, 718 exp.Month: _remove_ts_or_ds_to_date(), 719 exp.NullSafeEQ: lambda self, e: self.binary(e, "<=>"), 720 exp.NullSafeNEQ: lambda self, e: f"NOT {self.binary(e, '<=>')}", 721 exp.Pivot: no_pivot_sql, 722 exp.Select: transforms.preprocess( 723 [ 724 transforms.eliminate_distinct_on, 725 transforms.eliminate_semi_and_anti_joins, 726 transforms.eliminate_qualify, 727 transforms.eliminate_full_outer_join, 728 ] 729 ), 730 exp.StrPosition: strposition_to_locate_sql, 731 exp.StrToDate: _str_to_date_sql, 732 exp.StrToTime: _str_to_date_sql, 733 exp.Stuff: rename_func("INSERT"), 734 exp.TableSample: no_tablesample_sql, 735 exp.TimeFromParts: rename_func("MAKETIME"), 736 exp.TimestampAdd: date_add_interval_sql("DATE", "ADD"), 737 exp.TimestampDiff: lambda self, e: self.func( 738 "TIMESTAMPDIFF", unit_to_var(e), e.expression, e.this 739 ), 740 exp.TimestampSub: date_add_interval_sql("DATE", "SUB"), 741 exp.TimeStrToUnix: rename_func("UNIX_TIMESTAMP"), 742 exp.TimeStrToTime: lambda self, e: self.sql( 743 exp.cast(e.this, exp.DataType.Type.DATETIME, copy=True) 744 ), 745 exp.TimeToStr: _remove_ts_or_ds_to_date( 746 lambda self, e: self.func("DATE_FORMAT", e.this, self.format_time(e)) 747 ), 748 exp.Trim: _trim_sql, 749 exp.TryCast: no_trycast_sql, 750 exp.TsOrDsAdd: date_add_sql("ADD"), 751 exp.TsOrDsDiff: lambda self, e: self.func("DATEDIFF", e.this, e.expression), 752 exp.TsOrDsToDate: _ts_or_ds_to_date_sql, 753 exp.UnixToTime: _unix_to_time_sql, 754 exp.Week: _remove_ts_or_ds_to_date(), 755 exp.WeekOfYear: _remove_ts_or_ds_to_date(rename_func("WEEKOFYEAR")), 756 exp.Year: _remove_ts_or_ds_to_date(), 757 } 758 759 UNSIGNED_TYPE_MAPPING = { 760 exp.DataType.Type.UBIGINT: "BIGINT", 761 exp.DataType.Type.UINT: "INT", 762 exp.DataType.Type.UMEDIUMINT: "MEDIUMINT", 763 exp.DataType.Type.USMALLINT: "SMALLINT", 764 exp.DataType.Type.UTINYINT: "TINYINT", 765 exp.DataType.Type.UDECIMAL: "DECIMAL", 766 } 767 768 TIMESTAMP_TYPE_MAPPING = { 769 exp.DataType.Type.TIMESTAMP: "DATETIME", 770 exp.DataType.Type.TIMESTAMPTZ: "TIMESTAMP", 771 exp.DataType.Type.TIMESTAMPLTZ: "TIMESTAMP", 772 } 773 774 TYPE_MAPPING = { 775 **generator.Generator.TYPE_MAPPING, 776 **UNSIGNED_TYPE_MAPPING, 777 **TIMESTAMP_TYPE_MAPPING, 778 } 779 780 TYPE_MAPPING.pop(exp.DataType.Type.MEDIUMTEXT) 781 TYPE_MAPPING.pop(exp.DataType.Type.LONGTEXT) 782 TYPE_MAPPING.pop(exp.DataType.Type.TINYTEXT) 783 TYPE_MAPPING.pop(exp.DataType.Type.MEDIUMBLOB) 784 TYPE_MAPPING.pop(exp.DataType.Type.LONGBLOB) 785 TYPE_MAPPING.pop(exp.DataType.Type.TINYBLOB) 786 787 PROPERTIES_LOCATION = { 788 **generator.Generator.PROPERTIES_LOCATION, 789 exp.TransientProperty: exp.Properties.Location.UNSUPPORTED, 790 exp.VolatileProperty: exp.Properties.Location.UNSUPPORTED, 791 } 792 793 LIMIT_FETCH = "LIMIT" 794 795 LIMIT_ONLY_LITERALS = True 796 797 CHAR_CAST_MAPPING = dict.fromkeys( 798 ( 799 exp.DataType.Type.LONGTEXT, 800 exp.DataType.Type.LONGBLOB, 801 exp.DataType.Type.MEDIUMBLOB, 802 exp.DataType.Type.MEDIUMTEXT, 803 exp.DataType.Type.TEXT, 804 exp.DataType.Type.TINYBLOB, 805 exp.DataType.Type.TINYTEXT, 806 exp.DataType.Type.VARCHAR, 807 ), 808 "CHAR", 809 ) 810 SIGNED_CAST_MAPPING = dict.fromkeys( 811 ( 812 exp.DataType.Type.BIGINT, 813 exp.DataType.Type.BOOLEAN, 814 exp.DataType.Type.INT, 815 exp.DataType.Type.SMALLINT, 816 exp.DataType.Type.TINYINT, 817 exp.DataType.Type.MEDIUMINT, 818 ), 819 "SIGNED", 820 ) 821 822 # MySQL doesn't support many datatypes in cast. 823 # https://dev.mysql.com/doc/refman/8.0/en/cast-functions.html#function_cast 824 CAST_MAPPING = { 825 **CHAR_CAST_MAPPING, 826 **SIGNED_CAST_MAPPING, 827 exp.DataType.Type.UBIGINT: "UNSIGNED", 828 } 829 830 TIMESTAMP_FUNC_TYPES = { 831 exp.DataType.Type.TIMESTAMPTZ, 832 exp.DataType.Type.TIMESTAMPLTZ, 833 } 834 835 # https://dev.mysql.com/doc/refman/8.0/en/keywords.html 836 RESERVED_KEYWORDS = { 837 "accessible", 838 "add", 839 "all", 840 "alter", 841 "analyze", 842 "and", 843 "as", 844 "asc", 845 "asensitive", 846 "before", 847 "between", 848 "bigint", 849 "binary", 850 "blob", 851 "both", 852 "by", 853 "call", 854 "cascade", 855 "case", 856 "change", 857 "char", 858 "character", 859 "check", 860 "collate", 861 "column", 862 "condition", 863 "constraint", 864 "continue", 865 "convert", 866 "create", 867 "cross", 868 "cube", 869 "cume_dist", 870 "current_date", 871 "current_time", 872 "current_timestamp", 873 "current_user", 874 "cursor", 875 "database", 876 "databases", 877 "day_hour", 878 "day_microsecond", 879 "day_minute", 880 "day_second", 881 "dec", 882 "decimal", 883 "declare", 884 "default", 885 "delayed", 886 "delete", 887 "dense_rank", 888 "desc", 889 "describe", 890 "deterministic", 891 "distinct", 892 "distinctrow", 893 "div", 894 "double", 895 "drop", 896 "dual", 897 "each", 898 "else", 899 "elseif", 900 "empty", 901 "enclosed", 902 "escaped", 903 "except", 904 "exists", 905 "exit", 906 "explain", 907 "false", 908 "fetch", 909 "first_value", 910 "float", 911 "float4", 912 "float8", 913 "for", 914 "force", 915 "foreign", 916 "from", 917 "fulltext", 918 "function", 919 "generated", 920 "get", 921 "grant", 922 "group", 923 "grouping", 924 "groups", 925 "having", 926 "high_priority", 927 "hour_microsecond", 928 "hour_minute", 929 "hour_second", 930 "if", 931 "ignore", 932 "in", 933 "index", 934 "infile", 935 "inner", 936 "inout", 937 "insensitive", 938 "insert", 939 "int", 940 "int1", 941 "int2", 942 "int3", 943 "int4", 944 "int8", 945 "integer", 946 "intersect", 947 "interval", 948 "into", 949 "io_after_gtids", 950 "io_before_gtids", 951 "is", 952 "iterate", 953 "join", 954 "json_table", 955 "key", 956 "keys", 957 "kill", 958 "lag", 959 "last_value", 960 "lateral", 961 "lead", 962 "leading", 963 "leave", 964 "left", 965 "like", 966 "limit", 967 "linear", 968 "lines", 969 "load", 970 "localtime", 971 "localtimestamp", 972 "lock", 973 "long", 974 "longblob", 975 "longtext", 976 "loop", 977 "low_priority", 978 "master_bind", 979 "master_ssl_verify_server_cert", 980 "match", 981 "maxvalue", 982 "mediumblob", 983 "mediumint", 984 "mediumtext", 985 "middleint", 986 "minute_microsecond", 987 "minute_second", 988 "mod", 989 "modifies", 990 "natural", 991 "not", 992 "no_write_to_binlog", 993 "nth_value", 994 "ntile", 995 "null", 996 "numeric", 997 "of", 998 "on", 999 "optimize", 1000 "optimizer_costs", 1001 "option", 1002 "optionally", 1003 "or", 1004 "order", 1005 "out", 1006 "outer", 1007 "outfile", 1008 "over", 1009 "partition", 1010 "percent_rank", 1011 "precision", 1012 "primary", 1013 "procedure", 1014 "purge", 1015 "range", 1016 "rank", 1017 "read", 1018 "reads", 1019 "read_write", 1020 "real", 1021 "recursive", 1022 "references", 1023 "regexp", 1024 "release", 1025 "rename", 1026 "repeat", 1027 "replace", 1028 "require", 1029 "resignal", 1030 "restrict", 1031 "return", 1032 "revoke", 1033 "right", 1034 "rlike", 1035 "row", 1036 "rows", 1037 "row_number", 1038 "schema", 1039 "schemas", 1040 "second_microsecond", 1041 "select", 1042 "sensitive", 1043 "separator", 1044 "set", 1045 "show", 1046 "signal", 1047 "smallint", 1048 "spatial", 1049 "specific", 1050 "sql", 1051 "sqlexception", 1052 "sqlstate", 1053 "sqlwarning", 1054 "sql_big_result", 1055 "sql_calc_found_rows", 1056 "sql_small_result", 1057 "ssl", 1058 "starting", 1059 "stored", 1060 "straight_join", 1061 "system", 1062 "table", 1063 "terminated", 1064 "then", 1065 "tinyblob", 1066 "tinyint", 1067 "tinytext", 1068 "to", 1069 "trailing", 1070 "trigger", 1071 "true", 1072 "undo", 1073 "union", 1074 "unique", 1075 "unlock", 1076 "unsigned", 1077 "update", 1078 "usage", 1079 "use", 1080 "using", 1081 "utc_date", 1082 "utc_time", 1083 "utc_timestamp", 1084 "values", 1085 "varbinary", 1086 "varchar", 1087 "varcharacter", 1088 "varying", 1089 "virtual", 1090 "when", 1091 "where", 1092 "while", 1093 "window", 1094 "with", 1095 "write", 1096 "xor", 1097 "year_month", 1098 "zerofill", 1099 } 1100 1101 def array_sql(self, expression: exp.Array) -> str: 1102 self.unsupported("Arrays are not supported by MySQL") 1103 return self.function_fallback_sql(expression) 1104 1105 def arraycontainsall_sql(self, expression: exp.ArrayContainsAll) -> str: 1106 self.unsupported("Array operations are not supported by MySQL") 1107 return self.function_fallback_sql(expression) 1108 1109 def dpipe_sql(self, expression: exp.DPipe) -> str: 1110 return self.func("CONCAT", *expression.flatten()) 1111 1112 def extract_sql(self, expression: exp.Extract) -> str: 1113 unit = expression.name 1114 if unit and unit.lower() == "epoch": 1115 return self.func("UNIX_TIMESTAMP", expression.expression) 1116 1117 return super().extract_sql(expression) 1118 1119 def datatype_sql(self, expression: exp.DataType) -> str: 1120 # https://dev.mysql.com/doc/refman/8.0/en/numeric-type-syntax.html 1121 result = super().datatype_sql(expression) 1122 if expression.this in self.UNSIGNED_TYPE_MAPPING: 1123 result = f"{result} UNSIGNED" 1124 return result 1125 1126 def jsonarraycontains_sql(self, expression: exp.JSONArrayContains) -> str: 1127 return f"{self.sql(expression, 'this')} MEMBER OF({self.sql(expression, 'expression')})" 1128 1129 def cast_sql(self, expression: exp.Cast, safe_prefix: t.Optional[str] = None) -> str: 1130 if expression.to.this in self.TIMESTAMP_FUNC_TYPES: 1131 return self.func("TIMESTAMP", expression.this) 1132 1133 to = self.CAST_MAPPING.get(expression.to.this) 1134 1135 if to: 1136 expression.to.set("this", to) 1137 return super().cast_sql(expression) 1138 1139 def show_sql(self, expression: exp.Show) -> str: 1140 this = f" {expression.name}" 1141 full = " FULL" if expression.args.get("full") else "" 1142 global_ = " GLOBAL" if expression.args.get("global") else "" 1143 1144 target = self.sql(expression, "target") 1145 target = f" {target}" if target else "" 1146 if expression.name in ("COLUMNS", "INDEX"): 1147 target = f" FROM{target}" 1148 elif expression.name == "GRANTS": 1149 target = f" FOR{target}" 1150 1151 db = self._prefixed_sql("FROM", expression, "db") 1152 1153 like = self._prefixed_sql("LIKE", expression, "like") 1154 where = self.sql(expression, "where") 1155 1156 types = self.expressions(expression, key="types") 1157 types = f" {types}" if types else types 1158 query = self._prefixed_sql("FOR QUERY", expression, "query") 1159 1160 if expression.name == "PROFILE": 1161 offset = self._prefixed_sql("OFFSET", expression, "offset") 1162 limit = self._prefixed_sql("LIMIT", expression, "limit") 1163 else: 1164 offset = "" 1165 limit = self._oldstyle_limit_sql(expression) 1166 1167 log = self._prefixed_sql("IN", expression, "log") 1168 position = self._prefixed_sql("FROM", expression, "position") 1169 1170 channel = self._prefixed_sql("FOR CHANNEL", expression, "channel") 1171 1172 if expression.name == "ENGINE": 1173 mutex_or_status = " MUTEX" if expression.args.get("mutex") else " STATUS" 1174 else: 1175 mutex_or_status = "" 1176 1177 return f"SHOW{full}{global_}{this}{target}{types}{db}{query}{log}{position}{channel}{mutex_or_status}{like}{where}{offset}{limit}" 1178 1179 def altercolumn_sql(self, expression: exp.AlterColumn) -> str: 1180 dtype = self.sql(expression, "dtype") 1181 if not dtype: 1182 return super().altercolumn_sql(expression) 1183 1184 this = self.sql(expression, "this") 1185 return f"MODIFY COLUMN {this} {dtype}" 1186 1187 def _prefixed_sql(self, prefix: str, expression: exp.Expression, arg: str) -> str: 1188 sql = self.sql(expression, arg) 1189 return f" {prefix} {sql}" if sql else "" 1190 1191 def _oldstyle_limit_sql(self, expression: exp.Show) -> str: 1192 limit = self.sql(expression, "limit") 1193 offset = self.sql(expression, "offset") 1194 if limit: 1195 limit_offset = f"{offset}, {limit}" if offset else limit 1196 return f" LIMIT {limit_offset}" 1197 return "" 1198 1199 def chr_sql(self, expression: exp.Chr) -> str: 1200 this = self.expressions(sqls=[expression.this] + expression.expressions) 1201 charset = expression.args.get("charset") 1202 using = f" USING {self.sql(charset)}" if charset else "" 1203 return f"CHAR({this}{using})" 1204 1205 def timestamptrunc_sql(self, expression: exp.TimestampTrunc) -> str: 1206 unit = expression.args.get("unit") 1207 1208 # Pick an old-enough date to avoid negative timestamp diffs 1209 start_ts = "'0000-01-01 00:00:00'" 1210 1211 # Source: https://stackoverflow.com/a/32955740 1212 timestamp_diff = build_date_delta(exp.TimestampDiff)([unit, start_ts, expression.this]) 1213 interval = exp.Interval(this=timestamp_diff, unit=unit) 1214 dateadd = build_date_delta_with_interval(exp.DateAdd)([start_ts, interval]) 1215 1216 return self.sql(dateadd)
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
TRANSFORMS =
{<class 'sqlglot.expressions.JSONPathFilter'>: <function <lambda>>, <class 'sqlglot.expressions.JSONPathKey'>: <function <lambda>>, <class 'sqlglot.expressions.JSONPathRecursive'>: <function <lambda>>, <class 'sqlglot.expressions.JSONPathRoot'>: <function <lambda>>, <class 'sqlglot.expressions.JSONPathScript'>: <function <lambda>>, <class 'sqlglot.expressions.JSONPathSelector'>: <function <lambda>>, <class 'sqlglot.expressions.JSONPathSlice'>: <function <lambda>>, <class 'sqlglot.expressions.JSONPathSubscript'>: <function <lambda>>, <class 'sqlglot.expressions.JSONPathUnion'>: <function <lambda>>, <class 'sqlglot.expressions.JSONPathWildcard'>: <function <lambda>>, <class 'sqlglot.expressions.AllowedValuesProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.AutoRefreshProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.BackupProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.CaseSpecificColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.CharacterSetColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.CharacterSetProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.ClusteredColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.CollateColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.CommentColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.ConnectByRoot'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.CopyGrantsProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.DateFormatColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.DefaultColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.DynamicProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.EncodeColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.EphemeralColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.ExcludeColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.ExecuteAsProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.ExternalProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.GlobalProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.HeapProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.IcebergProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.InheritsProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.InlineLengthColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.InputModelProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.IntervalSpan'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.JSONExtract'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.JSONExtractScalar'>: <function arrow_json_extract_sql>, <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.OutputModelProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.PathColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.ProjectionPolicyColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.RemoteWithConnectionModelProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.ReturnsProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.SampleProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.SecureProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.SetConfigProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.SetProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.SettingsProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.SharingProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.SqlReadWriteProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.SqlSecurityProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.StabilityProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.StrictProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.TemporaryProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.TagColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.TitleColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.Timestamp'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.ToMap'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.ToTableProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.TransformModelProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.TransientProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.UppercaseColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.UnloggedProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.VarMap'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.ViewAttributeProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.VolatileProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.WithJournalTableProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.WithSchemaBindingProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.WithOperator'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.ArrayAgg'>: <function rename_func.<locals>.<lambda>>, <class 'sqlglot.expressions.CurrentDate'>: <function no_paren_current_date_sql>, <class 'sqlglot.expressions.DateDiff'>: <function _remove_ts_or_ds_to_date.<locals>.func>, <class 'sqlglot.expressions.DateAdd'>: <function _remove_ts_or_ds_to_date.<locals>.func>, <class 'sqlglot.expressions.DateStrToDate'>: <function datestrtodate_sql>, <class 'sqlglot.expressions.DateSub'>: <function _remove_ts_or_ds_to_date.<locals>.func>, <class 'sqlglot.expressions.DateTrunc'>: <function _date_trunc_sql>, <class 'sqlglot.expressions.Day'>: <function _remove_ts_or_ds_to_date.<locals>.func>, <class 'sqlglot.expressions.DayOfMonth'>: <function _remove_ts_or_ds_to_date.<locals>.func>, <class 'sqlglot.expressions.DayOfWeek'>: <function _remove_ts_or_ds_to_date.<locals>.func>, <class 'sqlglot.expressions.DayOfYear'>: <function _remove_ts_or_ds_to_date.<locals>.func>, <class 'sqlglot.expressions.GroupConcat'>: <function MySQL.Generator.<lambda>>, <class 'sqlglot.expressions.ILike'>: <function no_ilike_sql>, <class 'sqlglot.expressions.Max'>: <function max_or_greatest>, <class 'sqlglot.expressions.Min'>: <function min_or_least>, <class 'sqlglot.expressions.Month'>: <function _remove_ts_or_ds_to_date.<locals>.func>, <class 'sqlglot.expressions.NullSafeEQ'>: <function MySQL.Generator.<lambda>>, <class 'sqlglot.expressions.NullSafeNEQ'>: <function MySQL.Generator.<lambda>>, <class 'sqlglot.expressions.Pivot'>: <function no_pivot_sql>, <class 'sqlglot.expressions.Select'>: <function preprocess.<locals>._to_sql>, <class 'sqlglot.expressions.StrPosition'>: <function strposition_to_locate_sql>, <class 'sqlglot.expressions.StrToDate'>: <function _str_to_date_sql>, <class 'sqlglot.expressions.StrToTime'>: <function _str_to_date_sql>, <class 'sqlglot.expressions.Stuff'>: <function rename_func.<locals>.<lambda>>, <class 'sqlglot.expressions.TableSample'>: <function no_tablesample_sql>, <class 'sqlglot.expressions.TimeFromParts'>: <function rename_func.<locals>.<lambda>>, <class 'sqlglot.expressions.TimestampAdd'>: <function date_add_interval_sql.<locals>.func>, <class 'sqlglot.expressions.TimestampDiff'>: <function MySQL.Generator.<lambda>>, <class 'sqlglot.expressions.TimestampSub'>: <function date_add_interval_sql.<locals>.func>, <class 'sqlglot.expressions.TimeStrToUnix'>: <function rename_func.<locals>.<lambda>>, <class 'sqlglot.expressions.TimeStrToTime'>: <function MySQL.Generator.<lambda>>, <class 'sqlglot.expressions.TimeToStr'>: <function _remove_ts_or_ds_to_date.<locals>.func>, <class 'sqlglot.expressions.Trim'>: <function _trim_sql>, <class 'sqlglot.expressions.TryCast'>: <function no_trycast_sql>, <class 'sqlglot.expressions.TsOrDsAdd'>: <function date_add_sql.<locals>.func>, <class 'sqlglot.expressions.TsOrDsDiff'>: <function MySQL.Generator.<lambda>>, <class 'sqlglot.expressions.TsOrDsToDate'>: <function _ts_or_ds_to_date_sql>, <class 'sqlglot.expressions.UnixToTime'>: <function _unix_to_time_sql>, <class 'sqlglot.expressions.Week'>: <function _remove_ts_or_ds_to_date.<locals>.func>, <class 'sqlglot.expressions.WeekOfYear'>: <function _remove_ts_or_ds_to_date.<locals>.func>, <class 'sqlglot.expressions.Year'>: <function _remove_ts_or_ds_to_date.<locals>.func>}
UNSIGNED_TYPE_MAPPING =
{<Type.UBIGINT: 'UBIGINT'>: 'BIGINT', <Type.UINT: 'UINT'>: 'INT', <Type.UMEDIUMINT: 'UMEDIUMINT'>: 'MEDIUMINT', <Type.USMALLINT: 'USMALLINT'>: 'SMALLINT', <Type.UTINYINT: 'UTINYINT'>: 'TINYINT', <Type.UDECIMAL: 'UDECIMAL'>: 'DECIMAL'}
TIMESTAMP_TYPE_MAPPING =
{<Type.TIMESTAMP: 'TIMESTAMP'>: 'DATETIME', <Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>: 'TIMESTAMP', <Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>: 'TIMESTAMP'}
TYPE_MAPPING =
{<Type.NCHAR: 'NCHAR'>: 'CHAR', <Type.NVARCHAR: 'NVARCHAR'>: 'VARCHAR', <Type.INET: 'INET'>: 'INET', <Type.ROWVERSION: 'ROWVERSION'>: 'VARBINARY', <Type.UBIGINT: 'UBIGINT'>: 'BIGINT', <Type.UINT: 'UINT'>: 'INT', <Type.UMEDIUMINT: 'UMEDIUMINT'>: 'MEDIUMINT', <Type.USMALLINT: 'USMALLINT'>: 'SMALLINT', <Type.UTINYINT: 'UTINYINT'>: 'TINYINT', <Type.UDECIMAL: 'UDECIMAL'>: 'DECIMAL', <Type.TIMESTAMP: 'TIMESTAMP'>: 'DATETIME', <Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>: 'TIMESTAMP', <Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>: 'TIMESTAMP'}
PROPERTIES_LOCATION =
{<class 'sqlglot.expressions.AllowedValuesProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.AlgorithmProperty'>: <Location.POST_CREATE: 'POST_CREATE'>, <class 'sqlglot.expressions.AutoIncrementProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.AutoRefreshProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.BackupProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.BlockCompressionProperty'>: <Location.POST_NAME: 'POST_NAME'>, <class 'sqlglot.expressions.CharacterSetProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.ChecksumProperty'>: <Location.POST_NAME: 'POST_NAME'>, <class 'sqlglot.expressions.CollateProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.CopyGrantsProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.Cluster'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.ClusteredByProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.DataBlocksizeProperty'>: <Location.POST_NAME: 'POST_NAME'>, <class 'sqlglot.expressions.DataDeletionProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.DefinerProperty'>: <Location.POST_CREATE: 'POST_CREATE'>, <class 'sqlglot.expressions.DictRange'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.DictProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.DynamicProperty'>: <Location.POST_CREATE: 'POST_CREATE'>, <class 'sqlglot.expressions.DistKeyProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.DistStyleProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.EngineProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.ExecuteAsProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.ExternalProperty'>: <Location.POST_CREATE: 'POST_CREATE'>, <class 'sqlglot.expressions.FallbackProperty'>: <Location.POST_NAME: 'POST_NAME'>, <class 'sqlglot.expressions.FileFormatProperty'>: <Location.POST_WITH: 'POST_WITH'>, <class 'sqlglot.expressions.FreespaceProperty'>: <Location.POST_NAME: 'POST_NAME'>, <class 'sqlglot.expressions.GlobalProperty'>: <Location.POST_CREATE: 'POST_CREATE'>, <class 'sqlglot.expressions.HeapProperty'>: <Location.POST_WITH: 'POST_WITH'>, <class 'sqlglot.expressions.InheritsProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.IcebergProperty'>: <Location.POST_CREATE: 'POST_CREATE'>, <class 'sqlglot.expressions.InputModelProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.IsolatedLoadingProperty'>: <Location.POST_NAME: 'POST_NAME'>, <class 'sqlglot.expressions.JournalProperty'>: <Location.POST_NAME: 'POST_NAME'>, <class 'sqlglot.expressions.LanguageProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.LikeProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.LocationProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.LockProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.LockingProperty'>: <Location.POST_ALIAS: 'POST_ALIAS'>, <class 'sqlglot.expressions.LogProperty'>: <Location.POST_NAME: 'POST_NAME'>, <class 'sqlglot.expressions.MaterializedProperty'>: <Location.POST_CREATE: 'POST_CREATE'>, <class 'sqlglot.expressions.MergeBlockRatioProperty'>: <Location.POST_NAME: 'POST_NAME'>, <class 'sqlglot.expressions.NoPrimaryIndexProperty'>: <Location.POST_EXPRESSION: 'POST_EXPRESSION'>, <class 'sqlglot.expressions.OnProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.OnCommitProperty'>: <Location.POST_EXPRESSION: 'POST_EXPRESSION'>, <class 'sqlglot.expressions.Order'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.OutputModelProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.PartitionedByProperty'>: <Location.POST_WITH: 'POST_WITH'>, <class 'sqlglot.expressions.PartitionedOfProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.PrimaryKey'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.Property'>: <Location.POST_WITH: 'POST_WITH'>, <class 'sqlglot.expressions.RemoteWithConnectionModelProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.ReturnsProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.RowFormatProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.RowFormatDelimitedProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.RowFormatSerdeProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.SampleProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.SchemaCommentProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.SecureProperty'>: <Location.POST_CREATE: 'POST_CREATE'>, <class 'sqlglot.expressions.SerdeProperties'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.Set'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.SettingsProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.SetProperty'>: <Location.POST_CREATE: 'POST_CREATE'>, <class 'sqlglot.expressions.SetConfigProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.SharingProperty'>: <Location.POST_EXPRESSION: 'POST_EXPRESSION'>, <class 'sqlglot.expressions.SequenceProperties'>: <Location.POST_EXPRESSION: 'POST_EXPRESSION'>, <class 'sqlglot.expressions.SortKeyProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.SqlReadWriteProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.SqlSecurityProperty'>: <Location.POST_CREATE: 'POST_CREATE'>, <class 'sqlglot.expressions.StabilityProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.StrictProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.TemporaryProperty'>: <Location.POST_CREATE: 'POST_CREATE'>, <class 'sqlglot.expressions.ToTableProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.TransientProperty'>: <Location.UNSUPPORTED: 'UNSUPPORTED'>, <class 'sqlglot.expressions.TransformModelProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.MergeTreeTTL'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.UnloggedProperty'>: <Location.POST_CREATE: 'POST_CREATE'>, <class 'sqlglot.expressions.ViewAttributeProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.VolatileProperty'>: <Location.UNSUPPORTED: 'UNSUPPORTED'>, <class 'sqlglot.expressions.WithDataProperty'>: <Location.POST_EXPRESSION: 'POST_EXPRESSION'>, <class 'sqlglot.expressions.WithJournalTableProperty'>: <Location.POST_NAME: 'POST_NAME'>, <class 'sqlglot.expressions.WithSchemaBindingProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.WithSystemVersioningProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>}
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'}
RESERVED_KEYWORDS =
{'sql_small_result', 'optimizer_costs', 'foreign', 'else', 'year_month', 'procedure', 'explain', 'having', 'join', 'lines', 'like', 'where', 'blob', 'minute_second', 'sqlstate', 'binary', 'terminated', 'describe', 'sqlwarning', 'day_microsecond', 'int', 'straight_join', 'separator', 'condition', 'regexp', 'enclosed', 'convert', 'varchar', 'dual', 'when', 'dense_rank', 'current_user', 'day_hour', 'int3', 'right', 'call', 'release', 'cume_dist', 'last_value', 'utc_time', 'lag', 'fetch', 'drop', 'escaped', 'smallint', 'keys', 'json_table', 'interval', 'inout', 'localtimestamp', 'fulltext', 'grouping', 'limit', 'key', 'tinyint', 'load', 'div', 'update', 'stored', 'require', 'integer', 'unsigned', 'sqlexception', 'exit', 'current_date', 'inner', 'except', 'distinct', 'ignore', 'localtime', 'elseif', 'current_time', 'hour_minute', 'starting', 'xor', 'loop', 'hour_second', 'outfile', 'force', 'over', 'minute_microsecond', 'option', 'databases', 'using', 'false', 'range', 'leave', 'mediumblob', 'char', 'insert', 'ntile', 'for', 'io_before_gtids', 'numeric', 'if', 'on', 'float4', 'group', 'natural', 'float8', 'system', 'row_number', 'precision', 'references', 'from', 'tinyblob', 'between', 'check', 'infile', 'accessible', 'delayed', 'select', 'function', 'virtual', 'both', 'utc_date', 'specific', 'while', 'constraint', 'decimal', 'lock', 'varcharacter', 'int2', 'io_after_gtids', 'lateral', 'true', 'union', 'first_value', 'float', 'generated', 'is', 'leading', 'rows', 'default', 'with', 'resignal', 'intersect', 'second_microsecond', 'kill', 'groups', 'linear', 'current_timestamp', 'then', 'by', 'table', 'analyze', 'asc', 'usage', 'read_write', 'utc_timestamp', 'recursive', 'row', 'read', 'character', 'alter', 'low_priority', 'change', 'int4', 'repeat', 'continue', 'varying', 'left', 'write', 'into', 'optionally', 'longblob', 'to', 'day_second', 'rename', 'spatial', 'cursor', 'outer', 'undo', 'long', 'case', 'percent_rank', 'order', 'master_bind', 'use', 'double', 'values', 'schemas', 'exists', 'revoke', 'iterate', 'sql', 'cross', 'match', 'schema', 'reads', 'day_minute', 'out', 'all', 'purge', 'mediumtext', 'empty', 'before', 'mediumint', 'trigger', 'unlock', 'ssl', 'index', 'sql_calc_found_rows', 'column', 'int1', 'rlike', 'and', 'declare', 'null', 'add', 'nth_value', 'signal', 'cascade', 'bigint', 'master_ssl_verify_server_cert', 'return', 'sensitive', 'maxvalue', 'tinytext', 'sql_big_result', 'deterministic', 'of', 'distinctrow', 'set', 'database', 'or', 'each', 'dec', 'get', 'high_priority', 'as', 'desc', 'rank', 'lead', 'show', 'unique', 'int8', 'primary', 'create', 'in', 'restrict', 'window', 'zerofill', 'grant', 'trailing', 'cube', 'asensitive', 'partition', 'optimize', 'varbinary', 'hour_microsecond', 'no_write_to_binlog', 'collate', 'replace', 'not', 'insensitive', 'longtext', 'delete', 'mod', 'middleint', 'modifies', 'real'}
def
cast_sql( self, expression: sqlglot.expressions.Cast, safe_prefix: Optional[str] = None) -> str:
1129 def cast_sql(self, expression: exp.Cast, safe_prefix: t.Optional[str] = None) -> str: 1130 if expression.to.this in self.TIMESTAMP_FUNC_TYPES: 1131 return self.func("TIMESTAMP", expression.this) 1132 1133 to = self.CAST_MAPPING.get(expression.to.this) 1134 1135 if to: 1136 expression.to.set("this", to) 1137 return super().cast_sql(expression)
1139 def show_sql(self, expression: exp.Show) -> str: 1140 this = f" {expression.name}" 1141 full = " FULL" if expression.args.get("full") else "" 1142 global_ = " GLOBAL" if expression.args.get("global") else "" 1143 1144 target = self.sql(expression, "target") 1145 target = f" {target}" if target else "" 1146 if expression.name in ("COLUMNS", "INDEX"): 1147 target = f" FROM{target}" 1148 elif expression.name == "GRANTS": 1149 target = f" FOR{target}" 1150 1151 db = self._prefixed_sql("FROM", expression, "db") 1152 1153 like = self._prefixed_sql("LIKE", expression, "like") 1154 where = self.sql(expression, "where") 1155 1156 types = self.expressions(expression, key="types") 1157 types = f" {types}" if types else types 1158 query = self._prefixed_sql("FOR QUERY", expression, "query") 1159 1160 if expression.name == "PROFILE": 1161 offset = self._prefixed_sql("OFFSET", expression, "offset") 1162 limit = self._prefixed_sql("LIMIT", expression, "limit") 1163 else: 1164 offset = "" 1165 limit = self._oldstyle_limit_sql(expression) 1166 1167 log = self._prefixed_sql("IN", expression, "log") 1168 position = self._prefixed_sql("FROM", expression, "position") 1169 1170 channel = self._prefixed_sql("FOR CHANNEL", expression, "channel") 1171 1172 if expression.name == "ENGINE": 1173 mutex_or_status = " MUTEX" if expression.args.get("mutex") else " STATUS" 1174 else: 1175 mutex_or_status = "" 1176 1177 return f"SHOW{full}{global_}{this}{target}{types}{db}{query}{log}{position}{channel}{mutex_or_status}{like}{where}{offset}{limit}"
1205 def timestamptrunc_sql(self, expression: exp.TimestampTrunc) -> str: 1206 unit = expression.args.get("unit") 1207 1208 # Pick an old-enough date to avoid negative timestamp diffs 1209 start_ts = "'0000-01-01 00:00:00'" 1210 1211 # Source: https://stackoverflow.com/a/32955740 1212 timestamp_diff = build_date_delta(exp.TimestampDiff)([unit, start_ts, expression.this]) 1213 interval = exp.Interval(this=timestamp_diff, unit=unit) 1214 dateadd = build_date_delta_with_interval(exp.DateAdd)([start_ts, interval]) 1215 1216 return self.sql(dateadd)
AFTER_HAVING_MODIFIER_TRANSFORMS =
{'windows': <function Generator.<lambda>>, 'qualify': <function Generator.<lambda>>}
Inherited Members
- sqlglot.generator.Generator
- Generator
- IGNORE_NULLS_IN_FUNC
- EXPLICIT_SET_OP
- CREATE_FUNCTION_RETURN_AS
- MATCHED_BY_SOURCE
- SINGLE_STRING_INTERVAL
- RENAME_TABLE_WITH_DB
- GROUPINGS_SEP
- INDEX_ON
- QUERY_HINTS
- IS_BOOL_ALLOWED
- LIMIT_IS_TOP
- RETURNING_END
- EXTRACT_ALLOWS_QUOTES
- TZ_TO_WITH_TIME_ZONE
- ALTER_TABLE_INCLUDE_COLUMN_KEYWORD
- UNNEST_WITH_ORDINALITY
- AGGREGATE_FILTER_SUPPORTED
- SEMI_ANTI_JOIN_WITH_SIDE
- COMPUTED_COLUMN_WITH_TYPE
- SUPPORTS_TABLE_COPY
- TABLESAMPLE_REQUIRES_PARENS
- TABLESAMPLE_SIZE_IS_ROWS
- TABLESAMPLE_KEYWORDS
- TABLESAMPLE_WITH_METHOD
- TABLESAMPLE_SEED_KEYWORD
- COLLATE_IS_FUNC
- DATA_TYPE_SPECIFIERS_ALLOWED
- ENSURE_BOOLS
- CTE_RECURSIVE_KEYWORD_REQUIRED
- SUPPORTS_SINGLE_ARG_CONCAT
- SUPPORTS_TABLE_ALIAS_COLUMNS
- UNPIVOT_ALIASES_ARE_IDENTIFIERS
- INSERT_OVERWRITE
- SUPPORTS_SELECT_INTO
- SUPPORTS_UNLOGGED_TABLES
- SUPPORTS_CREATE_TABLE_LIKE
- LIKE_PROPERTY_INSIDE_SCHEMA
- MULTI_ARG_DISTINCT
- JSON_PATH_SINGLE_QUOTE_ESCAPE
- SUPPORTED_JSON_PATH_PARTS
- CAN_IMPLEMENT_ARRAY_ANY
- SET_OP_MODIFIERS
- COPY_PARAMS_ARE_WRAPPED
- COPY_PARAMS_EQ_REQUIRED
- COPY_HAS_INTO_KEYWORD
- STAR_EXCEPT
- HEX_FUNC
- WITH_PROPERTIES_PREFIX
- QUOTE_JSON_PATH
- TIME_PART_SINGULARS
- TOKEN_MAPPING
- STRUCT_DELIMITER
- PARAMETER_TOKEN
- NAMED_PLACEHOLDER_TOKEN
- WITH_SEPARATED_COMMENTS
- EXCLUDE_COMMENTS
- UNWRAPPED_INTERVAL_VALUES
- PARAMETERIZABLE_TEXT_TYPES
- EXPRESSIONS_WITHOUT_NESTED_CTES
- SENTINEL_LINE_BREAK
- pretty
- identify
- normalize
- pad
- unsupported_level
- max_unsupported
- leading_comma
- max_text_width
- comments
- dialect
- normalize_functions
- unsupported_messages
- generate
- preprocess
- unsupported
- sep
- seg
- pad_comment
- maybe_comment
- wrap
- no_identify
- normalize_func
- indent
- sql
- uncache_sql
- cache_sql
- characterset_sql
- column_parts
- column_sql
- columnposition_sql
- columndef_sql
- columnconstraint_sql
- computedcolumnconstraint_sql
- autoincrementcolumnconstraint_sql
- compresscolumnconstraint_sql
- generatedasidentitycolumnconstraint_sql
- generatedasrowcolumnconstraint_sql
- periodforsystemtimeconstraint_sql
- notnullcolumnconstraint_sql
- transformcolumnconstraint_sql
- primarykeycolumnconstraint_sql
- uniquecolumnconstraint_sql
- createable_sql
- create_sql
- sequenceproperties_sql
- clone_sql
- describe_sql
- heredoc_sql
- prepend_ctes
- with_sql
- cte_sql
- tablealias_sql
- bitstring_sql
- hexstring_sql
- bytestring_sql
- unicodestring_sql
- rawstring_sql
- datatypeparam_sql
- directory_sql
- delete_sql
- drop_sql
- except_sql
- except_op
- fetch_sql
- filter_sql
- hint_sql
- indexparameters_sql
- index_sql
- identifier_sql
- hex_sql
- lowerhex_sql
- inputoutputformat_sql
- national_sql
- partition_sql
- properties_sql
- root_properties
- properties
- with_properties
- locate_properties
- property_name
- property_sql
- likeproperty_sql
- fallbackproperty_sql
- journalproperty_sql
- freespaceproperty_sql
- checksumproperty_sql
- mergeblockratioproperty_sql
- datablocksizeproperty_sql
- blockcompressionproperty_sql
- isolatedloadingproperty_sql
- partitionboundspec_sql
- partitionedofproperty_sql
- lockingproperty_sql
- withdataproperty_sql
- withsystemversioningproperty_sql
- insert_sql
- intersect_sql
- intersect_op
- introducer_sql
- kill_sql
- pseudotype_sql
- objectidentifier_sql
- onconflict_sql
- returning_sql
- rowformatdelimitedproperty_sql
- withtablehint_sql
- indextablehint_sql
- historicaldata_sql
- table_parts
- table_sql
- tablesample_sql
- pivot_sql
- version_sql
- tuple_sql
- update_sql
- values_sql
- var_sql
- into_sql
- from_sql
- group_sql
- having_sql
- connect_sql
- prior_sql
- join_sql
- lambda_sql
- lateral_op
- lateral_sql
- limit_sql
- offset_sql
- setitem_sql
- set_sql
- pragma_sql
- lock_sql
- literal_sql
- escape_str
- loaddata_sql
- null_sql
- boolean_sql
- order_sql
- withfill_sql
- cluster_sql
- distribute_sql
- sort_sql
- ordered_sql
- matchrecognizemeasure_sql
- matchrecognize_sql
- query_modifiers
- options_modifier
- queryoption_sql
- offset_limit_modifiers
- after_limit_modifiers
- select_sql
- schema_sql
- schema_columns_sql
- star_sql
- parameter_sql
- sessionparameter_sql
- placeholder_sql
- subquery_sql
- qualify_sql
- set_operations
- union_sql
- union_op
- unnest_sql
- prewhere_sql
- where_sql
- window_sql
- partition_by_sql
- windowspec_sql
- withingroup_sql
- between_sql
- bracket_offset_expressions
- bracket_sql
- all_sql
- any_sql
- exists_sql
- case_sql
- constraint_sql
- nextvaluefor_sql
- trim_sql
- convert_concat_args
- concat_sql
- concatws_sql
- check_sql
- foreignkey_sql
- primarykey_sql
- if_sql
- matchagainst_sql
- jsonkeyvalue_sql
- jsonpath_sql
- json_path_part
- formatjson_sql
- jsonobject_sql
- jsonobjectagg_sql
- jsonarray_sql
- jsonarrayagg_sql
- jsoncolumndef_sql
- jsonschema_sql
- jsontable_sql
- openjsoncolumndef_sql
- openjson_sql
- in_sql
- in_unnest_op
- interval_sql
- return_sql
- reference_sql
- anonymous_sql
- paren_sql
- neg_sql
- not_sql
- alias_sql
- pivotalias_sql
- aliases_sql
- atindex_sql
- attimezone_sql
- fromtimezone_sql
- add_sql
- and_sql
- or_sql
- xor_sql
- connector_sql
- bitwiseand_sql
- bitwiseleftshift_sql
- bitwisenot_sql
- bitwiseor_sql
- bitwiserightshift_sql
- bitwisexor_sql
- currentdate_sql
- currenttimestamp_sql
- collate_sql
- command_sql
- comment_sql
- mergetreettlaction_sql
- mergetreettl_sql
- transaction_sql
- commit_sql
- rollback_sql
- alterdiststyle_sql
- altersortkey_sql
- renametable_sql
- renamecolumn_sql
- alterset_sql
- altertable_sql
- add_column_sql
- droppartition_sql
- addconstraint_sql
- distinct_sql
- ignorenulls_sql
- respectnulls_sql
- havingmax_sql
- intdiv_sql
- div_sql
- overlaps_sql
- distance_sql
- dot_sql
- eq_sql
- propertyeq_sql
- escape_sql
- glob_sql
- gt_sql
- gte_sql
- ilike_sql
- ilikeany_sql
- is_sql
- like_sql
- likeany_sql
- similarto_sql
- lt_sql
- lte_sql
- mod_sql
- mul_sql
- neq_sql
- nullsafeeq_sql
- nullsafeneq_sql
- slice_sql
- sub_sql
- trycast_sql
- try_sql
- log_sql
- use_sql
- binary
- function_fallback_sql
- func
- format_args
- too_wide
- format_time
- expressions
- op_expressions
- naked_property
- tag_sql
- token_sql
- userdefinedfunction_sql
- joinhint_sql
- kwarg_sql
- when_sql
- merge_sql
- tochar_sql
- tonumber_sql
- dictproperty_sql
- dictrange_sql
- dictsubproperty_sql
- oncluster_sql
- clusteredbyproperty_sql
- anyvalue_sql
- querytransform_sql
- indexconstraintoption_sql
- checkcolumnconstraint_sql
- indexcolumnconstraint_sql
- nvl2_sql
- comprehension_sql
- columnprefix_sql
- opclass_sql
- predict_sql
- forin_sql
- refresh_sql
- operator_sql
- toarray_sql
- tsordstotime_sql
- tsordstotimestamp_sql
- tsordstodate_sql
- unixdate_sql
- lastday_sql
- dateadd_sql
- arrayany_sql
- generateseries_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
- length_sql
- rand_sql
- strtodate_sql
- strtotime_sql
- changes_sql
- pad_sql