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