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