sqlglot.dialects.mysql
1from __future__ import annotations 2 3import typing as t 4 5from sqlglot import exp, generator, parser, tokens, transforms 6from sqlglot.dialects.dialect import ( 7 Dialect, 8 NormalizationStrategy, 9 arrow_json_extract_sql, 10 date_add_interval_sql, 11 datestrtodate_sql, 12 build_formatted_time, 13 isnull_to_is_null, 14 locate_to_strposition, 15 max_or_greatest, 16 min_or_least, 17 no_ilike_sql, 18 no_paren_current_date_sql, 19 no_pivot_sql, 20 no_tablesample_sql, 21 no_trycast_sql, 22 build_date_delta, 23 build_date_delta_with_interval, 24 rename_func, 25 strposition_to_locate_sql, 26 unit_to_var, 27 trim_sql, 28 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 "CHAR_LENGTH": exp.Length.from_arg_list, 299 "CHARACTER_LENGTH": exp.Length.from_arg_list, 300 "CONVERT_TZ": lambda args: exp.ConvertTimezone( 301 source_tz=seq_get(args, 1), target_tz=seq_get(args, 2), timestamp=seq_get(args, 0) 302 ), 303 "DATE": lambda args: exp.TsOrDsToDate(this=seq_get(args, 0)), 304 "DATE_ADD": build_date_delta_with_interval(exp.DateAdd), 305 "DATE_FORMAT": build_formatted_time(exp.TimeToStr, "mysql"), 306 "DATE_SUB": build_date_delta_with_interval(exp.DateSub), 307 "DAY": lambda args: exp.Day(this=exp.TsOrDsToDate(this=seq_get(args, 0))), 308 "DAYOFMONTH": lambda args: exp.DayOfMonth(this=exp.TsOrDsToDate(this=seq_get(args, 0))), 309 "DAYOFWEEK": lambda args: exp.DayOfWeek(this=exp.TsOrDsToDate(this=seq_get(args, 0))), 310 "DAYOFYEAR": lambda args: exp.DayOfYear(this=exp.TsOrDsToDate(this=seq_get(args, 0))), 311 "FORMAT": exp.NumberToStr.from_arg_list, 312 "FROM_UNIXTIME": build_formatted_time(exp.UnixToTime, "mysql"), 313 "ISNULL": isnull_to_is_null, 314 "LOCATE": locate_to_strposition, 315 "MAKETIME": exp.TimeFromParts.from_arg_list, 316 "MONTH": lambda args: exp.Month(this=exp.TsOrDsToDate(this=seq_get(args, 0))), 317 "MONTHNAME": lambda args: exp.TimeToStr( 318 this=exp.TsOrDsToDate(this=seq_get(args, 0)), 319 format=exp.Literal.string("%B"), 320 ), 321 "STR_TO_DATE": _str_to_date, 322 "TIMESTAMPDIFF": build_date_delta(exp.TimestampDiff), 323 "TO_DAYS": lambda args: exp.paren( 324 exp.DateDiff( 325 this=exp.TsOrDsToDate(this=seq_get(args, 0)), 326 expression=exp.TsOrDsToDate(this=exp.Literal.string("0000-01-01")), 327 unit=exp.var("DAY"), 328 ) 329 + 1 330 ), 331 "WEEK": lambda args: exp.Week( 332 this=exp.TsOrDsToDate(this=seq_get(args, 0)), mode=seq_get(args, 1) 333 ), 334 "WEEKOFYEAR": lambda args: exp.WeekOfYear(this=exp.TsOrDsToDate(this=seq_get(args, 0))), 335 "YEAR": lambda args: exp.Year(this=exp.TsOrDsToDate(this=seq_get(args, 0))), 336 } 337 338 FUNCTION_PARSERS = { 339 **parser.Parser.FUNCTION_PARSERS, 340 "CHAR": lambda self: self.expression( 341 exp.Chr, 342 expressions=self._parse_csv(self._parse_assignment), 343 charset=self._match(TokenType.USING) and self._parse_var(), 344 ), 345 "GROUP_CONCAT": lambda self: self._parse_group_concat(), 346 # https://dev.mysql.com/doc/refman/5.7/en/miscellaneous-functions.html#function_values 347 "VALUES": lambda self: self.expression( 348 exp.Anonymous, this="VALUES", expressions=[self._parse_id_var()] 349 ), 350 "JSON_VALUE": lambda self: self._parse_json_value(), 351 } 352 353 STATEMENT_PARSERS = { 354 **parser.Parser.STATEMENT_PARSERS, 355 TokenType.SHOW: lambda self: self._parse_show(), 356 } 357 358 SHOW_PARSERS = { 359 "BINARY LOGS": _show_parser("BINARY LOGS"), 360 "MASTER LOGS": _show_parser("BINARY LOGS"), 361 "BINLOG EVENTS": _show_parser("BINLOG EVENTS"), 362 "CHARACTER SET": _show_parser("CHARACTER SET"), 363 "CHARSET": _show_parser("CHARACTER SET"), 364 "COLLATION": _show_parser("COLLATION"), 365 "FULL COLUMNS": _show_parser("COLUMNS", target="FROM", full=True), 366 "COLUMNS": _show_parser("COLUMNS", target="FROM"), 367 "CREATE DATABASE": _show_parser("CREATE DATABASE", target=True), 368 "CREATE EVENT": _show_parser("CREATE EVENT", target=True), 369 "CREATE FUNCTION": _show_parser("CREATE FUNCTION", target=True), 370 "CREATE PROCEDURE": _show_parser("CREATE PROCEDURE", target=True), 371 "CREATE TABLE": _show_parser("CREATE TABLE", target=True), 372 "CREATE TRIGGER": _show_parser("CREATE TRIGGER", target=True), 373 "CREATE VIEW": _show_parser("CREATE VIEW", target=True), 374 "DATABASES": _show_parser("DATABASES"), 375 "SCHEMAS": _show_parser("DATABASES"), 376 "ENGINE": _show_parser("ENGINE", target=True), 377 "STORAGE ENGINES": _show_parser("ENGINES"), 378 "ENGINES": _show_parser("ENGINES"), 379 "ERRORS": _show_parser("ERRORS"), 380 "EVENTS": _show_parser("EVENTS"), 381 "FUNCTION CODE": _show_parser("FUNCTION CODE", target=True), 382 "FUNCTION STATUS": _show_parser("FUNCTION STATUS"), 383 "GRANTS": _show_parser("GRANTS", target="FOR"), 384 "INDEX": _show_parser("INDEX", target="FROM"), 385 "MASTER STATUS": _show_parser("MASTER STATUS"), 386 "OPEN TABLES": _show_parser("OPEN TABLES"), 387 "PLUGINS": _show_parser("PLUGINS"), 388 "PROCEDURE CODE": _show_parser("PROCEDURE CODE", target=True), 389 "PROCEDURE STATUS": _show_parser("PROCEDURE STATUS"), 390 "PRIVILEGES": _show_parser("PRIVILEGES"), 391 "FULL PROCESSLIST": _show_parser("PROCESSLIST", full=True), 392 "PROCESSLIST": _show_parser("PROCESSLIST"), 393 "PROFILE": _show_parser("PROFILE"), 394 "PROFILES": _show_parser("PROFILES"), 395 "RELAYLOG EVENTS": _show_parser("RELAYLOG EVENTS"), 396 "REPLICAS": _show_parser("REPLICAS"), 397 "SLAVE HOSTS": _show_parser("REPLICAS"), 398 "REPLICA STATUS": _show_parser("REPLICA STATUS"), 399 "SLAVE STATUS": _show_parser("REPLICA STATUS"), 400 "GLOBAL STATUS": _show_parser("STATUS", global_=True), 401 "SESSION STATUS": _show_parser("STATUS"), 402 "STATUS": _show_parser("STATUS"), 403 "TABLE STATUS": _show_parser("TABLE STATUS"), 404 "FULL TABLES": _show_parser("TABLES", full=True), 405 "TABLES": _show_parser("TABLES"), 406 "TRIGGERS": _show_parser("TRIGGERS"), 407 "GLOBAL VARIABLES": _show_parser("VARIABLES", global_=True), 408 "SESSION VARIABLES": _show_parser("VARIABLES"), 409 "VARIABLES": _show_parser("VARIABLES"), 410 "WARNINGS": _show_parser("WARNINGS"), 411 } 412 413 PROPERTY_PARSERS = { 414 **parser.Parser.PROPERTY_PARSERS, 415 "LOCK": lambda self: self._parse_property_assignment(exp.LockProperty), 416 } 417 418 SET_PARSERS = { 419 **parser.Parser.SET_PARSERS, 420 "PERSIST": lambda self: self._parse_set_item_assignment("PERSIST"), 421 "PERSIST_ONLY": lambda self: self._parse_set_item_assignment("PERSIST_ONLY"), 422 "CHARACTER SET": lambda self: self._parse_set_item_charset("CHARACTER SET"), 423 "CHARSET": lambda self: self._parse_set_item_charset("CHARACTER SET"), 424 "NAMES": lambda self: self._parse_set_item_names(), 425 } 426 427 CONSTRAINT_PARSERS = { 428 **parser.Parser.CONSTRAINT_PARSERS, 429 "FULLTEXT": lambda self: self._parse_index_constraint(kind="FULLTEXT"), 430 "INDEX": lambda self: self._parse_index_constraint(), 431 "KEY": lambda self: self._parse_index_constraint(), 432 "SPATIAL": lambda self: self._parse_index_constraint(kind="SPATIAL"), 433 } 434 435 ALTER_PARSERS = { 436 **parser.Parser.ALTER_PARSERS, 437 "MODIFY": lambda self: self._parse_alter_table_alter(), 438 } 439 440 SCHEMA_UNNAMED_CONSTRAINTS = { 441 *parser.Parser.SCHEMA_UNNAMED_CONSTRAINTS, 442 "FULLTEXT", 443 "INDEX", 444 "KEY", 445 "SPATIAL", 446 } 447 448 PROFILE_TYPES: parser.OPTIONS_TYPE = { 449 **dict.fromkeys(("ALL", "CPU", "IPC", "MEMORY", "SOURCE", "SWAPS"), tuple()), 450 "BLOCK": ("IO",), 451 "CONTEXT": ("SWITCHES",), 452 "PAGE": ("FAULTS",), 453 } 454 455 TYPE_TOKENS = { 456 *parser.Parser.TYPE_TOKENS, 457 TokenType.SET, 458 } 459 460 ENUM_TYPE_TOKENS = { 461 *parser.Parser.ENUM_TYPE_TOKENS, 462 TokenType.SET, 463 } 464 465 # SELECT [ ALL | DISTINCT | DISTINCTROW ] [ <OPERATION_MODIFIERS> ] 466 OPERATION_MODIFIERS = { 467 "HIGH_PRIORITY", 468 "STRAIGHT_JOIN", 469 "SQL_SMALL_RESULT", 470 "SQL_BIG_RESULT", 471 "SQL_BUFFER_RESULT", 472 "SQL_NO_CACHE", 473 "SQL_CALC_FOUND_ROWS", 474 } 475 476 LOG_DEFAULTS_TO_LN = True 477 STRING_ALIASES = True 478 VALUES_FOLLOWED_BY_PAREN = False 479 SUPPORTS_PARTITION_SELECTION = True 480 481 def _parse_primary_key_part(self) -> t.Optional[exp.Expression]: 482 this = self._parse_id_var() 483 if not self._match(TokenType.L_PAREN): 484 return this 485 486 expression = self._parse_number() 487 self._match_r_paren() 488 return self.expression(exp.ColumnPrefix, this=this, expression=expression) 489 490 def _parse_index_constraint( 491 self, kind: t.Optional[str] = None 492 ) -> exp.IndexColumnConstraint: 493 if kind: 494 self._match_texts(("INDEX", "KEY")) 495 496 this = self._parse_id_var(any_token=False) 497 index_type = self._match(TokenType.USING) and self._advance_any() and self._prev.text 498 expressions = self._parse_wrapped_csv(self._parse_ordered) 499 500 options = [] 501 while True: 502 if self._match_text_seq("KEY_BLOCK_SIZE"): 503 self._match(TokenType.EQ) 504 opt = exp.IndexConstraintOption(key_block_size=self._parse_number()) 505 elif self._match(TokenType.USING): 506 opt = exp.IndexConstraintOption(using=self._advance_any() and self._prev.text) 507 elif self._match_text_seq("WITH", "PARSER"): 508 opt = exp.IndexConstraintOption(parser=self._parse_var(any_token=True)) 509 elif self._match(TokenType.COMMENT): 510 opt = exp.IndexConstraintOption(comment=self._parse_string()) 511 elif self._match_text_seq("VISIBLE"): 512 opt = exp.IndexConstraintOption(visible=True) 513 elif self._match_text_seq("INVISIBLE"): 514 opt = exp.IndexConstraintOption(visible=False) 515 elif self._match_text_seq("ENGINE_ATTRIBUTE"): 516 self._match(TokenType.EQ) 517 opt = exp.IndexConstraintOption(engine_attr=self._parse_string()) 518 elif self._match_text_seq("SECONDARY_ENGINE_ATTRIBUTE"): 519 self._match(TokenType.EQ) 520 opt = exp.IndexConstraintOption(secondary_engine_attr=self._parse_string()) 521 else: 522 opt = None 523 524 if not opt: 525 break 526 527 options.append(opt) 528 529 return self.expression( 530 exp.IndexColumnConstraint, 531 this=this, 532 expressions=expressions, 533 kind=kind, 534 index_type=index_type, 535 options=options, 536 ) 537 538 def _parse_show_mysql( 539 self, 540 this: str, 541 target: bool | str = False, 542 full: t.Optional[bool] = None, 543 global_: t.Optional[bool] = None, 544 ) -> exp.Show: 545 if target: 546 if isinstance(target, str): 547 self._match_text_seq(target) 548 target_id = self._parse_id_var() 549 else: 550 target_id = None 551 552 log = self._parse_string() if self._match_text_seq("IN") else None 553 554 if this in ("BINLOG EVENTS", "RELAYLOG EVENTS"): 555 position = self._parse_number() if self._match_text_seq("FROM") else None 556 db = None 557 else: 558 position = None 559 db = None 560 561 if self._match(TokenType.FROM): 562 db = self._parse_id_var() 563 elif self._match(TokenType.DOT): 564 db = target_id 565 target_id = self._parse_id_var() 566 567 channel = self._parse_id_var() if self._match_text_seq("FOR", "CHANNEL") else None 568 569 like = self._parse_string() if self._match_text_seq("LIKE") else None 570 where = self._parse_where() 571 572 if this == "PROFILE": 573 types = self._parse_csv(lambda: self._parse_var_from_options(self.PROFILE_TYPES)) 574 query = self._parse_number() if self._match_text_seq("FOR", "QUERY") else None 575 offset = self._parse_number() if self._match_text_seq("OFFSET") else None 576 limit = self._parse_number() if self._match_text_seq("LIMIT") else None 577 else: 578 types, query = None, None 579 offset, limit = self._parse_oldstyle_limit() 580 581 mutex = True if self._match_text_seq("MUTEX") else None 582 mutex = False if self._match_text_seq("STATUS") else mutex 583 584 return self.expression( 585 exp.Show, 586 this=this, 587 target=target_id, 588 full=full, 589 log=log, 590 position=position, 591 db=db, 592 channel=channel, 593 like=like, 594 where=where, 595 types=types, 596 query=query, 597 offset=offset, 598 limit=limit, 599 mutex=mutex, 600 **{"global": global_}, # type: ignore 601 ) 602 603 def _parse_oldstyle_limit( 604 self, 605 ) -> t.Tuple[t.Optional[exp.Expression], t.Optional[exp.Expression]]: 606 limit = None 607 offset = None 608 if self._match_text_seq("LIMIT"): 609 parts = self._parse_csv(self._parse_number) 610 if len(parts) == 1: 611 limit = parts[0] 612 elif len(parts) == 2: 613 limit = parts[1] 614 offset = parts[0] 615 616 return offset, limit 617 618 def _parse_set_item_charset(self, kind: str) -> exp.Expression: 619 this = self._parse_string() or self._parse_unquoted_field() 620 return self.expression(exp.SetItem, this=this, kind=kind) 621 622 def _parse_set_item_names(self) -> exp.Expression: 623 charset = self._parse_string() or self._parse_unquoted_field() 624 if self._match_text_seq("COLLATE"): 625 collate = self._parse_string() or self._parse_unquoted_field() 626 else: 627 collate = None 628 629 return self.expression(exp.SetItem, this=charset, collate=collate, kind="NAMES") 630 631 def _parse_type( 632 self, parse_interval: bool = True, fallback_to_identifier: bool = False 633 ) -> t.Optional[exp.Expression]: 634 # mysql binary is special and can work anywhere, even in order by operations 635 # it operates like a no paren func 636 if self._match(TokenType.BINARY, advance=False): 637 data_type = self._parse_types(check_func=True, allow_identifiers=False) 638 639 if isinstance(data_type, exp.DataType): 640 return self.expression(exp.Cast, this=self._parse_column(), to=data_type) 641 642 return super()._parse_type( 643 parse_interval=parse_interval, fallback_to_identifier=fallback_to_identifier 644 ) 645 646 def _parse_group_concat(self) -> t.Optional[exp.Expression]: 647 def concat_exprs( 648 node: t.Optional[exp.Expression], exprs: t.List[exp.Expression] 649 ) -> exp.Expression: 650 if isinstance(node, exp.Distinct) and len(node.expressions) > 1: 651 concat_exprs = [ 652 self.expression(exp.Concat, expressions=node.expressions, safe=True) 653 ] 654 node.set("expressions", concat_exprs) 655 return node 656 if len(exprs) == 1: 657 return exprs[0] 658 return self.expression(exp.Concat, expressions=args, safe=True) 659 660 args = self._parse_csv(self._parse_lambda) 661 662 if args: 663 order = args[-1] if isinstance(args[-1], exp.Order) else None 664 665 if order: 666 # Order By is the last (or only) expression in the list and has consumed the 'expr' before it, 667 # remove 'expr' from exp.Order and add it back to args 668 args[-1] = order.this 669 order.set("this", concat_exprs(order.this, args)) 670 671 this = order or concat_exprs(args[0], args) 672 else: 673 this = None 674 675 separator = self._parse_field() if self._match(TokenType.SEPARATOR) else None 676 677 return self.expression(exp.GroupConcat, this=this, separator=separator) 678 679 def _parse_json_value(self) -> exp.JSONValue: 680 this = self._parse_bitwise() 681 self._match(TokenType.COMMA) 682 path = self._parse_bitwise() 683 684 returning = self._match(TokenType.RETURNING) and self._parse_type() 685 686 return self.expression( 687 exp.JSONValue, 688 this=this, 689 path=self.dialect.to_json_path(path), 690 returning=returning, 691 on_condition=self._parse_on_condition(), 692 ) 693 694 class Generator(generator.Generator): 695 INTERVAL_ALLOWS_PLURAL_FORM = False 696 LOCKING_READS_SUPPORTED = True 697 NULL_ORDERING_SUPPORTED = None 698 JOIN_HINTS = False 699 TABLE_HINTS = True 700 DUPLICATE_KEY_UPDATE_WITH_SET = False 701 QUERY_HINT_SEP = " " 702 VALUES_AS_TABLE = False 703 NVL2_SUPPORTED = False 704 LAST_DAY_SUPPORTS_DATE_PART = False 705 JSON_TYPE_REQUIRED_FOR_EXTRACTION = True 706 JSON_PATH_BRACKETED_KEY_SUPPORTED = False 707 JSON_KEY_VALUE_PAIR_SEP = "," 708 SUPPORTS_TO_NUMBER = False 709 PARSE_JSON_NAME: t.Optional[str] = None 710 PAD_FILL_PATTERN_IS_REQUIRED = True 711 WRAP_DERIVED_VALUES = False 712 VARCHAR_REQUIRES_SIZE = True 713 SUPPORTS_MEDIAN = False 714 715 TRANSFORMS = { 716 **generator.Generator.TRANSFORMS, 717 exp.ArrayAgg: rename_func("GROUP_CONCAT"), 718 exp.CurrentDate: no_paren_current_date_sql, 719 exp.DateDiff: _remove_ts_or_ds_to_date( 720 lambda self, e: self.func("DATEDIFF", e.this, e.expression), ("this", "expression") 721 ), 722 exp.DateAdd: _remove_ts_or_ds_to_date(date_add_sql("ADD")), 723 exp.DateStrToDate: datestrtodate_sql, 724 exp.DateSub: _remove_ts_or_ds_to_date(date_add_sql("SUB")), 725 exp.DateTrunc: _date_trunc_sql, 726 exp.Day: _remove_ts_or_ds_to_date(), 727 exp.DayOfMonth: _remove_ts_or_ds_to_date(rename_func("DAYOFMONTH")), 728 exp.DayOfWeek: _remove_ts_or_ds_to_date(rename_func("DAYOFWEEK")), 729 exp.DayOfYear: _remove_ts_or_ds_to_date(rename_func("DAYOFYEAR")), 730 exp.GroupConcat: lambda self, 731 e: f"""GROUP_CONCAT({self.sql(e, "this")} SEPARATOR {self.sql(e, "separator") or "','"})""", 732 exp.ILike: no_ilike_sql, 733 exp.JSONExtractScalar: arrow_json_extract_sql, 734 exp.Length: rename_func("CHAR_LENGTH"), 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: strposition_to_locate_sql, 752 exp.StrToDate: _str_to_date_sql, 753 exp.StrToTime: _str_to_date_sql, 754 exp.Stuff: rename_func("INSERT"), 755 exp.TableSample: no_tablesample_sql, 756 exp.TimeFromParts: rename_func("MAKETIME"), 757 exp.TimestampAdd: date_add_interval_sql("DATE", "ADD"), 758 exp.TimestampDiff: lambda self, e: self.func( 759 "TIMESTAMPDIFF", unit_to_var(e), e.expression, e.this 760 ), 761 exp.TimestampSub: date_add_interval_sql("DATE", "SUB"), 762 exp.TimeStrToUnix: rename_func("UNIX_TIMESTAMP"), 763 exp.TimeStrToTime: lambda self, e: timestrtotime_sql( 764 self, 765 e, 766 include_precision=not e.args.get("zone"), 767 ), 768 exp.TimeToStr: _remove_ts_or_ds_to_date( 769 lambda self, e: self.func("DATE_FORMAT", e.this, self.format_time(e)) 770 ), 771 exp.Trim: trim_sql, 772 exp.TryCast: no_trycast_sql, 773 exp.TsOrDsAdd: date_add_sql("ADD"), 774 exp.TsOrDsDiff: lambda self, e: self.func("DATEDIFF", e.this, e.expression), 775 exp.TsOrDsToDate: _ts_or_ds_to_date_sql, 776 exp.UnixToTime: _unix_to_time_sql, 777 exp.Week: _remove_ts_or_ds_to_date(), 778 exp.WeekOfYear: _remove_ts_or_ds_to_date(rename_func("WEEKOFYEAR")), 779 exp.Year: _remove_ts_or_ds_to_date(), 780 } 781 782 UNSIGNED_TYPE_MAPPING = { 783 exp.DataType.Type.UBIGINT: "BIGINT", 784 exp.DataType.Type.UINT: "INT", 785 exp.DataType.Type.UMEDIUMINT: "MEDIUMINT", 786 exp.DataType.Type.USMALLINT: "SMALLINT", 787 exp.DataType.Type.UTINYINT: "TINYINT", 788 exp.DataType.Type.UDECIMAL: "DECIMAL", 789 } 790 791 TIMESTAMP_TYPE_MAPPING = { 792 exp.DataType.Type.DATETIME2: "DATETIME", 793 exp.DataType.Type.SMALLDATETIME: "DATETIME", 794 exp.DataType.Type.TIMESTAMP: "DATETIME", 795 exp.DataType.Type.TIMESTAMPTZ: "TIMESTAMP", 796 exp.DataType.Type.TIMESTAMPLTZ: "TIMESTAMP", 797 } 798 799 TYPE_MAPPING = { 800 **generator.Generator.TYPE_MAPPING, 801 **UNSIGNED_TYPE_MAPPING, 802 **TIMESTAMP_TYPE_MAPPING, 803 } 804 805 TYPE_MAPPING.pop(exp.DataType.Type.MEDIUMTEXT) 806 TYPE_MAPPING.pop(exp.DataType.Type.LONGTEXT) 807 TYPE_MAPPING.pop(exp.DataType.Type.TINYTEXT) 808 TYPE_MAPPING.pop(exp.DataType.Type.MEDIUMBLOB) 809 TYPE_MAPPING.pop(exp.DataType.Type.LONGBLOB) 810 TYPE_MAPPING.pop(exp.DataType.Type.TINYBLOB) 811 812 PROPERTIES_LOCATION = { 813 **generator.Generator.PROPERTIES_LOCATION, 814 exp.TransientProperty: exp.Properties.Location.UNSUPPORTED, 815 exp.VolatileProperty: exp.Properties.Location.UNSUPPORTED, 816 } 817 818 LIMIT_FETCH = "LIMIT" 819 820 LIMIT_ONLY_LITERALS = True 821 822 CHAR_CAST_MAPPING = dict.fromkeys( 823 ( 824 exp.DataType.Type.LONGTEXT, 825 exp.DataType.Type.LONGBLOB, 826 exp.DataType.Type.MEDIUMBLOB, 827 exp.DataType.Type.MEDIUMTEXT, 828 exp.DataType.Type.TEXT, 829 exp.DataType.Type.TINYBLOB, 830 exp.DataType.Type.TINYTEXT, 831 exp.DataType.Type.VARCHAR, 832 ), 833 "CHAR", 834 ) 835 SIGNED_CAST_MAPPING = dict.fromkeys( 836 ( 837 exp.DataType.Type.BIGINT, 838 exp.DataType.Type.BOOLEAN, 839 exp.DataType.Type.INT, 840 exp.DataType.Type.SMALLINT, 841 exp.DataType.Type.TINYINT, 842 exp.DataType.Type.MEDIUMINT, 843 ), 844 "SIGNED", 845 ) 846 847 # MySQL doesn't support many datatypes in cast. 848 # https://dev.mysql.com/doc/refman/8.0/en/cast-functions.html#function_cast 849 CAST_MAPPING = { 850 **CHAR_CAST_MAPPING, 851 **SIGNED_CAST_MAPPING, 852 exp.DataType.Type.UBIGINT: "UNSIGNED", 853 } 854 855 TIMESTAMP_FUNC_TYPES = { 856 exp.DataType.Type.TIMESTAMPTZ, 857 exp.DataType.Type.TIMESTAMPLTZ, 858 } 859 860 # https://dev.mysql.com/doc/refman/8.0/en/keywords.html 861 RESERVED_KEYWORDS = { 862 "accessible", 863 "add", 864 "all", 865 "alter", 866 "analyze", 867 "and", 868 "as", 869 "asc", 870 "asensitive", 871 "before", 872 "between", 873 "bigint", 874 "binary", 875 "blob", 876 "both", 877 "by", 878 "call", 879 "cascade", 880 "case", 881 "change", 882 "char", 883 "character", 884 "check", 885 "collate", 886 "column", 887 "condition", 888 "constraint", 889 "continue", 890 "convert", 891 "create", 892 "cross", 893 "cube", 894 "cume_dist", 895 "current_date", 896 "current_time", 897 "current_timestamp", 898 "current_user", 899 "cursor", 900 "database", 901 "databases", 902 "day_hour", 903 "day_microsecond", 904 "day_minute", 905 "day_second", 906 "dec", 907 "decimal", 908 "declare", 909 "default", 910 "delayed", 911 "delete", 912 "dense_rank", 913 "desc", 914 "describe", 915 "deterministic", 916 "distinct", 917 "distinctrow", 918 "div", 919 "double", 920 "drop", 921 "dual", 922 "each", 923 "else", 924 "elseif", 925 "empty", 926 "enclosed", 927 "escaped", 928 "except", 929 "exists", 930 "exit", 931 "explain", 932 "false", 933 "fetch", 934 "first_value", 935 "float", 936 "float4", 937 "float8", 938 "for", 939 "force", 940 "foreign", 941 "from", 942 "fulltext", 943 "function", 944 "generated", 945 "get", 946 "grant", 947 "group", 948 "grouping", 949 "groups", 950 "having", 951 "high_priority", 952 "hour_microsecond", 953 "hour_minute", 954 "hour_second", 955 "if", 956 "ignore", 957 "in", 958 "index", 959 "infile", 960 "inner", 961 "inout", 962 "insensitive", 963 "insert", 964 "int", 965 "int1", 966 "int2", 967 "int3", 968 "int4", 969 "int8", 970 "integer", 971 "intersect", 972 "interval", 973 "into", 974 "io_after_gtids", 975 "io_before_gtids", 976 "is", 977 "iterate", 978 "join", 979 "json_table", 980 "key", 981 "keys", 982 "kill", 983 "lag", 984 "last_value", 985 "lateral", 986 "lead", 987 "leading", 988 "leave", 989 "left", 990 "like", 991 "limit", 992 "linear", 993 "lines", 994 "load", 995 "localtime", 996 "localtimestamp", 997 "lock", 998 "long", 999 "longblob", 1000 "longtext", 1001 "loop", 1002 "low_priority", 1003 "master_bind", 1004 "master_ssl_verify_server_cert", 1005 "match", 1006 "maxvalue", 1007 "mediumblob", 1008 "mediumint", 1009 "mediumtext", 1010 "middleint", 1011 "minute_microsecond", 1012 "minute_second", 1013 "mod", 1014 "modifies", 1015 "natural", 1016 "not", 1017 "no_write_to_binlog", 1018 "nth_value", 1019 "ntile", 1020 "null", 1021 "numeric", 1022 "of", 1023 "on", 1024 "optimize", 1025 "optimizer_costs", 1026 "option", 1027 "optionally", 1028 "or", 1029 "order", 1030 "out", 1031 "outer", 1032 "outfile", 1033 "over", 1034 "partition", 1035 "percent_rank", 1036 "precision", 1037 "primary", 1038 "procedure", 1039 "purge", 1040 "range", 1041 "rank", 1042 "read", 1043 "reads", 1044 "read_write", 1045 "real", 1046 "recursive", 1047 "references", 1048 "regexp", 1049 "release", 1050 "rename", 1051 "repeat", 1052 "replace", 1053 "require", 1054 "resignal", 1055 "restrict", 1056 "return", 1057 "revoke", 1058 "right", 1059 "rlike", 1060 "row", 1061 "rows", 1062 "row_number", 1063 "schema", 1064 "schemas", 1065 "second_microsecond", 1066 "select", 1067 "sensitive", 1068 "separator", 1069 "set", 1070 "show", 1071 "signal", 1072 "smallint", 1073 "spatial", 1074 "specific", 1075 "sql", 1076 "sqlexception", 1077 "sqlstate", 1078 "sqlwarning", 1079 "sql_big_result", 1080 "sql_calc_found_rows", 1081 "sql_small_result", 1082 "ssl", 1083 "starting", 1084 "stored", 1085 "straight_join", 1086 "system", 1087 "table", 1088 "terminated", 1089 "then", 1090 "tinyblob", 1091 "tinyint", 1092 "tinytext", 1093 "to", 1094 "trailing", 1095 "trigger", 1096 "true", 1097 "undo", 1098 "union", 1099 "unique", 1100 "unlock", 1101 "unsigned", 1102 "update", 1103 "usage", 1104 "use", 1105 "using", 1106 "utc_date", 1107 "utc_time", 1108 "utc_timestamp", 1109 "values", 1110 "varbinary", 1111 "varchar", 1112 "varcharacter", 1113 "varying", 1114 "virtual", 1115 "when", 1116 "where", 1117 "while", 1118 "window", 1119 "with", 1120 "write", 1121 "xor", 1122 "year_month", 1123 "zerofill", 1124 } 1125 1126 def array_sql(self, expression: exp.Array) -> str: 1127 self.unsupported("Arrays are not supported by MySQL") 1128 return self.function_fallback_sql(expression) 1129 1130 def arraycontainsall_sql(self, expression: exp.ArrayContainsAll) -> str: 1131 self.unsupported("Array operations are not supported by MySQL") 1132 return self.function_fallback_sql(expression) 1133 1134 def dpipe_sql(self, expression: exp.DPipe) -> str: 1135 return self.func("CONCAT", *expression.flatten()) 1136 1137 def extract_sql(self, expression: exp.Extract) -> str: 1138 unit = expression.name 1139 if unit and unit.lower() == "epoch": 1140 return self.func("UNIX_TIMESTAMP", expression.expression) 1141 1142 return super().extract_sql(expression) 1143 1144 def datatype_sql(self, expression: exp.DataType) -> str: 1145 if ( 1146 self.VARCHAR_REQUIRES_SIZE 1147 and expression.is_type(exp.DataType.Type.VARCHAR) 1148 and not expression.expressions 1149 ): 1150 # `VARCHAR` must always have a size - if it doesn't, we always generate `TEXT` 1151 return "TEXT" 1152 1153 # https://dev.mysql.com/doc/refman/8.0/en/numeric-type-syntax.html 1154 result = super().datatype_sql(expression) 1155 if expression.this in self.UNSIGNED_TYPE_MAPPING: 1156 result = f"{result} UNSIGNED" 1157 1158 return result 1159 1160 def jsonarraycontains_sql(self, expression: exp.JSONArrayContains) -> str: 1161 return f"{self.sql(expression, 'this')} MEMBER OF({self.sql(expression, 'expression')})" 1162 1163 def cast_sql(self, expression: exp.Cast, safe_prefix: t.Optional[str] = None) -> str: 1164 if expression.to.this in self.TIMESTAMP_FUNC_TYPES: 1165 return self.func("TIMESTAMP", expression.this) 1166 1167 to = self.CAST_MAPPING.get(expression.to.this) 1168 1169 if to: 1170 expression.to.set("this", to) 1171 return super().cast_sql(expression) 1172 1173 def show_sql(self, expression: exp.Show) -> str: 1174 this = f" {expression.name}" 1175 full = " FULL" if expression.args.get("full") else "" 1176 global_ = " GLOBAL" if expression.args.get("global") else "" 1177 1178 target = self.sql(expression, "target") 1179 target = f" {target}" if target else "" 1180 if expression.name in ("COLUMNS", "INDEX"): 1181 target = f" FROM{target}" 1182 elif expression.name == "GRANTS": 1183 target = f" FOR{target}" 1184 1185 db = self._prefixed_sql("FROM", expression, "db") 1186 1187 like = self._prefixed_sql("LIKE", expression, "like") 1188 where = self.sql(expression, "where") 1189 1190 types = self.expressions(expression, key="types") 1191 types = f" {types}" if types else types 1192 query = self._prefixed_sql("FOR QUERY", expression, "query") 1193 1194 if expression.name == "PROFILE": 1195 offset = self._prefixed_sql("OFFSET", expression, "offset") 1196 limit = self._prefixed_sql("LIMIT", expression, "limit") 1197 else: 1198 offset = "" 1199 limit = self._oldstyle_limit_sql(expression) 1200 1201 log = self._prefixed_sql("IN", expression, "log") 1202 position = self._prefixed_sql("FROM", expression, "position") 1203 1204 channel = self._prefixed_sql("FOR CHANNEL", expression, "channel") 1205 1206 if expression.name == "ENGINE": 1207 mutex_or_status = " MUTEX" if expression.args.get("mutex") else " STATUS" 1208 else: 1209 mutex_or_status = "" 1210 1211 return f"SHOW{full}{global_}{this}{target}{types}{db}{query}{log}{position}{channel}{mutex_or_status}{like}{where}{offset}{limit}" 1212 1213 def altercolumn_sql(self, expression: exp.AlterColumn) -> str: 1214 dtype = self.sql(expression, "dtype") 1215 if not dtype: 1216 return super().altercolumn_sql(expression) 1217 1218 this = self.sql(expression, "this") 1219 return f"MODIFY COLUMN {this} {dtype}" 1220 1221 def _prefixed_sql(self, prefix: str, expression: exp.Expression, arg: str) -> str: 1222 sql = self.sql(expression, arg) 1223 return f" {prefix} {sql}" if sql else "" 1224 1225 def _oldstyle_limit_sql(self, expression: exp.Show) -> str: 1226 limit = self.sql(expression, "limit") 1227 offset = self.sql(expression, "offset") 1228 if limit: 1229 limit_offset = f"{offset}, {limit}" if offset else limit 1230 return f" LIMIT {limit_offset}" 1231 return "" 1232 1233 def chr_sql(self, expression: exp.Chr) -> str: 1234 this = self.expressions(sqls=[expression.this] + expression.expressions) 1235 charset = expression.args.get("charset") 1236 using = f" USING {self.sql(charset)}" if charset else "" 1237 return f"CHAR({this}{using})" 1238 1239 def timestamptrunc_sql(self, expression: exp.TimestampTrunc) -> str: 1240 unit = expression.args.get("unit") 1241 1242 # Pick an old-enough date to avoid negative timestamp diffs 1243 start_ts = "'0000-01-01 00:00:00'" 1244 1245 # Source: https://stackoverflow.com/a/32955740 1246 timestamp_diff = build_date_delta(exp.TimestampDiff)([unit, start_ts, expression.this]) 1247 interval = exp.Interval(this=timestamp_diff, unit=unit) 1248 dateadd = build_date_delta_with_interval(exp.DateAdd)([start_ts, interval]) 1249 1250 return self.sql(dateadd) 1251 1252 def converttimezone_sql(self, expression: exp.ConvertTimezone) -> str: 1253 from_tz = expression.args.get("source_tz") 1254 to_tz = expression.args.get("target_tz") 1255 dt = expression.args.get("timestamp") 1256 1257 return self.func("CONVERT_TZ", dt, from_tz, to_tz) 1258 1259 def attimezone_sql(self, expression: exp.AtTimeZone) -> str: 1260 self.unsupported("AT TIME ZONE is not supported by MySQL") 1261 return self.sql(expression.this)
TIME_SPECIFIERS =
{'p', 'r', 'l', 's', 'i', 'h', 'k', 'S', 'f', 'T', 'I', 'H'}
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 "CHAR_LENGTH": exp.Length.from_arg_list, 300 "CHARACTER_LENGTH": exp.Length.from_arg_list, 301 "CONVERT_TZ": lambda args: exp.ConvertTimezone( 302 source_tz=seq_get(args, 1), target_tz=seq_get(args, 2), timestamp=seq_get(args, 0) 303 ), 304 "DATE": lambda args: exp.TsOrDsToDate(this=seq_get(args, 0)), 305 "DATE_ADD": build_date_delta_with_interval(exp.DateAdd), 306 "DATE_FORMAT": build_formatted_time(exp.TimeToStr, "mysql"), 307 "DATE_SUB": build_date_delta_with_interval(exp.DateSub), 308 "DAY": lambda args: exp.Day(this=exp.TsOrDsToDate(this=seq_get(args, 0))), 309 "DAYOFMONTH": lambda args: exp.DayOfMonth(this=exp.TsOrDsToDate(this=seq_get(args, 0))), 310 "DAYOFWEEK": lambda args: exp.DayOfWeek(this=exp.TsOrDsToDate(this=seq_get(args, 0))), 311 "DAYOFYEAR": lambda args: exp.DayOfYear(this=exp.TsOrDsToDate(this=seq_get(args, 0))), 312 "FORMAT": exp.NumberToStr.from_arg_list, 313 "FROM_UNIXTIME": build_formatted_time(exp.UnixToTime, "mysql"), 314 "ISNULL": isnull_to_is_null, 315 "LOCATE": locate_to_strposition, 316 "MAKETIME": exp.TimeFromParts.from_arg_list, 317 "MONTH": lambda args: exp.Month(this=exp.TsOrDsToDate(this=seq_get(args, 0))), 318 "MONTHNAME": lambda args: exp.TimeToStr( 319 this=exp.TsOrDsToDate(this=seq_get(args, 0)), 320 format=exp.Literal.string("%B"), 321 ), 322 "STR_TO_DATE": _str_to_date, 323 "TIMESTAMPDIFF": build_date_delta(exp.TimestampDiff), 324 "TO_DAYS": lambda args: exp.paren( 325 exp.DateDiff( 326 this=exp.TsOrDsToDate(this=seq_get(args, 0)), 327 expression=exp.TsOrDsToDate(this=exp.Literal.string("0000-01-01")), 328 unit=exp.var("DAY"), 329 ) 330 + 1 331 ), 332 "WEEK": lambda args: exp.Week( 333 this=exp.TsOrDsToDate(this=seq_get(args, 0)), mode=seq_get(args, 1) 334 ), 335 "WEEKOFYEAR": lambda args: exp.WeekOfYear(this=exp.TsOrDsToDate(this=seq_get(args, 0))), 336 "YEAR": lambda args: exp.Year(this=exp.TsOrDsToDate(this=seq_get(args, 0))), 337 } 338 339 FUNCTION_PARSERS = { 340 **parser.Parser.FUNCTION_PARSERS, 341 "CHAR": lambda self: self.expression( 342 exp.Chr, 343 expressions=self._parse_csv(self._parse_assignment), 344 charset=self._match(TokenType.USING) and self._parse_var(), 345 ), 346 "GROUP_CONCAT": lambda self: self._parse_group_concat(), 347 # https://dev.mysql.com/doc/refman/5.7/en/miscellaneous-functions.html#function_values 348 "VALUES": lambda self: self.expression( 349 exp.Anonymous, this="VALUES", expressions=[self._parse_id_var()] 350 ), 351 "JSON_VALUE": lambda self: self._parse_json_value(), 352 } 353 354 STATEMENT_PARSERS = { 355 **parser.Parser.STATEMENT_PARSERS, 356 TokenType.SHOW: lambda self: self._parse_show(), 357 } 358 359 SHOW_PARSERS = { 360 "BINARY LOGS": _show_parser("BINARY LOGS"), 361 "MASTER LOGS": _show_parser("BINARY LOGS"), 362 "BINLOG EVENTS": _show_parser("BINLOG EVENTS"), 363 "CHARACTER SET": _show_parser("CHARACTER SET"), 364 "CHARSET": _show_parser("CHARACTER SET"), 365 "COLLATION": _show_parser("COLLATION"), 366 "FULL COLUMNS": _show_parser("COLUMNS", target="FROM", full=True), 367 "COLUMNS": _show_parser("COLUMNS", target="FROM"), 368 "CREATE DATABASE": _show_parser("CREATE DATABASE", target=True), 369 "CREATE EVENT": _show_parser("CREATE EVENT", target=True), 370 "CREATE FUNCTION": _show_parser("CREATE FUNCTION", target=True), 371 "CREATE PROCEDURE": _show_parser("CREATE PROCEDURE", target=True), 372 "CREATE TABLE": _show_parser("CREATE TABLE", target=True), 373 "CREATE TRIGGER": _show_parser("CREATE TRIGGER", target=True), 374 "CREATE VIEW": _show_parser("CREATE VIEW", target=True), 375 "DATABASES": _show_parser("DATABASES"), 376 "SCHEMAS": _show_parser("DATABASES"), 377 "ENGINE": _show_parser("ENGINE", target=True), 378 "STORAGE ENGINES": _show_parser("ENGINES"), 379 "ENGINES": _show_parser("ENGINES"), 380 "ERRORS": _show_parser("ERRORS"), 381 "EVENTS": _show_parser("EVENTS"), 382 "FUNCTION CODE": _show_parser("FUNCTION CODE", target=True), 383 "FUNCTION STATUS": _show_parser("FUNCTION STATUS"), 384 "GRANTS": _show_parser("GRANTS", target="FOR"), 385 "INDEX": _show_parser("INDEX", target="FROM"), 386 "MASTER STATUS": _show_parser("MASTER STATUS"), 387 "OPEN TABLES": _show_parser("OPEN TABLES"), 388 "PLUGINS": _show_parser("PLUGINS"), 389 "PROCEDURE CODE": _show_parser("PROCEDURE CODE", target=True), 390 "PROCEDURE STATUS": _show_parser("PROCEDURE STATUS"), 391 "PRIVILEGES": _show_parser("PRIVILEGES"), 392 "FULL PROCESSLIST": _show_parser("PROCESSLIST", full=True), 393 "PROCESSLIST": _show_parser("PROCESSLIST"), 394 "PROFILE": _show_parser("PROFILE"), 395 "PROFILES": _show_parser("PROFILES"), 396 "RELAYLOG EVENTS": _show_parser("RELAYLOG EVENTS"), 397 "REPLICAS": _show_parser("REPLICAS"), 398 "SLAVE HOSTS": _show_parser("REPLICAS"), 399 "REPLICA STATUS": _show_parser("REPLICA STATUS"), 400 "SLAVE STATUS": _show_parser("REPLICA STATUS"), 401 "GLOBAL STATUS": _show_parser("STATUS", global_=True), 402 "SESSION STATUS": _show_parser("STATUS"), 403 "STATUS": _show_parser("STATUS"), 404 "TABLE STATUS": _show_parser("TABLE STATUS"), 405 "FULL TABLES": _show_parser("TABLES", full=True), 406 "TABLES": _show_parser("TABLES"), 407 "TRIGGERS": _show_parser("TRIGGERS"), 408 "GLOBAL VARIABLES": _show_parser("VARIABLES", global_=True), 409 "SESSION VARIABLES": _show_parser("VARIABLES"), 410 "VARIABLES": _show_parser("VARIABLES"), 411 "WARNINGS": _show_parser("WARNINGS"), 412 } 413 414 PROPERTY_PARSERS = { 415 **parser.Parser.PROPERTY_PARSERS, 416 "LOCK": lambda self: self._parse_property_assignment(exp.LockProperty), 417 } 418 419 SET_PARSERS = { 420 **parser.Parser.SET_PARSERS, 421 "PERSIST": lambda self: self._parse_set_item_assignment("PERSIST"), 422 "PERSIST_ONLY": lambda self: self._parse_set_item_assignment("PERSIST_ONLY"), 423 "CHARACTER SET": lambda self: self._parse_set_item_charset("CHARACTER SET"), 424 "CHARSET": lambda self: self._parse_set_item_charset("CHARACTER SET"), 425 "NAMES": lambda self: self._parse_set_item_names(), 426 } 427 428 CONSTRAINT_PARSERS = { 429 **parser.Parser.CONSTRAINT_PARSERS, 430 "FULLTEXT": lambda self: self._parse_index_constraint(kind="FULLTEXT"), 431 "INDEX": lambda self: self._parse_index_constraint(), 432 "KEY": lambda self: self._parse_index_constraint(), 433 "SPATIAL": lambda self: self._parse_index_constraint(kind="SPATIAL"), 434 } 435 436 ALTER_PARSERS = { 437 **parser.Parser.ALTER_PARSERS, 438 "MODIFY": lambda self: self._parse_alter_table_alter(), 439 } 440 441 SCHEMA_UNNAMED_CONSTRAINTS = { 442 *parser.Parser.SCHEMA_UNNAMED_CONSTRAINTS, 443 "FULLTEXT", 444 "INDEX", 445 "KEY", 446 "SPATIAL", 447 } 448 449 PROFILE_TYPES: parser.OPTIONS_TYPE = { 450 **dict.fromkeys(("ALL", "CPU", "IPC", "MEMORY", "SOURCE", "SWAPS"), tuple()), 451 "BLOCK": ("IO",), 452 "CONTEXT": ("SWITCHES",), 453 "PAGE": ("FAULTS",), 454 } 455 456 TYPE_TOKENS = { 457 *parser.Parser.TYPE_TOKENS, 458 TokenType.SET, 459 } 460 461 ENUM_TYPE_TOKENS = { 462 *parser.Parser.ENUM_TYPE_TOKENS, 463 TokenType.SET, 464 } 465 466 # SELECT [ ALL | DISTINCT | DISTINCTROW ] [ <OPERATION_MODIFIERS> ] 467 OPERATION_MODIFIERS = { 468 "HIGH_PRIORITY", 469 "STRAIGHT_JOIN", 470 "SQL_SMALL_RESULT", 471 "SQL_BIG_RESULT", 472 "SQL_BUFFER_RESULT", 473 "SQL_NO_CACHE", 474 "SQL_CALC_FOUND_ROWS", 475 } 476 477 LOG_DEFAULTS_TO_LN = True 478 STRING_ALIASES = True 479 VALUES_FOLLOWED_BY_PAREN = False 480 SUPPORTS_PARTITION_SELECTION = True 481 482 def _parse_primary_key_part(self) -> t.Optional[exp.Expression]: 483 this = self._parse_id_var() 484 if not self._match(TokenType.L_PAREN): 485 return this 486 487 expression = self._parse_number() 488 self._match_r_paren() 489 return self.expression(exp.ColumnPrefix, this=this, expression=expression) 490 491 def _parse_index_constraint( 492 self, kind: t.Optional[str] = None 493 ) -> exp.IndexColumnConstraint: 494 if kind: 495 self._match_texts(("INDEX", "KEY")) 496 497 this = self._parse_id_var(any_token=False) 498 index_type = self._match(TokenType.USING) and self._advance_any() and self._prev.text 499 expressions = self._parse_wrapped_csv(self._parse_ordered) 500 501 options = [] 502 while True: 503 if self._match_text_seq("KEY_BLOCK_SIZE"): 504 self._match(TokenType.EQ) 505 opt = exp.IndexConstraintOption(key_block_size=self._parse_number()) 506 elif self._match(TokenType.USING): 507 opt = exp.IndexConstraintOption(using=self._advance_any() and self._prev.text) 508 elif self._match_text_seq("WITH", "PARSER"): 509 opt = exp.IndexConstraintOption(parser=self._parse_var(any_token=True)) 510 elif self._match(TokenType.COMMENT): 511 opt = exp.IndexConstraintOption(comment=self._parse_string()) 512 elif self._match_text_seq("VISIBLE"): 513 opt = exp.IndexConstraintOption(visible=True) 514 elif self._match_text_seq("INVISIBLE"): 515 opt = exp.IndexConstraintOption(visible=False) 516 elif self._match_text_seq("ENGINE_ATTRIBUTE"): 517 self._match(TokenType.EQ) 518 opt = exp.IndexConstraintOption(engine_attr=self._parse_string()) 519 elif self._match_text_seq("SECONDARY_ENGINE_ATTRIBUTE"): 520 self._match(TokenType.EQ) 521 opt = exp.IndexConstraintOption(secondary_engine_attr=self._parse_string()) 522 else: 523 opt = None 524 525 if not opt: 526 break 527 528 options.append(opt) 529 530 return self.expression( 531 exp.IndexColumnConstraint, 532 this=this, 533 expressions=expressions, 534 kind=kind, 535 index_type=index_type, 536 options=options, 537 ) 538 539 def _parse_show_mysql( 540 self, 541 this: str, 542 target: bool | str = False, 543 full: t.Optional[bool] = None, 544 global_: t.Optional[bool] = None, 545 ) -> exp.Show: 546 if target: 547 if isinstance(target, str): 548 self._match_text_seq(target) 549 target_id = self._parse_id_var() 550 else: 551 target_id = None 552 553 log = self._parse_string() if self._match_text_seq("IN") else None 554 555 if this in ("BINLOG EVENTS", "RELAYLOG EVENTS"): 556 position = self._parse_number() if self._match_text_seq("FROM") else None 557 db = None 558 else: 559 position = None 560 db = None 561 562 if self._match(TokenType.FROM): 563 db = self._parse_id_var() 564 elif self._match(TokenType.DOT): 565 db = target_id 566 target_id = self._parse_id_var() 567 568 channel = self._parse_id_var() if self._match_text_seq("FOR", "CHANNEL") else None 569 570 like = self._parse_string() if self._match_text_seq("LIKE") else None 571 where = self._parse_where() 572 573 if this == "PROFILE": 574 types = self._parse_csv(lambda: self._parse_var_from_options(self.PROFILE_TYPES)) 575 query = self._parse_number() if self._match_text_seq("FOR", "QUERY") else None 576 offset = self._parse_number() if self._match_text_seq("OFFSET") else None 577 limit = self._parse_number() if self._match_text_seq("LIMIT") else None 578 else: 579 types, query = None, None 580 offset, limit = self._parse_oldstyle_limit() 581 582 mutex = True if self._match_text_seq("MUTEX") else None 583 mutex = False if self._match_text_seq("STATUS") else mutex 584 585 return self.expression( 586 exp.Show, 587 this=this, 588 target=target_id, 589 full=full, 590 log=log, 591 position=position, 592 db=db, 593 channel=channel, 594 like=like, 595 where=where, 596 types=types, 597 query=query, 598 offset=offset, 599 limit=limit, 600 mutex=mutex, 601 **{"global": global_}, # type: ignore 602 ) 603 604 def _parse_oldstyle_limit( 605 self, 606 ) -> t.Tuple[t.Optional[exp.Expression], t.Optional[exp.Expression]]: 607 limit = None 608 offset = None 609 if self._match_text_seq("LIMIT"): 610 parts = self._parse_csv(self._parse_number) 611 if len(parts) == 1: 612 limit = parts[0] 613 elif len(parts) == 2: 614 limit = parts[1] 615 offset = parts[0] 616 617 return offset, limit 618 619 def _parse_set_item_charset(self, kind: str) -> exp.Expression: 620 this = self._parse_string() or self._parse_unquoted_field() 621 return self.expression(exp.SetItem, this=this, kind=kind) 622 623 def _parse_set_item_names(self) -> exp.Expression: 624 charset = self._parse_string() or self._parse_unquoted_field() 625 if self._match_text_seq("COLLATE"): 626 collate = self._parse_string() or self._parse_unquoted_field() 627 else: 628 collate = None 629 630 return self.expression(exp.SetItem, this=charset, collate=collate, kind="NAMES") 631 632 def _parse_type( 633 self, parse_interval: bool = True, fallback_to_identifier: bool = False 634 ) -> t.Optional[exp.Expression]: 635 # mysql binary is special and can work anywhere, even in order by operations 636 # it operates like a no paren func 637 if self._match(TokenType.BINARY, advance=False): 638 data_type = self._parse_types(check_func=True, allow_identifiers=False) 639 640 if isinstance(data_type, exp.DataType): 641 return self.expression(exp.Cast, this=self._parse_column(), to=data_type) 642 643 return super()._parse_type( 644 parse_interval=parse_interval, fallback_to_identifier=fallback_to_identifier 645 ) 646 647 def _parse_group_concat(self) -> t.Optional[exp.Expression]: 648 def concat_exprs( 649 node: t.Optional[exp.Expression], exprs: t.List[exp.Expression] 650 ) -> exp.Expression: 651 if isinstance(node, exp.Distinct) and len(node.expressions) > 1: 652 concat_exprs = [ 653 self.expression(exp.Concat, expressions=node.expressions, safe=True) 654 ] 655 node.set("expressions", concat_exprs) 656 return node 657 if len(exprs) == 1: 658 return exprs[0] 659 return self.expression(exp.Concat, expressions=args, safe=True) 660 661 args = self._parse_csv(self._parse_lambda) 662 663 if args: 664 order = args[-1] if isinstance(args[-1], exp.Order) else None 665 666 if order: 667 # Order By is the last (or only) expression in the list and has consumed the 'expr' before it, 668 # remove 'expr' from exp.Order and add it back to args 669 args[-1] = order.this 670 order.set("this", concat_exprs(order.this, args)) 671 672 this = order or concat_exprs(args[0], args) 673 else: 674 this = None 675 676 separator = self._parse_field() if self._match(TokenType.SEPARATOR) else None 677 678 return self.expression(exp.GroupConcat, this=this, separator=separator) 679 680 def _parse_json_value(self) -> exp.JSONValue: 681 this = self._parse_bitwise() 682 self._match(TokenType.COMMA) 683 path = self._parse_bitwise() 684 685 returning = self._match(TokenType.RETURNING) and self._parse_type() 686 687 return self.expression( 688 exp.JSONValue, 689 this=this, 690 path=self.dialect.to_json_path(path), 691 returning=returning, 692 on_condition=self._parse_on_condition(), 693 ) 694 695 class Generator(generator.Generator): 696 INTERVAL_ALLOWS_PLURAL_FORM = False 697 LOCKING_READS_SUPPORTED = True 698 NULL_ORDERING_SUPPORTED = None 699 JOIN_HINTS = False 700 TABLE_HINTS = True 701 DUPLICATE_KEY_UPDATE_WITH_SET = False 702 QUERY_HINT_SEP = " " 703 VALUES_AS_TABLE = False 704 NVL2_SUPPORTED = False 705 LAST_DAY_SUPPORTS_DATE_PART = False 706 JSON_TYPE_REQUIRED_FOR_EXTRACTION = True 707 JSON_PATH_BRACKETED_KEY_SUPPORTED = False 708 JSON_KEY_VALUE_PAIR_SEP = "," 709 SUPPORTS_TO_NUMBER = False 710 PARSE_JSON_NAME: t.Optional[str] = None 711 PAD_FILL_PATTERN_IS_REQUIRED = True 712 WRAP_DERIVED_VALUES = False 713 VARCHAR_REQUIRES_SIZE = True 714 SUPPORTS_MEDIAN = False 715 716 TRANSFORMS = { 717 **generator.Generator.TRANSFORMS, 718 exp.ArrayAgg: rename_func("GROUP_CONCAT"), 719 exp.CurrentDate: no_paren_current_date_sql, 720 exp.DateDiff: _remove_ts_or_ds_to_date( 721 lambda self, e: self.func("DATEDIFF", e.this, e.expression), ("this", "expression") 722 ), 723 exp.DateAdd: _remove_ts_or_ds_to_date(date_add_sql("ADD")), 724 exp.DateStrToDate: datestrtodate_sql, 725 exp.DateSub: _remove_ts_or_ds_to_date(date_add_sql("SUB")), 726 exp.DateTrunc: _date_trunc_sql, 727 exp.Day: _remove_ts_or_ds_to_date(), 728 exp.DayOfMonth: _remove_ts_or_ds_to_date(rename_func("DAYOFMONTH")), 729 exp.DayOfWeek: _remove_ts_or_ds_to_date(rename_func("DAYOFWEEK")), 730 exp.DayOfYear: _remove_ts_or_ds_to_date(rename_func("DAYOFYEAR")), 731 exp.GroupConcat: lambda self, 732 e: f"""GROUP_CONCAT({self.sql(e, "this")} SEPARATOR {self.sql(e, "separator") or "','"})""", 733 exp.ILike: no_ilike_sql, 734 exp.JSONExtractScalar: arrow_json_extract_sql, 735 exp.Length: rename_func("CHAR_LENGTH"), 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: strposition_to_locate_sql, 753 exp.StrToDate: _str_to_date_sql, 754 exp.StrToTime: _str_to_date_sql, 755 exp.Stuff: rename_func("INSERT"), 756 exp.TableSample: no_tablesample_sql, 757 exp.TimeFromParts: rename_func("MAKETIME"), 758 exp.TimestampAdd: date_add_interval_sql("DATE", "ADD"), 759 exp.TimestampDiff: lambda self, e: self.func( 760 "TIMESTAMPDIFF", unit_to_var(e), e.expression, e.this 761 ), 762 exp.TimestampSub: date_add_interval_sql("DATE", "SUB"), 763 exp.TimeStrToUnix: rename_func("UNIX_TIMESTAMP"), 764 exp.TimeStrToTime: lambda self, e: timestrtotime_sql( 765 self, 766 e, 767 include_precision=not e.args.get("zone"), 768 ), 769 exp.TimeToStr: _remove_ts_or_ds_to_date( 770 lambda self, e: self.func("DATE_FORMAT", e.this, self.format_time(e)) 771 ), 772 exp.Trim: trim_sql, 773 exp.TryCast: no_trycast_sql, 774 exp.TsOrDsAdd: date_add_sql("ADD"), 775 exp.TsOrDsDiff: lambda self, e: self.func("DATEDIFF", e.this, e.expression), 776 exp.TsOrDsToDate: _ts_or_ds_to_date_sql, 777 exp.UnixToTime: _unix_to_time_sql, 778 exp.Week: _remove_ts_or_ds_to_date(), 779 exp.WeekOfYear: _remove_ts_or_ds_to_date(rename_func("WEEKOFYEAR")), 780 exp.Year: _remove_ts_or_ds_to_date(), 781 } 782 783 UNSIGNED_TYPE_MAPPING = { 784 exp.DataType.Type.UBIGINT: "BIGINT", 785 exp.DataType.Type.UINT: "INT", 786 exp.DataType.Type.UMEDIUMINT: "MEDIUMINT", 787 exp.DataType.Type.USMALLINT: "SMALLINT", 788 exp.DataType.Type.UTINYINT: "TINYINT", 789 exp.DataType.Type.UDECIMAL: "DECIMAL", 790 } 791 792 TIMESTAMP_TYPE_MAPPING = { 793 exp.DataType.Type.DATETIME2: "DATETIME", 794 exp.DataType.Type.SMALLDATETIME: "DATETIME", 795 exp.DataType.Type.TIMESTAMP: "DATETIME", 796 exp.DataType.Type.TIMESTAMPTZ: "TIMESTAMP", 797 exp.DataType.Type.TIMESTAMPLTZ: "TIMESTAMP", 798 } 799 800 TYPE_MAPPING = { 801 **generator.Generator.TYPE_MAPPING, 802 **UNSIGNED_TYPE_MAPPING, 803 **TIMESTAMP_TYPE_MAPPING, 804 } 805 806 TYPE_MAPPING.pop(exp.DataType.Type.MEDIUMTEXT) 807 TYPE_MAPPING.pop(exp.DataType.Type.LONGTEXT) 808 TYPE_MAPPING.pop(exp.DataType.Type.TINYTEXT) 809 TYPE_MAPPING.pop(exp.DataType.Type.MEDIUMBLOB) 810 TYPE_MAPPING.pop(exp.DataType.Type.LONGBLOB) 811 TYPE_MAPPING.pop(exp.DataType.Type.TINYBLOB) 812 813 PROPERTIES_LOCATION = { 814 **generator.Generator.PROPERTIES_LOCATION, 815 exp.TransientProperty: exp.Properties.Location.UNSUPPORTED, 816 exp.VolatileProperty: exp.Properties.Location.UNSUPPORTED, 817 } 818 819 LIMIT_FETCH = "LIMIT" 820 821 LIMIT_ONLY_LITERALS = True 822 823 CHAR_CAST_MAPPING = dict.fromkeys( 824 ( 825 exp.DataType.Type.LONGTEXT, 826 exp.DataType.Type.LONGBLOB, 827 exp.DataType.Type.MEDIUMBLOB, 828 exp.DataType.Type.MEDIUMTEXT, 829 exp.DataType.Type.TEXT, 830 exp.DataType.Type.TINYBLOB, 831 exp.DataType.Type.TINYTEXT, 832 exp.DataType.Type.VARCHAR, 833 ), 834 "CHAR", 835 ) 836 SIGNED_CAST_MAPPING = dict.fromkeys( 837 ( 838 exp.DataType.Type.BIGINT, 839 exp.DataType.Type.BOOLEAN, 840 exp.DataType.Type.INT, 841 exp.DataType.Type.SMALLINT, 842 exp.DataType.Type.TINYINT, 843 exp.DataType.Type.MEDIUMINT, 844 ), 845 "SIGNED", 846 ) 847 848 # MySQL doesn't support many datatypes in cast. 849 # https://dev.mysql.com/doc/refman/8.0/en/cast-functions.html#function_cast 850 CAST_MAPPING = { 851 **CHAR_CAST_MAPPING, 852 **SIGNED_CAST_MAPPING, 853 exp.DataType.Type.UBIGINT: "UNSIGNED", 854 } 855 856 TIMESTAMP_FUNC_TYPES = { 857 exp.DataType.Type.TIMESTAMPTZ, 858 exp.DataType.Type.TIMESTAMPLTZ, 859 } 860 861 # https://dev.mysql.com/doc/refman/8.0/en/keywords.html 862 RESERVED_KEYWORDS = { 863 "accessible", 864 "add", 865 "all", 866 "alter", 867 "analyze", 868 "and", 869 "as", 870 "asc", 871 "asensitive", 872 "before", 873 "between", 874 "bigint", 875 "binary", 876 "blob", 877 "both", 878 "by", 879 "call", 880 "cascade", 881 "case", 882 "change", 883 "char", 884 "character", 885 "check", 886 "collate", 887 "column", 888 "condition", 889 "constraint", 890 "continue", 891 "convert", 892 "create", 893 "cross", 894 "cube", 895 "cume_dist", 896 "current_date", 897 "current_time", 898 "current_timestamp", 899 "current_user", 900 "cursor", 901 "database", 902 "databases", 903 "day_hour", 904 "day_microsecond", 905 "day_minute", 906 "day_second", 907 "dec", 908 "decimal", 909 "declare", 910 "default", 911 "delayed", 912 "delete", 913 "dense_rank", 914 "desc", 915 "describe", 916 "deterministic", 917 "distinct", 918 "distinctrow", 919 "div", 920 "double", 921 "drop", 922 "dual", 923 "each", 924 "else", 925 "elseif", 926 "empty", 927 "enclosed", 928 "escaped", 929 "except", 930 "exists", 931 "exit", 932 "explain", 933 "false", 934 "fetch", 935 "first_value", 936 "float", 937 "float4", 938 "float8", 939 "for", 940 "force", 941 "foreign", 942 "from", 943 "fulltext", 944 "function", 945 "generated", 946 "get", 947 "grant", 948 "group", 949 "grouping", 950 "groups", 951 "having", 952 "high_priority", 953 "hour_microsecond", 954 "hour_minute", 955 "hour_second", 956 "if", 957 "ignore", 958 "in", 959 "index", 960 "infile", 961 "inner", 962 "inout", 963 "insensitive", 964 "insert", 965 "int", 966 "int1", 967 "int2", 968 "int3", 969 "int4", 970 "int8", 971 "integer", 972 "intersect", 973 "interval", 974 "into", 975 "io_after_gtids", 976 "io_before_gtids", 977 "is", 978 "iterate", 979 "join", 980 "json_table", 981 "key", 982 "keys", 983 "kill", 984 "lag", 985 "last_value", 986 "lateral", 987 "lead", 988 "leading", 989 "leave", 990 "left", 991 "like", 992 "limit", 993 "linear", 994 "lines", 995 "load", 996 "localtime", 997 "localtimestamp", 998 "lock", 999 "long", 1000 "longblob", 1001 "longtext", 1002 "loop", 1003 "low_priority", 1004 "master_bind", 1005 "master_ssl_verify_server_cert", 1006 "match", 1007 "maxvalue", 1008 "mediumblob", 1009 "mediumint", 1010 "mediumtext", 1011 "middleint", 1012 "minute_microsecond", 1013 "minute_second", 1014 "mod", 1015 "modifies", 1016 "natural", 1017 "not", 1018 "no_write_to_binlog", 1019 "nth_value", 1020 "ntile", 1021 "null", 1022 "numeric", 1023 "of", 1024 "on", 1025 "optimize", 1026 "optimizer_costs", 1027 "option", 1028 "optionally", 1029 "or", 1030 "order", 1031 "out", 1032 "outer", 1033 "outfile", 1034 "over", 1035 "partition", 1036 "percent_rank", 1037 "precision", 1038 "primary", 1039 "procedure", 1040 "purge", 1041 "range", 1042 "rank", 1043 "read", 1044 "reads", 1045 "read_write", 1046 "real", 1047 "recursive", 1048 "references", 1049 "regexp", 1050 "release", 1051 "rename", 1052 "repeat", 1053 "replace", 1054 "require", 1055 "resignal", 1056 "restrict", 1057 "return", 1058 "revoke", 1059 "right", 1060 "rlike", 1061 "row", 1062 "rows", 1063 "row_number", 1064 "schema", 1065 "schemas", 1066 "second_microsecond", 1067 "select", 1068 "sensitive", 1069 "separator", 1070 "set", 1071 "show", 1072 "signal", 1073 "smallint", 1074 "spatial", 1075 "specific", 1076 "sql", 1077 "sqlexception", 1078 "sqlstate", 1079 "sqlwarning", 1080 "sql_big_result", 1081 "sql_calc_found_rows", 1082 "sql_small_result", 1083 "ssl", 1084 "starting", 1085 "stored", 1086 "straight_join", 1087 "system", 1088 "table", 1089 "terminated", 1090 "then", 1091 "tinyblob", 1092 "tinyint", 1093 "tinytext", 1094 "to", 1095 "trailing", 1096 "trigger", 1097 "true", 1098 "undo", 1099 "union", 1100 "unique", 1101 "unlock", 1102 "unsigned", 1103 "update", 1104 "usage", 1105 "use", 1106 "using", 1107 "utc_date", 1108 "utc_time", 1109 "utc_timestamp", 1110 "values", 1111 "varbinary", 1112 "varchar", 1113 "varcharacter", 1114 "varying", 1115 "virtual", 1116 "when", 1117 "where", 1118 "while", 1119 "window", 1120 "with", 1121 "write", 1122 "xor", 1123 "year_month", 1124 "zerofill", 1125 } 1126 1127 def array_sql(self, expression: exp.Array) -> str: 1128 self.unsupported("Arrays are not supported by MySQL") 1129 return self.function_fallback_sql(expression) 1130 1131 def arraycontainsall_sql(self, expression: exp.ArrayContainsAll) -> str: 1132 self.unsupported("Array operations are not supported by MySQL") 1133 return self.function_fallback_sql(expression) 1134 1135 def dpipe_sql(self, expression: exp.DPipe) -> str: 1136 return self.func("CONCAT", *expression.flatten()) 1137 1138 def extract_sql(self, expression: exp.Extract) -> str: 1139 unit = expression.name 1140 if unit and unit.lower() == "epoch": 1141 return self.func("UNIX_TIMESTAMP", expression.expression) 1142 1143 return super().extract_sql(expression) 1144 1145 def datatype_sql(self, expression: exp.DataType) -> str: 1146 if ( 1147 self.VARCHAR_REQUIRES_SIZE 1148 and expression.is_type(exp.DataType.Type.VARCHAR) 1149 and not expression.expressions 1150 ): 1151 # `VARCHAR` must always have a size - if it doesn't, we always generate `TEXT` 1152 return "TEXT" 1153 1154 # https://dev.mysql.com/doc/refman/8.0/en/numeric-type-syntax.html 1155 result = super().datatype_sql(expression) 1156 if expression.this in self.UNSIGNED_TYPE_MAPPING: 1157 result = f"{result} UNSIGNED" 1158 1159 return result 1160 1161 def jsonarraycontains_sql(self, expression: exp.JSONArrayContains) -> str: 1162 return f"{self.sql(expression, 'this')} MEMBER OF({self.sql(expression, 'expression')})" 1163 1164 def cast_sql(self, expression: exp.Cast, safe_prefix: t.Optional[str] = None) -> str: 1165 if expression.to.this in self.TIMESTAMP_FUNC_TYPES: 1166 return self.func("TIMESTAMP", expression.this) 1167 1168 to = self.CAST_MAPPING.get(expression.to.this) 1169 1170 if to: 1171 expression.to.set("this", to) 1172 return super().cast_sql(expression) 1173 1174 def show_sql(self, expression: exp.Show) -> str: 1175 this = f" {expression.name}" 1176 full = " FULL" if expression.args.get("full") else "" 1177 global_ = " GLOBAL" if expression.args.get("global") else "" 1178 1179 target = self.sql(expression, "target") 1180 target = f" {target}" if target else "" 1181 if expression.name in ("COLUMNS", "INDEX"): 1182 target = f" FROM{target}" 1183 elif expression.name == "GRANTS": 1184 target = f" FOR{target}" 1185 1186 db = self._prefixed_sql("FROM", expression, "db") 1187 1188 like = self._prefixed_sql("LIKE", expression, "like") 1189 where = self.sql(expression, "where") 1190 1191 types = self.expressions(expression, key="types") 1192 types = f" {types}" if types else types 1193 query = self._prefixed_sql("FOR QUERY", expression, "query") 1194 1195 if expression.name == "PROFILE": 1196 offset = self._prefixed_sql("OFFSET", expression, "offset") 1197 limit = self._prefixed_sql("LIMIT", expression, "limit") 1198 else: 1199 offset = "" 1200 limit = self._oldstyle_limit_sql(expression) 1201 1202 log = self._prefixed_sql("IN", expression, "log") 1203 position = self._prefixed_sql("FROM", expression, "position") 1204 1205 channel = self._prefixed_sql("FOR CHANNEL", expression, "channel") 1206 1207 if expression.name == "ENGINE": 1208 mutex_or_status = " MUTEX" if expression.args.get("mutex") else " STATUS" 1209 else: 1210 mutex_or_status = "" 1211 1212 return f"SHOW{full}{global_}{this}{target}{types}{db}{query}{log}{position}{channel}{mutex_or_status}{like}{where}{offset}{limit}" 1213 1214 def altercolumn_sql(self, expression: exp.AlterColumn) -> str: 1215 dtype = self.sql(expression, "dtype") 1216 if not dtype: 1217 return super().altercolumn_sql(expression) 1218 1219 this = self.sql(expression, "this") 1220 return f"MODIFY COLUMN {this} {dtype}" 1221 1222 def _prefixed_sql(self, prefix: str, expression: exp.Expression, arg: str) -> str: 1223 sql = self.sql(expression, arg) 1224 return f" {prefix} {sql}" if sql else "" 1225 1226 def _oldstyle_limit_sql(self, expression: exp.Show) -> str: 1227 limit = self.sql(expression, "limit") 1228 offset = self.sql(expression, "offset") 1229 if limit: 1230 limit_offset = f"{offset}, {limit}" if offset else limit 1231 return f" LIMIT {limit_offset}" 1232 return "" 1233 1234 def chr_sql(self, expression: exp.Chr) -> str: 1235 this = self.expressions(sqls=[expression.this] + expression.expressions) 1236 charset = expression.args.get("charset") 1237 using = f" USING {self.sql(charset)}" if charset else "" 1238 return f"CHAR({this}{using})" 1239 1240 def timestamptrunc_sql(self, expression: exp.TimestampTrunc) -> str: 1241 unit = expression.args.get("unit") 1242 1243 # Pick an old-enough date to avoid negative timestamp diffs 1244 start_ts = "'0000-01-01 00:00:00'" 1245 1246 # Source: https://stackoverflow.com/a/32955740 1247 timestamp_diff = build_date_delta(exp.TimestampDiff)([unit, start_ts, expression.this]) 1248 interval = exp.Interval(this=timestamp_diff, unit=unit) 1249 dateadd = build_date_delta_with_interval(exp.DateAdd)([start_ts, interval]) 1250 1251 return self.sql(dateadd) 1252 1253 def converttimezone_sql(self, expression: exp.ConvertTimezone) -> str: 1254 from_tz = expression.args.get("source_tz") 1255 to_tz = expression.args.get("target_tz") 1256 dt = expression.args.get("timestamp") 1257 1258 return self.func("CONVERT_TZ", dt, from_tz, to_tz) 1259 1260 def attimezone_sql(self, expression: exp.AtTimeZone) -> str: 1261 self.unsupported("AT TIME ZONE is not supported by MySQL") 1262 return self.sql(expression.this)
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
- 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'>, '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.COMMAND: 'COMMAND'>, '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.EXECUTE: 'EXECUTE'>, <TokenType.COMMAND: 'COMMAND'>, <TokenType.FETCH: 'FETCH'>, <TokenType.RENAME: 'RENAME'>, <TokenType.REPLACE: 'REPLACE'>}
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
- 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 "CHAR_LENGTH": exp.Length.from_arg_list, 300 "CHARACTER_LENGTH": exp.Length.from_arg_list, 301 "CONVERT_TZ": lambda args: exp.ConvertTimezone( 302 source_tz=seq_get(args, 1), target_tz=seq_get(args, 2), timestamp=seq_get(args, 0) 303 ), 304 "DATE": lambda args: exp.TsOrDsToDate(this=seq_get(args, 0)), 305 "DATE_ADD": build_date_delta_with_interval(exp.DateAdd), 306 "DATE_FORMAT": build_formatted_time(exp.TimeToStr, "mysql"), 307 "DATE_SUB": build_date_delta_with_interval(exp.DateSub), 308 "DAY": lambda args: exp.Day(this=exp.TsOrDsToDate(this=seq_get(args, 0))), 309 "DAYOFMONTH": lambda args: exp.DayOfMonth(this=exp.TsOrDsToDate(this=seq_get(args, 0))), 310 "DAYOFWEEK": lambda args: exp.DayOfWeek(this=exp.TsOrDsToDate(this=seq_get(args, 0))), 311 "DAYOFYEAR": lambda args: exp.DayOfYear(this=exp.TsOrDsToDate(this=seq_get(args, 0))), 312 "FORMAT": exp.NumberToStr.from_arg_list, 313 "FROM_UNIXTIME": build_formatted_time(exp.UnixToTime, "mysql"), 314 "ISNULL": isnull_to_is_null, 315 "LOCATE": locate_to_strposition, 316 "MAKETIME": exp.TimeFromParts.from_arg_list, 317 "MONTH": lambda args: exp.Month(this=exp.TsOrDsToDate(this=seq_get(args, 0))), 318 "MONTHNAME": lambda args: exp.TimeToStr( 319 this=exp.TsOrDsToDate(this=seq_get(args, 0)), 320 format=exp.Literal.string("%B"), 321 ), 322 "STR_TO_DATE": _str_to_date, 323 "TIMESTAMPDIFF": build_date_delta(exp.TimestampDiff), 324 "TO_DAYS": lambda args: exp.paren( 325 exp.DateDiff( 326 this=exp.TsOrDsToDate(this=seq_get(args, 0)), 327 expression=exp.TsOrDsToDate(this=exp.Literal.string("0000-01-01")), 328 unit=exp.var("DAY"), 329 ) 330 + 1 331 ), 332 "WEEK": lambda args: exp.Week( 333 this=exp.TsOrDsToDate(this=seq_get(args, 0)), mode=seq_get(args, 1) 334 ), 335 "WEEKOFYEAR": lambda args: exp.WeekOfYear(this=exp.TsOrDsToDate(this=seq_get(args, 0))), 336 "YEAR": lambda args: exp.Year(this=exp.TsOrDsToDate(this=seq_get(args, 0))), 337 } 338 339 FUNCTION_PARSERS = { 340 **parser.Parser.FUNCTION_PARSERS, 341 "CHAR": lambda self: self.expression( 342 exp.Chr, 343 expressions=self._parse_csv(self._parse_assignment), 344 charset=self._match(TokenType.USING) and self._parse_var(), 345 ), 346 "GROUP_CONCAT": lambda self: self._parse_group_concat(), 347 # https://dev.mysql.com/doc/refman/5.7/en/miscellaneous-functions.html#function_values 348 "VALUES": lambda self: self.expression( 349 exp.Anonymous, this="VALUES", expressions=[self._parse_id_var()] 350 ), 351 "JSON_VALUE": lambda self: self._parse_json_value(), 352 } 353 354 STATEMENT_PARSERS = { 355 **parser.Parser.STATEMENT_PARSERS, 356 TokenType.SHOW: lambda self: self._parse_show(), 357 } 358 359 SHOW_PARSERS = { 360 "BINARY LOGS": _show_parser("BINARY LOGS"), 361 "MASTER LOGS": _show_parser("BINARY LOGS"), 362 "BINLOG EVENTS": _show_parser("BINLOG EVENTS"), 363 "CHARACTER SET": _show_parser("CHARACTER SET"), 364 "CHARSET": _show_parser("CHARACTER SET"), 365 "COLLATION": _show_parser("COLLATION"), 366 "FULL COLUMNS": _show_parser("COLUMNS", target="FROM", full=True), 367 "COLUMNS": _show_parser("COLUMNS", target="FROM"), 368 "CREATE DATABASE": _show_parser("CREATE DATABASE", target=True), 369 "CREATE EVENT": _show_parser("CREATE EVENT", target=True), 370 "CREATE FUNCTION": _show_parser("CREATE FUNCTION", target=True), 371 "CREATE PROCEDURE": _show_parser("CREATE PROCEDURE", target=True), 372 "CREATE TABLE": _show_parser("CREATE TABLE", target=True), 373 "CREATE TRIGGER": _show_parser("CREATE TRIGGER", target=True), 374 "CREATE VIEW": _show_parser("CREATE VIEW", target=True), 375 "DATABASES": _show_parser("DATABASES"), 376 "SCHEMAS": _show_parser("DATABASES"), 377 "ENGINE": _show_parser("ENGINE", target=True), 378 "STORAGE ENGINES": _show_parser("ENGINES"), 379 "ENGINES": _show_parser("ENGINES"), 380 "ERRORS": _show_parser("ERRORS"), 381 "EVENTS": _show_parser("EVENTS"), 382 "FUNCTION CODE": _show_parser("FUNCTION CODE", target=True), 383 "FUNCTION STATUS": _show_parser("FUNCTION STATUS"), 384 "GRANTS": _show_parser("GRANTS", target="FOR"), 385 "INDEX": _show_parser("INDEX", target="FROM"), 386 "MASTER STATUS": _show_parser("MASTER STATUS"), 387 "OPEN TABLES": _show_parser("OPEN TABLES"), 388 "PLUGINS": _show_parser("PLUGINS"), 389 "PROCEDURE CODE": _show_parser("PROCEDURE CODE", target=True), 390 "PROCEDURE STATUS": _show_parser("PROCEDURE STATUS"), 391 "PRIVILEGES": _show_parser("PRIVILEGES"), 392 "FULL PROCESSLIST": _show_parser("PROCESSLIST", full=True), 393 "PROCESSLIST": _show_parser("PROCESSLIST"), 394 "PROFILE": _show_parser("PROFILE"), 395 "PROFILES": _show_parser("PROFILES"), 396 "RELAYLOG EVENTS": _show_parser("RELAYLOG EVENTS"), 397 "REPLICAS": _show_parser("REPLICAS"), 398 "SLAVE HOSTS": _show_parser("REPLICAS"), 399 "REPLICA STATUS": _show_parser("REPLICA STATUS"), 400 "SLAVE STATUS": _show_parser("REPLICA STATUS"), 401 "GLOBAL STATUS": _show_parser("STATUS", global_=True), 402 "SESSION STATUS": _show_parser("STATUS"), 403 "STATUS": _show_parser("STATUS"), 404 "TABLE STATUS": _show_parser("TABLE STATUS"), 405 "FULL TABLES": _show_parser("TABLES", full=True), 406 "TABLES": _show_parser("TABLES"), 407 "TRIGGERS": _show_parser("TRIGGERS"), 408 "GLOBAL VARIABLES": _show_parser("VARIABLES", global_=True), 409 "SESSION VARIABLES": _show_parser("VARIABLES"), 410 "VARIABLES": _show_parser("VARIABLES"), 411 "WARNINGS": _show_parser("WARNINGS"), 412 } 413 414 PROPERTY_PARSERS = { 415 **parser.Parser.PROPERTY_PARSERS, 416 "LOCK": lambda self: self._parse_property_assignment(exp.LockProperty), 417 } 418 419 SET_PARSERS = { 420 **parser.Parser.SET_PARSERS, 421 "PERSIST": lambda self: self._parse_set_item_assignment("PERSIST"), 422 "PERSIST_ONLY": lambda self: self._parse_set_item_assignment("PERSIST_ONLY"), 423 "CHARACTER SET": lambda self: self._parse_set_item_charset("CHARACTER SET"), 424 "CHARSET": lambda self: self._parse_set_item_charset("CHARACTER SET"), 425 "NAMES": lambda self: self._parse_set_item_names(), 426 } 427 428 CONSTRAINT_PARSERS = { 429 **parser.Parser.CONSTRAINT_PARSERS, 430 "FULLTEXT": lambda self: self._parse_index_constraint(kind="FULLTEXT"), 431 "INDEX": lambda self: self._parse_index_constraint(), 432 "KEY": lambda self: self._parse_index_constraint(), 433 "SPATIAL": lambda self: self._parse_index_constraint(kind="SPATIAL"), 434 } 435 436 ALTER_PARSERS = { 437 **parser.Parser.ALTER_PARSERS, 438 "MODIFY": lambda self: self._parse_alter_table_alter(), 439 } 440 441 SCHEMA_UNNAMED_CONSTRAINTS = { 442 *parser.Parser.SCHEMA_UNNAMED_CONSTRAINTS, 443 "FULLTEXT", 444 "INDEX", 445 "KEY", 446 "SPATIAL", 447 } 448 449 PROFILE_TYPES: parser.OPTIONS_TYPE = { 450 **dict.fromkeys(("ALL", "CPU", "IPC", "MEMORY", "SOURCE", "SWAPS"), tuple()), 451 "BLOCK": ("IO",), 452 "CONTEXT": ("SWITCHES",), 453 "PAGE": ("FAULTS",), 454 } 455 456 TYPE_TOKENS = { 457 *parser.Parser.TYPE_TOKENS, 458 TokenType.SET, 459 } 460 461 ENUM_TYPE_TOKENS = { 462 *parser.Parser.ENUM_TYPE_TOKENS, 463 TokenType.SET, 464 } 465 466 # SELECT [ ALL | DISTINCT | DISTINCTROW ] [ <OPERATION_MODIFIERS> ] 467 OPERATION_MODIFIERS = { 468 "HIGH_PRIORITY", 469 "STRAIGHT_JOIN", 470 "SQL_SMALL_RESULT", 471 "SQL_BIG_RESULT", 472 "SQL_BUFFER_RESULT", 473 "SQL_NO_CACHE", 474 "SQL_CALC_FOUND_ROWS", 475 } 476 477 LOG_DEFAULTS_TO_LN = True 478 STRING_ALIASES = True 479 VALUES_FOLLOWED_BY_PAREN = False 480 SUPPORTS_PARTITION_SELECTION = True 481 482 def _parse_primary_key_part(self) -> t.Optional[exp.Expression]: 483 this = self._parse_id_var() 484 if not self._match(TokenType.L_PAREN): 485 return this 486 487 expression = self._parse_number() 488 self._match_r_paren() 489 return self.expression(exp.ColumnPrefix, this=this, expression=expression) 490 491 def _parse_index_constraint( 492 self, kind: t.Optional[str] = None 493 ) -> exp.IndexColumnConstraint: 494 if kind: 495 self._match_texts(("INDEX", "KEY")) 496 497 this = self._parse_id_var(any_token=False) 498 index_type = self._match(TokenType.USING) and self._advance_any() and self._prev.text 499 expressions = self._parse_wrapped_csv(self._parse_ordered) 500 501 options = [] 502 while True: 503 if self._match_text_seq("KEY_BLOCK_SIZE"): 504 self._match(TokenType.EQ) 505 opt = exp.IndexConstraintOption(key_block_size=self._parse_number()) 506 elif self._match(TokenType.USING): 507 opt = exp.IndexConstraintOption(using=self._advance_any() and self._prev.text) 508 elif self._match_text_seq("WITH", "PARSER"): 509 opt = exp.IndexConstraintOption(parser=self._parse_var(any_token=True)) 510 elif self._match(TokenType.COMMENT): 511 opt = exp.IndexConstraintOption(comment=self._parse_string()) 512 elif self._match_text_seq("VISIBLE"): 513 opt = exp.IndexConstraintOption(visible=True) 514 elif self._match_text_seq("INVISIBLE"): 515 opt = exp.IndexConstraintOption(visible=False) 516 elif self._match_text_seq("ENGINE_ATTRIBUTE"): 517 self._match(TokenType.EQ) 518 opt = exp.IndexConstraintOption(engine_attr=self._parse_string()) 519 elif self._match_text_seq("SECONDARY_ENGINE_ATTRIBUTE"): 520 self._match(TokenType.EQ) 521 opt = exp.IndexConstraintOption(secondary_engine_attr=self._parse_string()) 522 else: 523 opt = None 524 525 if not opt: 526 break 527 528 options.append(opt) 529 530 return self.expression( 531 exp.IndexColumnConstraint, 532 this=this, 533 expressions=expressions, 534 kind=kind, 535 index_type=index_type, 536 options=options, 537 ) 538 539 def _parse_show_mysql( 540 self, 541 this: str, 542 target: bool | str = False, 543 full: t.Optional[bool] = None, 544 global_: t.Optional[bool] = None, 545 ) -> exp.Show: 546 if target: 547 if isinstance(target, str): 548 self._match_text_seq(target) 549 target_id = self._parse_id_var() 550 else: 551 target_id = None 552 553 log = self._parse_string() if self._match_text_seq("IN") else None 554 555 if this in ("BINLOG EVENTS", "RELAYLOG EVENTS"): 556 position = self._parse_number() if self._match_text_seq("FROM") else None 557 db = None 558 else: 559 position = None 560 db = None 561 562 if self._match(TokenType.FROM): 563 db = self._parse_id_var() 564 elif self._match(TokenType.DOT): 565 db = target_id 566 target_id = self._parse_id_var() 567 568 channel = self._parse_id_var() if self._match_text_seq("FOR", "CHANNEL") else None 569 570 like = self._parse_string() if self._match_text_seq("LIKE") else None 571 where = self._parse_where() 572 573 if this == "PROFILE": 574 types = self._parse_csv(lambda: self._parse_var_from_options(self.PROFILE_TYPES)) 575 query = self._parse_number() if self._match_text_seq("FOR", "QUERY") else None 576 offset = self._parse_number() if self._match_text_seq("OFFSET") else None 577 limit = self._parse_number() if self._match_text_seq("LIMIT") else None 578 else: 579 types, query = None, None 580 offset, limit = self._parse_oldstyle_limit() 581 582 mutex = True if self._match_text_seq("MUTEX") else None 583 mutex = False if self._match_text_seq("STATUS") else mutex 584 585 return self.expression( 586 exp.Show, 587 this=this, 588 target=target_id, 589 full=full, 590 log=log, 591 position=position, 592 db=db, 593 channel=channel, 594 like=like, 595 where=where, 596 types=types, 597 query=query, 598 offset=offset, 599 limit=limit, 600 mutex=mutex, 601 **{"global": global_}, # type: ignore 602 ) 603 604 def _parse_oldstyle_limit( 605 self, 606 ) -> t.Tuple[t.Optional[exp.Expression], t.Optional[exp.Expression]]: 607 limit = None 608 offset = None 609 if self._match_text_seq("LIMIT"): 610 parts = self._parse_csv(self._parse_number) 611 if len(parts) == 1: 612 limit = parts[0] 613 elif len(parts) == 2: 614 limit = parts[1] 615 offset = parts[0] 616 617 return offset, limit 618 619 def _parse_set_item_charset(self, kind: str) -> exp.Expression: 620 this = self._parse_string() or self._parse_unquoted_field() 621 return self.expression(exp.SetItem, this=this, kind=kind) 622 623 def _parse_set_item_names(self) -> exp.Expression: 624 charset = self._parse_string() or self._parse_unquoted_field() 625 if self._match_text_seq("COLLATE"): 626 collate = self._parse_string() or self._parse_unquoted_field() 627 else: 628 collate = None 629 630 return self.expression(exp.SetItem, this=charset, collate=collate, kind="NAMES") 631 632 def _parse_type( 633 self, parse_interval: bool = True, fallback_to_identifier: bool = False 634 ) -> t.Optional[exp.Expression]: 635 # mysql binary is special and can work anywhere, even in order by operations 636 # it operates like a no paren func 637 if self._match(TokenType.BINARY, advance=False): 638 data_type = self._parse_types(check_func=True, allow_identifiers=False) 639 640 if isinstance(data_type, exp.DataType): 641 return self.expression(exp.Cast, this=self._parse_column(), to=data_type) 642 643 return super()._parse_type( 644 parse_interval=parse_interval, fallback_to_identifier=fallback_to_identifier 645 ) 646 647 def _parse_group_concat(self) -> t.Optional[exp.Expression]: 648 def concat_exprs( 649 node: t.Optional[exp.Expression], exprs: t.List[exp.Expression] 650 ) -> exp.Expression: 651 if isinstance(node, exp.Distinct) and len(node.expressions) > 1: 652 concat_exprs = [ 653 self.expression(exp.Concat, expressions=node.expressions, safe=True) 654 ] 655 node.set("expressions", concat_exprs) 656 return node 657 if len(exprs) == 1: 658 return exprs[0] 659 return self.expression(exp.Concat, expressions=args, safe=True) 660 661 args = self._parse_csv(self._parse_lambda) 662 663 if args: 664 order = args[-1] if isinstance(args[-1], exp.Order) else None 665 666 if order: 667 # Order By is the last (or only) expression in the list and has consumed the 'expr' before it, 668 # remove 'expr' from exp.Order and add it back to args 669 args[-1] = order.this 670 order.set("this", concat_exprs(order.this, args)) 671 672 this = order or concat_exprs(args[0], args) 673 else: 674 this = None 675 676 separator = self._parse_field() if self._match(TokenType.SEPARATOR) else None 677 678 return self.expression(exp.GroupConcat, this=this, separator=separator) 679 680 def _parse_json_value(self) -> exp.JSONValue: 681 this = self._parse_bitwise() 682 self._match(TokenType.COMMA) 683 path = self._parse_bitwise() 684 685 returning = self._match(TokenType.RETURNING) and self._parse_type() 686 687 return self.expression( 688 exp.JSONValue, 689 this=this, 690 path=self.dialect.to_json_path(path), 691 returning=returning, 692 on_condition=self._parse_on_condition(), 693 )
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.TIMESTAMP_NS: 'TIMESTAMP_NS'>, <TokenType.TABLE: 'TABLE'>, <TokenType.LONGTEXT: 'LONGTEXT'>, <TokenType.ARRAY: 'ARRAY'>, <TokenType.NESTED: 'NESTED'>, <TokenType.USMALLINT: 'USMALLINT'>, <TokenType.IPPREFIX: 'IPPREFIX'>, <TokenType.DOUBLE: 'DOUBLE'>, <TokenType.INT8MULTIRANGE: 'INT8MULTIRANGE'>, <TokenType.RLIKE: 'RLIKE'>, <TokenType.SIMPLEAGGREGATEFUNCTION: 'SIMPLEAGGREGATEFUNCTION'>, <TokenType.FIRST: 'FIRST'>, <TokenType.UDECIMAL: 'UDECIMAL'>, <TokenType.TSTZRANGE: 'TSTZRANGE'>, <TokenType.TIMESTAMPTZ: 'TIMESTAMPTZ'>, <TokenType.YEAR: 'YEAR'>, <TokenType.MEDIUMINT: 'MEDIUMINT'>, <TokenType.NCHAR: 'NCHAR'>, <TokenType.IPADDRESS: 'IPADDRESS'>, <TokenType.TINYINT: 'TINYINT'>, <TokenType.LIKE: 'LIKE'>, <TokenType.TIMESTAMP: 'TIMESTAMP'>, <TokenType.POLYGON: 'POLYGON'>, <TokenType.TINYBLOB: 'TINYBLOB'>, <TokenType.DECIMAL256: 'DECIMAL256'>, <TokenType.DATETIME2: 'DATETIME2'>, <TokenType.LEFT: 'LEFT'>, <TokenType.VARBINARY: 'VARBINARY'>, <TokenType.INT128: 'INT128'>, <TokenType.CURRENT_TIME: 'CURRENT_TIME'>, <TokenType.UMEDIUMINT: 'UMEDIUMINT'>, <TokenType.FIXEDSTRING: 'FIXEDSTRING'>, <TokenType.TRUNCATE: 'TRUNCATE'>, <TokenType.DECIMAL64: 'DECIMAL64'>, <TokenType.SCHEMA: 'SCHEMA'>, <TokenType.POINT: 'POINT'>, <TokenType.TIME: 'TIME'>, <TokenType.MEDIUMBLOB: 'MEDIUMBLOB'>, <TokenType.UINT: 'UINT'>, <TokenType.BIGINT: 'BIGINT'>, <TokenType.GEOMETRY: 'GEOMETRY'>, <TokenType.IPV6: 'IPV6'>, <TokenType.BOOLEAN: 'BOOLEAN'>, <TokenType.INT8RANGE: 'INT8RANGE'>, <TokenType.TIMESTAMP_MS: 'TIMESTAMP_MS'>, <TokenType.WINDOW: 'WINDOW'>, <TokenType.MEDIUMTEXT: 'MEDIUMTEXT'>, <TokenType.JSONB: 'JSONB'>, <TokenType.DATABASE: 'DATABASE'>, <TokenType.IPV4: 'IPV4'>, <TokenType.OFFSET: 'OFFSET'>, <TokenType.JSON: 'JSON'>, <TokenType.RING: 'RING'>, <TokenType.AGGREGATEFUNCTION: 'AGGREGATEFUNCTION'>, <TokenType.VAR: 'VAR'>, <TokenType.DATE32: 'DATE32'>, <TokenType.DATETIME64: 'DATETIME64'>, <TokenType.USERDEFINED: 'USERDEFINED'>, <TokenType.VECTOR: 'VECTOR'>, <TokenType.ROWVERSION: 'ROWVERSION'>, <TokenType.INET: 'INET'>, <TokenType.XML: 'XML'>, <TokenType.GLOB: 'GLOB'>, <TokenType.NUMRANGE: 'NUMRANGE'>, <TokenType.UNKNOWN: 'UNKNOWN'>, <TokenType.BINARY: 'BINARY'>, <TokenType.LINESTRING: 'LINESTRING'>, <TokenType.LOWCARDINALITY: 'LOWCARDINALITY'>, <TokenType.FILTER: 'FILTER'>, <TokenType.CURRENT_DATE: 'CURRENT_DATE'>, <TokenType.VARCHAR: 'VARCHAR'>, <TokenType.ILIKE: 'ILIKE'>, <TokenType.UTINYINT: 'UTINYINT'>, <TokenType.CURRENT_TIMESTAMP: 'CURRENT_TIMESTAMP'>, <TokenType.DATETIME: 'DATETIME'>, <TokenType.LONGBLOB: 'LONGBLOB'>, <TokenType.FLOAT: 'FLOAT'>, <TokenType.UINT256: 'UINT256'>, <TokenType.UINT128: 'UINT128'>, <TokenType.BPCHAR: 'BPCHAR'>, <TokenType.ROW: 'ROW'>, <TokenType.INT256: 'INT256'>, <TokenType.INT: 'INT'>, <TokenType.NULL: 'NULL'>, <TokenType.NULLABLE: 'NULLABLE'>, <TokenType.SUPER: 'SUPER'>, <TokenType.OBJECT_IDENTIFIER: 'OBJECT_IDENTIFIER'>, <TokenType.NAME: 'NAME'>, <TokenType.IMAGE: 'IMAGE'>, <TokenType.UNNEST: 'UNNEST'>, <TokenType.CURRENT_USER: 'CURRENT_USER'>, <TokenType.TSMULTIRANGE: 'TSMULTIRANGE'>, <TokenType.SOME: 'SOME'>, <TokenType.MAP: 'MAP'>, <TokenType.HSTORE: 'HSTORE'>, <TokenType.PSEUDO_TYPE: 'PSEUDO_TYPE'>, <TokenType.ISNULL: 'ISNULL'>, <TokenType.UNIQUEIDENTIFIER: 'UNIQUEIDENTIFIER'>, <TokenType.SERIAL: 'SERIAL'>, <TokenType.XOR: 'XOR'>, <TokenType.BIT: 'BIT'>, <TokenType.DATERANGE: 'DATERANGE'>, <TokenType.TIMESTAMPNTZ: 'TIMESTAMPNTZ'>, <TokenType.STRUCT: 'STRUCT'>, <TokenType.GEOGRAPHY: 'GEOGRAPHY'>, <TokenType.BIGSERIAL: 'BIGSERIAL'>, <TokenType.SMALLMONEY: 'SMALLMONEY'>, <TokenType.UNION: 'UNION'>, <TokenType.CURRENT_DATETIME: 'CURRENT_DATETIME'>, <TokenType.UBIGINT: 'UBIGINT'>, <TokenType.CHAR: 'CHAR'>, <TokenType.TIMESTAMP_S: 'TIMESTAMP_S'>, <TokenType.TSTZMULTIRANGE: 'TSTZMULTIRANGE'>, <TokenType.MONEY: 'MONEY'>, <TokenType.ALL: 'ALL'>, <TokenType.RIGHT: 'RIGHT'>, <TokenType.INT4RANGE: 'INT4RANGE'>, <TokenType.INDEX: 'INDEX'>, <TokenType.ENUM16: 'ENUM16'>, <TokenType.MULTILINESTRING: 'MULTILINESTRING'>, <TokenType.ENUM8: 'ENUM8'>, <TokenType.UUID: 'UUID'>, <TokenType.SMALLINT: 'SMALLINT'>, <TokenType.TSRANGE: 'TSRANGE'>, <TokenType.TDIGEST: 'TDIGEST'>, <TokenType.ENUM: 'ENUM'>, <TokenType.BIGDECIMAL: 'BIGDECIMAL'>, <TokenType.HLLSKETCH: 'HLLSKETCH'>, <TokenType.COLLATE: 'COLLATE'>, <TokenType.DATEMULTIRANGE: 'DATEMULTIRANGE'>, <TokenType.PRIMARY_KEY: 'PRIMARY_KEY'>, <TokenType.COMMAND: 'COMMAND'>, <TokenType.FORMAT: 'FORMAT'>, <TokenType.EXISTS: 'EXISTS'>, <TokenType.DECIMAL: 'DECIMAL'>, <TokenType.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, <TokenType.MULTIPOLYGON: 'MULTIPOLYGON'>, <TokenType.TEXT: 'TEXT'>, <TokenType.IDENTIFIER: 'IDENTIFIER'>, <TokenType.DECIMAL32: 'DECIMAL32'>, <TokenType.OBJECT: 'OBJECT'>, <TokenType.DATE: 'DATE'>, <TokenType.DECIMAL128: 'DECIMAL128'>, <TokenType.NVARCHAR: 'NVARCHAR'>, <TokenType.INSERT: 'INSERT'>, <TokenType.INT4MULTIRANGE: 'INT4MULTIRANGE'>, <TokenType.RANGE: 'RANGE'>, <TokenType.VALUES: 'VALUES'>, <TokenType.SMALLDATETIME: 'SMALLDATETIME'>, <TokenType.ANY: 'ANY'>, <TokenType.INTERVAL: 'INTERVAL'>, <TokenType.SEQUENCE: 'SEQUENCE'>, <TokenType.MERGE: 'MERGE'>, <TokenType.VARIANT: 'VARIANT'>, <TokenType.SMALLSERIAL: 'SMALLSERIAL'>, <TokenType.TINYTEXT: 'TINYTEXT'>, <TokenType.NEXT: 'NEXT'>, <TokenType.NUMMULTIRANGE: 'NUMMULTIRANGE'>, <TokenType.LIST: 'LIST'>, <TokenType.REPLACE: 'REPLACE'>, <TokenType.TIMETZ: 'TIMETZ'>}
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.TIMESTAMP_NS: 'TIMESTAMP_NS'>, <TokenType.TABLE: 'TABLE'>, <TokenType.LONGTEXT: 'LONGTEXT'>, <TokenType.ARRAY: 'ARRAY'>, <TokenType.NESTED: 'NESTED'>, <TokenType.USMALLINT: 'USMALLINT'>, <TokenType.IPPREFIX: 'IPPREFIX'>, <TokenType.DOUBLE: 'DOUBLE'>, <TokenType.PRAGMA: 'PRAGMA'>, <TokenType.INT8MULTIRANGE: 'INT8MULTIRANGE'>, <TokenType.SIMPLEAGGREGATEFUNCTION: 'SIMPLEAGGREGATEFUNCTION'>, <TokenType.FIRST: 'FIRST'>, <TokenType.UDECIMAL: 'UDECIMAL'>, <TokenType.TSTZRANGE: 'TSTZRANGE'>, <TokenType.TIMESTAMPTZ: 'TIMESTAMPTZ'>, <TokenType.YEAR: 'YEAR'>, <TokenType.SET: 'SET'>, <TokenType.MEDIUMINT: 'MEDIUMINT'>, <TokenType.NCHAR: 'NCHAR'>, <TokenType.IPADDRESS: 'IPADDRESS'>, <TokenType.BEGIN: 'BEGIN'>, <TokenType.TINYINT: 'TINYINT'>, <TokenType.UNIQUE: 'UNIQUE'>, <TokenType.TIMESTAMP: 'TIMESTAMP'>, <TokenType.OPERATOR: 'OPERATOR'>, <TokenType.POLYGON: 'POLYGON'>, <TokenType.TINYBLOB: 'TINYBLOB'>, <TokenType.DECIMAL256: 'DECIMAL256'>, <TokenType.DATETIME2: 'DATETIME2'>, <TokenType.VARBINARY: 'VARBINARY'>, <TokenType.INT128: 'INT128'>, <TokenType.CASE: 'CASE'>, <TokenType.END: 'END'>, <TokenType.UMEDIUMINT: 'UMEDIUMINT'>, <TokenType.FIXEDSTRING: 'FIXEDSTRING'>, <TokenType.TRUNCATE: 'TRUNCATE'>, <TokenType.CURRENT_TIME: 'CURRENT_TIME'>, <TokenType.DECIMAL64: 'DECIMAL64'>, <TokenType.REFERENCES: 'REFERENCES'>, <TokenType.SCHEMA: 'SCHEMA'>, <TokenType.POINT: 'POINT'>, <TokenType.TIME: 'TIME'>, <TokenType.MEDIUMBLOB: 'MEDIUMBLOB'>, <TokenType.UINT: 'UINT'>, <TokenType.ASC: 'ASC'>, <TokenType.BIGINT: 'BIGINT'>, <TokenType.GEOMETRY: 'GEOMETRY'>, <TokenType.COMMENT: 'COMMENT'>, <TokenType.IPV6: 'IPV6'>, <TokenType.BOOLEAN: 'BOOLEAN'>, <TokenType.FOREIGN_KEY: 'FOREIGN_KEY'>, <TokenType.DICTIONARY: 'DICTIONARY'>, <TokenType.INT8RANGE: 'INT8RANGE'>, <TokenType.STREAMLIT: 'STREAMLIT'>, <TokenType.TIMESTAMP_MS: 'TIMESTAMP_MS'>, <TokenType.ATTACH: 'ATTACH'>, <TokenType.MEDIUMTEXT: 'MEDIUMTEXT'>, <TokenType.FINAL: 'FINAL'>, <TokenType.CACHE: 'CACHE'>, <TokenType.COLUMN: 'COLUMN'>, <TokenType.JSONB: 'JSONB'>, <TokenType.DETACH: 'DETACH'>, <TokenType.DATABASE: 'DATABASE'>, <TokenType.IPV4: 'IPV4'>, <TokenType.PIVOT: 'PIVOT'>, <TokenType.JSON: 'JSON'>, <TokenType.SINK: 'SINK'>, <TokenType.RING: 'RING'>, <TokenType.AGGREGATEFUNCTION: 'AGGREGATEFUNCTION'>, <TokenType.VAR: 'VAR'>, <TokenType.DATE32: 'DATE32'>, <TokenType.DATETIME64: 'DATETIME64'>, <TokenType.USERDEFINED: 'USERDEFINED'>, <TokenType.ANTI: 'ANTI'>, <TokenType.SEMI: 'SEMI'>, <TokenType.VECTOR: 'VECTOR'>, <TokenType.ROWS: 'ROWS'>, <TokenType.ROWVERSION: 'ROWVERSION'>, <TokenType.DESCRIBE: 'DESCRIBE'>, <TokenType.INET: 'INET'>, <TokenType.CUBE: 'CUBE'>, <TokenType.XML: 'XML'>, <TokenType.UNPIVOT: 'UNPIVOT'>, <TokenType.SOURCE: 'SOURCE'>, <TokenType.NUMRANGE: 'NUMRANGE'>, <TokenType.UNKNOWN: 'UNKNOWN'>, <TokenType.COPY: 'COPY'>, <TokenType.BINARY: 'BINARY'>, <TokenType.LINESTRING: 'LINESTRING'>, <TokenType.LOWCARDINALITY: 'LOWCARDINALITY'>, <TokenType.DEFAULT: 'DEFAULT'>, <TokenType.FILTER: 'FILTER'>, <TokenType.CURRENT_DATE: 'CURRENT_DATE'>, <TokenType.VARCHAR: 'VARCHAR'>, <TokenType.UTINYINT: 'UTINYINT'>, <TokenType.LONGBLOB: 'LONGBLOB'>, <TokenType.FLOAT: 'FLOAT'>, <TokenType.UINT256: 'UINT256'>, <TokenType.BPCHAR: 'BPCHAR'>, <TokenType.UINT128: 'UINT128'>, <TokenType.INT256: 'INT256'>, <TokenType.DATETIME: 'DATETIME'>, <TokenType.ROW: 'ROW'>, <TokenType.INT: 'INT'>, <TokenType.HLLSKETCH: 'HLLSKETCH'>, <TokenType.NULL: 'NULL'>, <TokenType.RENAME: 'RENAME'>, <TokenType.NULLABLE: 'NULLABLE'>, <TokenType.SUPER: 'SUPER'>, <TokenType.OBJECT_IDENTIFIER: 'OBJECT_IDENTIFIER'>, <TokenType.NAME: 'NAME'>, <TokenType.IMAGE: 'IMAGE'>, <TokenType.UNNEST: 'UNNEST'>, <TokenType.CURRENT_USER: 'CURRENT_USER'>, <TokenType.KILL: 'KILL'>, <TokenType.TSMULTIRANGE: 'TSMULTIRANGE'>, <TokenType.SOME: 'SOME'>, <TokenType.RECURSIVE: 'RECURSIVE'>, <TokenType.MAP: 'MAP'>, <TokenType.CURRENT_TIMESTAMP: 'CURRENT_TIMESTAMP'>, <TokenType.HSTORE: 'HSTORE'>, <TokenType.PSEUDO_TYPE: 'PSEUDO_TYPE'>, <TokenType.ISNULL: 'ISNULL'>, <TokenType.OVERLAPS: 'OVERLAPS'>, <TokenType.UNIQUEIDENTIFIER: 'UNIQUEIDENTIFIER'>, <TokenType.LOAD: 'LOAD'>, <TokenType.TAG: 'TAG'>, <TokenType.SERIAL: 'SERIAL'>, <TokenType.BIT: 'BIT'>, <TokenType.DIV: 'DIV'>, <TokenType.DATERANGE: 'DATERANGE'>, <TokenType.IS: 'IS'>, <TokenType.TIMESTAMPNTZ: 'TIMESTAMPNTZ'>, <TokenType.MODEL: 'MODEL'>, <TokenType.ESCAPE: 'ESCAPE'>, <TokenType.STRUCT: 'STRUCT'>, <TokenType.CONSTRAINT: 'CONSTRAINT'>, <TokenType.GEOGRAPHY: 'GEOGRAPHY'>, <TokenType.BIGSERIAL: 'BIGSERIAL'>, <TokenType.SMALLMONEY: 'SMALLMONEY'>, <TokenType.AUTO_INCREMENT: 'AUTO_INCREMENT'>, <TokenType.ALL: 'ALL'>, <TokenType.UBIGINT: 'UBIGINT'>, <TokenType.CHAR: 'CHAR'>, <TokenType.TIMESTAMP_S: 'TIMESTAMP_S'>, <TokenType.TSTZMULTIRANGE: 'TSTZMULTIRANGE'>, <TokenType.MONEY: 'MONEY'>, <TokenType.FALSE: 'FALSE'>, <TokenType.CURRENT_DATETIME: 'CURRENT_DATETIME'>, <TokenType.INT4RANGE: 'INT4RANGE'>, <TokenType.INDEX: 'INDEX'>, <TokenType.ENUM16: 'ENUM16'>, <TokenType.MULTILINESTRING: 'MULTILINESTRING'>, <TokenType.ENUM8: 'ENUM8'>, <TokenType.UUID: 'UUID'>, <TokenType.STORAGE_INTEGRATION: 'STORAGE_INTEGRATION'>, <TokenType.KEEP: 'KEEP'>, <TokenType.SMALLINT: 'SMALLINT'>, <TokenType.PROCEDURE: 'PROCEDURE'>, <TokenType.TSRANGE: 'TSRANGE'>, <TokenType.TDIGEST: 'TDIGEST'>, <TokenType.DESC: 'DESC'>, <TokenType.ENUM: 'ENUM'>, <TokenType.BIGDECIMAL: 'BIGDECIMAL'>, <TokenType.COLLATE: 'COLLATE'>, <TokenType.DATEMULTIRANGE: 'DATEMULTIRANGE'>, <TokenType.EXECUTE: 'EXECUTE'>, <TokenType.COMMAND: 'COMMAND'>, <TokenType.WAREHOUSE: 'WAREHOUSE'>, <TokenType.FORMAT: 'FORMAT'>, <TokenType.EXISTS: 'EXISTS'>, <TokenType.TOP: 'TOP'>, <TokenType.DECIMAL: 'DECIMAL'>, <TokenType.PARTITION: 'PARTITION'>, <TokenType.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, <TokenType.MULTIPOLYGON: 'MULTIPOLYGON'>, <TokenType.TEXT: 'TEXT'>, <TokenType.IDENTIFIER: 'IDENTIFIER'>, <TokenType.DECIMAL32: 'DECIMAL32'>, <TokenType.OBJECT: 'OBJECT'>, <TokenType.DATE: 'DATE'>, <TokenType.DECIMAL128: 'DECIMAL128'>, <TokenType.SHOW: 'SHOW'>, <TokenType.SETTINGS: 'SETTINGS'>, <TokenType.NVARCHAR: 'NVARCHAR'>, <TokenType.INT4MULTIRANGE: 'INT4MULTIRANGE'>, <TokenType.VIEW: 'VIEW'>, <TokenType.ORDINALITY: 'ORDINALITY'>, <TokenType.VOLATILE: 'VOLATILE'>, <TokenType.RANGE: 'RANGE'>, <TokenType.ROLLUP: 'ROLLUP'>, <TokenType.SMALLDATETIME: 'SMALLDATETIME'>, <TokenType.PERCENT: 'PERCENT'>, <TokenType.TRUE: 'TRUE'>, <TokenType.ANY: 'ANY'>, <TokenType.INTERVAL: 'INTERVAL'>, <TokenType.SEQUENCE: 'SEQUENCE'>, <TokenType.MERGE: 'MERGE'>, <TokenType.COMMIT: 'COMMIT'>, <TokenType.REFRESH: 'REFRESH'>, <TokenType.TEMPORARY: 'TEMPORARY'>, <TokenType.VARIANT: 'VARIANT'>, <TokenType.SMALLSERIAL: 'SMALLSERIAL'>, <TokenType.TINYTEXT: 'TINYTEXT'>, <TokenType.DELETE: 'DELETE'>, <TokenType.NEXT: 'NEXT'>, <TokenType.OVERWRITE: 'OVERWRITE'>, <TokenType.FUNCTION: 'FUNCTION'>, <TokenType.NUMMULTIRANGE: 'NUMMULTIRANGE'>, <TokenType.LIST: 'LIST'>, <TokenType.UPDATE: 'UPDATE'>, <TokenType.REPLACE: 'REPLACE'>, <TokenType.TIMETZ: 'TIMETZ'>}
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_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': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Length'>>, 'LEN': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Length'>>, 'LEVENSHTEIN': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Levenshtein'>>, 'LIST': <bound method Func.from_arg_list of <class 'sqlglot.expressions.List'>>, 'LN': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Ln'>>, 'LOG': <function build_logarithm>, 'LOGICAL_AND': <bound method Func.from_arg_list of <class 'sqlglot.expressions.LogicalAnd'>>, 'BOOL_AND': <bound method Func.from_arg_list of <class 'sqlglot.expressions.LogicalAnd'>>, 'BOOLAND_AGG': <bound method Func.from_arg_list of <class 'sqlglot.expressions.LogicalAnd'>>, 'LOGICAL_OR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.LogicalOr'>>, 'BOOL_OR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.LogicalOr'>>, 'BOOLOR_AGG': <bound method Func.from_arg_list of <class 'sqlglot.expressions.LogicalOr'>>, 'LOWER': <function build_lower>, 'LCASE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Lower'>>, 'LOWER_HEX': <bound method Func.from_arg_list of <class 'sqlglot.expressions.LowerHex'>>, 'MD5': <bound method Func.from_arg_list of <class 'sqlglot.expressions.MD5'>>, 'MD5_DIGEST': <bound method Func.from_arg_list of <class 'sqlglot.expressions.MD5Digest'>>, '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'>>, '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>>, 'INSTR': <function Parser.<lambda>>, 'JSON_EXTRACT_PATH_TEXT': <function build_extract_json_with_path.<locals>._builder>, 'LIKE': <function build_like>, 'LOG2': <function Parser.<lambda>>, 'LOG10': <function Parser.<lambda>>, 'LPAD': <function Parser.<lambda>>, 'LEFTPAD': <function Parser.<lambda>>, 'LTRIM': <function Parser.<lambda>>, 'MOD': <function build_mod>, 'RIGHTPAD': <function Parser.<lambda>>, 'RPAD': <function Parser.<lambda>>, 'RTRIM': <function Parser.<lambda>>, 'SCOPE_RESOLUTION': <function Parser.<lambda>>, 'TO_HEX': <function build_hex>, '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'>>, '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>, 'LOCATE': <function locate_to_strposition>, 'MAKETIME': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimeFromParts'>>, 'MONTHNAME': <function MySQL.Parser.<lambda>>}
FUNCTION_PARSERS =
{'CAST': <function Parser.<lambda>>, 'CONVERT': <function Parser.<lambda>>, 'DECODE': <function Parser.<lambda>>, 'EXTRACT': <function Parser.<lambda>>, 'GAP_FILL': <function Parser.<lambda>>, 'JSON_OBJECT': <function Parser.<lambda>>, 'JSON_OBJECTAGG': <function Parser.<lambda>>, 'JSON_TABLE': <function Parser.<lambda>>, 'MATCH': <function Parser.<lambda>>, '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>>, '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.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.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 =
{'PRIMARY KEY', 'FULLTEXT', 'SPATIAL', 'LIKE', 'CHECK', 'KEY', 'EXCLUDE', 'UNIQUE', 'FOREIGN KEY', 'WATERMARK', 'PERIOD', 'INDEX'}
PROFILE_TYPES: Dict[str, Sequence[Union[Sequence[str], str]]] =
{'ALL': (), 'CPU': (), 'IPC': (), 'MEMORY': (), 'SOURCE': (), 'SWAPS': (), 'BLOCK': ('IO',), 'CONTEXT': ('SWITCHES',), 'PAGE': ('FAULTS',)}
TYPE_TOKENS =
{<TokenType.TIMESTAMP_NS: 'TIMESTAMP_NS'>, <TokenType.TSMULTIRANGE: 'TSMULTIRANGE'>, <TokenType.LONGTEXT: 'LONGTEXT'>, <TokenType.ARRAY: 'ARRAY'>, <TokenType.NESTED: 'NESTED'>, <TokenType.USMALLINT: 'USMALLINT'>, <TokenType.IPPREFIX: 'IPPREFIX'>, <TokenType.DOUBLE: 'DOUBLE'>, <TokenType.INT8MULTIRANGE: 'INT8MULTIRANGE'>, <TokenType.SIMPLEAGGREGATEFUNCTION: 'SIMPLEAGGREGATEFUNCTION'>, <TokenType.MAP: 'MAP'>, <TokenType.HSTORE: 'HSTORE'>, <TokenType.PSEUDO_TYPE: 'PSEUDO_TYPE'>, <TokenType.UDECIMAL: 'UDECIMAL'>, <TokenType.TSTZRANGE: 'TSTZRANGE'>, <TokenType.UNIQUEIDENTIFIER: 'UNIQUEIDENTIFIER'>, <TokenType.SERIAL: 'SERIAL'>, <TokenType.TIMESTAMPTZ: 'TIMESTAMPTZ'>, <TokenType.YEAR: 'YEAR'>, <TokenType.BIT: 'BIT'>, <TokenType.SET: 'SET'>, <TokenType.DATERANGE: 'DATERANGE'>, <TokenType.MEDIUMINT: 'MEDIUMINT'>, <TokenType.TIMESTAMPNTZ: 'TIMESTAMPNTZ'>, <TokenType.NCHAR: 'NCHAR'>, <TokenType.IPADDRESS: 'IPADDRESS'>, <TokenType.TINYINT: 'TINYINT'>, <TokenType.STRUCT: 'STRUCT'>, <TokenType.TIMESTAMP: 'TIMESTAMP'>, <TokenType.POLYGON: 'POLYGON'>, <TokenType.TINYBLOB: 'TINYBLOB'>, <TokenType.DECIMAL256: 'DECIMAL256'>, <TokenType.DATETIME2: 'DATETIME2'>, <TokenType.GEOGRAPHY: 'GEOGRAPHY'>, <TokenType.VARBINARY: 'VARBINARY'>, <TokenType.INT128: 'INT128'>, <TokenType.BIGSERIAL: 'BIGSERIAL'>, <TokenType.SMALLMONEY: 'SMALLMONEY'>, <TokenType.UNION: 'UNION'>, <TokenType.UMEDIUMINT: 'UMEDIUMINT'>, <TokenType.FIXEDSTRING: 'FIXEDSTRING'>, <TokenType.DECIMAL64: 'DECIMAL64'>, <TokenType.POINT: 'POINT'>, <TokenType.TIME: 'TIME'>, <TokenType.UBIGINT: 'UBIGINT'>, <TokenType.MEDIUMBLOB: 'MEDIUMBLOB'>, <TokenType.UINT: 'UINT'>, <TokenType.CHAR: 'CHAR'>, <TokenType.BIGINT: 'BIGINT'>, <TokenType.TIMESTAMP_S: 'TIMESTAMP_S'>, <TokenType.TSTZMULTIRANGE: 'TSTZMULTIRANGE'>, <TokenType.MONEY: 'MONEY'>, <TokenType.GEOMETRY: 'GEOMETRY'>, <TokenType.INT4RANGE: 'INT4RANGE'>, <TokenType.ENUM16: 'ENUM16'>, <TokenType.MULTILINESTRING: 'MULTILINESTRING'>, <TokenType.ENUM8: 'ENUM8'>, <TokenType.UUID: 'UUID'>, <TokenType.SMALLINT: 'SMALLINT'>, <TokenType.IPV6: 'IPV6'>, <TokenType.BOOLEAN: 'BOOLEAN'>, <TokenType.TSRANGE: 'TSRANGE'>, <TokenType.TDIGEST: 'TDIGEST'>, <TokenType.ENUM: 'ENUM'>, <TokenType.BIGDECIMAL: 'BIGDECIMAL'>, <TokenType.INT8RANGE: 'INT8RANGE'>, <TokenType.TIMESTAMP_MS: 'TIMESTAMP_MS'>, <TokenType.DATEMULTIRANGE: 'DATEMULTIRANGE'>, <TokenType.MEDIUMTEXT: 'MEDIUMTEXT'>, <TokenType.JSONB: 'JSONB'>, <TokenType.DECIMAL: 'DECIMAL'>, <TokenType.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, <TokenType.MULTIPOLYGON: 'MULTIPOLYGON'>, <TokenType.IPV4: 'IPV4'>, <TokenType.JSON: 'JSON'>, <TokenType.TEXT: 'TEXT'>, <TokenType.RING: 'RING'>, <TokenType.AGGREGATEFUNCTION: 'AGGREGATEFUNCTION'>, <TokenType.DECIMAL32: 'DECIMAL32'>, <TokenType.DATE32: 'DATE32'>, <TokenType.DATETIME64: 'DATETIME64'>, <TokenType.USERDEFINED: 'USERDEFINED'>, <TokenType.OBJECT: 'OBJECT'>, <TokenType.DATE: 'DATE'>, <TokenType.DECIMAL128: 'DECIMAL128'>, <TokenType.NVARCHAR: 'NVARCHAR'>, <TokenType.INT4MULTIRANGE: 'INT4MULTIRANGE'>, <TokenType.VECTOR: 'VECTOR'>, <TokenType.ROWVERSION: 'ROWVERSION'>, <TokenType.INET: 'INET'>, <TokenType.XML: 'XML'>, <TokenType.RANGE: 'RANGE'>, <TokenType.SMALLDATETIME: 'SMALLDATETIME'>, <TokenType.NUMRANGE: 'NUMRANGE'>, <TokenType.UNKNOWN: 'UNKNOWN'>, <TokenType.BINARY: 'BINARY'>, <TokenType.LINESTRING: 'LINESTRING'>, <TokenType.LOWCARDINALITY: 'LOWCARDINALITY'>, <TokenType.INTERVAL: 'INTERVAL'>, <TokenType.VARCHAR: 'VARCHAR'>, <TokenType.VARIANT: 'VARIANT'>, <TokenType.SMALLSERIAL: 'SMALLSERIAL'>, <TokenType.TINYTEXT: 'TINYTEXT'>, <TokenType.UTINYINT: 'UTINYINT'>, <TokenType.LONGBLOB: 'LONGBLOB'>, <TokenType.FLOAT: 'FLOAT'>, <TokenType.UINT256: 'UINT256'>, <TokenType.UINT128: 'UINT128'>, <TokenType.BPCHAR: 'BPCHAR'>, <TokenType.INT256: 'INT256'>, <TokenType.DATETIME: 'DATETIME'>, <TokenType.INT: 'INT'>, <TokenType.HLLSKETCH: 'HLLSKETCH'>, <TokenType.NULL: 'NULL'>, <TokenType.NULLABLE: 'NULLABLE'>, <TokenType.SUPER: 'SUPER'>, <TokenType.OBJECT_IDENTIFIER: 'OBJECT_IDENTIFIER'>, <TokenType.NUMMULTIRANGE: 'NUMMULTIRANGE'>, <TokenType.LIST: 'LIST'>, <TokenType.NAME: 'NAME'>, <TokenType.IMAGE: 'IMAGE'>, <TokenType.TIMETZ: 'TIMETZ'>}
ENUM_TYPE_TOKENS =
{<TokenType.ENUM8: 'ENUM8'>, <TokenType.ENUM: 'ENUM'>, <TokenType.SET: 'SET'>, <TokenType.ENUM16: 'ENUM16'>}
OPERATION_MODIFIERS =
{'SQL_SMALL_RESULT', 'HIGH_PRIORITY', 'SQL_NO_CACHE', 'STRAIGHT_JOIN', 'SQL_CALC_FOUND_ROWS', 'SQL_BIG_RESULT', 'SQL_BUFFER_RESULT'}
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
- 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
- error_level
- error_message_context
- max_errors
- dialect
- reset
- parse
- parse_into
- check_errors
- raise_error
- expression
- validate_expression
- errors
- sql
695 class Generator(generator.Generator): 696 INTERVAL_ALLOWS_PLURAL_FORM = False 697 LOCKING_READS_SUPPORTED = True 698 NULL_ORDERING_SUPPORTED = None 699 JOIN_HINTS = False 700 TABLE_HINTS = True 701 DUPLICATE_KEY_UPDATE_WITH_SET = False 702 QUERY_HINT_SEP = " " 703 VALUES_AS_TABLE = False 704 NVL2_SUPPORTED = False 705 LAST_DAY_SUPPORTS_DATE_PART = False 706 JSON_TYPE_REQUIRED_FOR_EXTRACTION = True 707 JSON_PATH_BRACKETED_KEY_SUPPORTED = False 708 JSON_KEY_VALUE_PAIR_SEP = "," 709 SUPPORTS_TO_NUMBER = False 710 PARSE_JSON_NAME: t.Optional[str] = None 711 PAD_FILL_PATTERN_IS_REQUIRED = True 712 WRAP_DERIVED_VALUES = False 713 VARCHAR_REQUIRES_SIZE = True 714 SUPPORTS_MEDIAN = False 715 716 TRANSFORMS = { 717 **generator.Generator.TRANSFORMS, 718 exp.ArrayAgg: rename_func("GROUP_CONCAT"), 719 exp.CurrentDate: no_paren_current_date_sql, 720 exp.DateDiff: _remove_ts_or_ds_to_date( 721 lambda self, e: self.func("DATEDIFF", e.this, e.expression), ("this", "expression") 722 ), 723 exp.DateAdd: _remove_ts_or_ds_to_date(date_add_sql("ADD")), 724 exp.DateStrToDate: datestrtodate_sql, 725 exp.DateSub: _remove_ts_or_ds_to_date(date_add_sql("SUB")), 726 exp.DateTrunc: _date_trunc_sql, 727 exp.Day: _remove_ts_or_ds_to_date(), 728 exp.DayOfMonth: _remove_ts_or_ds_to_date(rename_func("DAYOFMONTH")), 729 exp.DayOfWeek: _remove_ts_or_ds_to_date(rename_func("DAYOFWEEK")), 730 exp.DayOfYear: _remove_ts_or_ds_to_date(rename_func("DAYOFYEAR")), 731 exp.GroupConcat: lambda self, 732 e: f"""GROUP_CONCAT({self.sql(e, "this")} SEPARATOR {self.sql(e, "separator") or "','"})""", 733 exp.ILike: no_ilike_sql, 734 exp.JSONExtractScalar: arrow_json_extract_sql, 735 exp.Length: rename_func("CHAR_LENGTH"), 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: strposition_to_locate_sql, 753 exp.StrToDate: _str_to_date_sql, 754 exp.StrToTime: _str_to_date_sql, 755 exp.Stuff: rename_func("INSERT"), 756 exp.TableSample: no_tablesample_sql, 757 exp.TimeFromParts: rename_func("MAKETIME"), 758 exp.TimestampAdd: date_add_interval_sql("DATE", "ADD"), 759 exp.TimestampDiff: lambda self, e: self.func( 760 "TIMESTAMPDIFF", unit_to_var(e), e.expression, e.this 761 ), 762 exp.TimestampSub: date_add_interval_sql("DATE", "SUB"), 763 exp.TimeStrToUnix: rename_func("UNIX_TIMESTAMP"), 764 exp.TimeStrToTime: lambda self, e: timestrtotime_sql( 765 self, 766 e, 767 include_precision=not e.args.get("zone"), 768 ), 769 exp.TimeToStr: _remove_ts_or_ds_to_date( 770 lambda self, e: self.func("DATE_FORMAT", e.this, self.format_time(e)) 771 ), 772 exp.Trim: trim_sql, 773 exp.TryCast: no_trycast_sql, 774 exp.TsOrDsAdd: date_add_sql("ADD"), 775 exp.TsOrDsDiff: lambda self, e: self.func("DATEDIFF", e.this, e.expression), 776 exp.TsOrDsToDate: _ts_or_ds_to_date_sql, 777 exp.UnixToTime: _unix_to_time_sql, 778 exp.Week: _remove_ts_or_ds_to_date(), 779 exp.WeekOfYear: _remove_ts_or_ds_to_date(rename_func("WEEKOFYEAR")), 780 exp.Year: _remove_ts_or_ds_to_date(), 781 } 782 783 UNSIGNED_TYPE_MAPPING = { 784 exp.DataType.Type.UBIGINT: "BIGINT", 785 exp.DataType.Type.UINT: "INT", 786 exp.DataType.Type.UMEDIUMINT: "MEDIUMINT", 787 exp.DataType.Type.USMALLINT: "SMALLINT", 788 exp.DataType.Type.UTINYINT: "TINYINT", 789 exp.DataType.Type.UDECIMAL: "DECIMAL", 790 } 791 792 TIMESTAMP_TYPE_MAPPING = { 793 exp.DataType.Type.DATETIME2: "DATETIME", 794 exp.DataType.Type.SMALLDATETIME: "DATETIME", 795 exp.DataType.Type.TIMESTAMP: "DATETIME", 796 exp.DataType.Type.TIMESTAMPTZ: "TIMESTAMP", 797 exp.DataType.Type.TIMESTAMPLTZ: "TIMESTAMP", 798 } 799 800 TYPE_MAPPING = { 801 **generator.Generator.TYPE_MAPPING, 802 **UNSIGNED_TYPE_MAPPING, 803 **TIMESTAMP_TYPE_MAPPING, 804 } 805 806 TYPE_MAPPING.pop(exp.DataType.Type.MEDIUMTEXT) 807 TYPE_MAPPING.pop(exp.DataType.Type.LONGTEXT) 808 TYPE_MAPPING.pop(exp.DataType.Type.TINYTEXT) 809 TYPE_MAPPING.pop(exp.DataType.Type.MEDIUMBLOB) 810 TYPE_MAPPING.pop(exp.DataType.Type.LONGBLOB) 811 TYPE_MAPPING.pop(exp.DataType.Type.TINYBLOB) 812 813 PROPERTIES_LOCATION = { 814 **generator.Generator.PROPERTIES_LOCATION, 815 exp.TransientProperty: exp.Properties.Location.UNSUPPORTED, 816 exp.VolatileProperty: exp.Properties.Location.UNSUPPORTED, 817 } 818 819 LIMIT_FETCH = "LIMIT" 820 821 LIMIT_ONLY_LITERALS = True 822 823 CHAR_CAST_MAPPING = dict.fromkeys( 824 ( 825 exp.DataType.Type.LONGTEXT, 826 exp.DataType.Type.LONGBLOB, 827 exp.DataType.Type.MEDIUMBLOB, 828 exp.DataType.Type.MEDIUMTEXT, 829 exp.DataType.Type.TEXT, 830 exp.DataType.Type.TINYBLOB, 831 exp.DataType.Type.TINYTEXT, 832 exp.DataType.Type.VARCHAR, 833 ), 834 "CHAR", 835 ) 836 SIGNED_CAST_MAPPING = dict.fromkeys( 837 ( 838 exp.DataType.Type.BIGINT, 839 exp.DataType.Type.BOOLEAN, 840 exp.DataType.Type.INT, 841 exp.DataType.Type.SMALLINT, 842 exp.DataType.Type.TINYINT, 843 exp.DataType.Type.MEDIUMINT, 844 ), 845 "SIGNED", 846 ) 847 848 # MySQL doesn't support many datatypes in cast. 849 # https://dev.mysql.com/doc/refman/8.0/en/cast-functions.html#function_cast 850 CAST_MAPPING = { 851 **CHAR_CAST_MAPPING, 852 **SIGNED_CAST_MAPPING, 853 exp.DataType.Type.UBIGINT: "UNSIGNED", 854 } 855 856 TIMESTAMP_FUNC_TYPES = { 857 exp.DataType.Type.TIMESTAMPTZ, 858 exp.DataType.Type.TIMESTAMPLTZ, 859 } 860 861 # https://dev.mysql.com/doc/refman/8.0/en/keywords.html 862 RESERVED_KEYWORDS = { 863 "accessible", 864 "add", 865 "all", 866 "alter", 867 "analyze", 868 "and", 869 "as", 870 "asc", 871 "asensitive", 872 "before", 873 "between", 874 "bigint", 875 "binary", 876 "blob", 877 "both", 878 "by", 879 "call", 880 "cascade", 881 "case", 882 "change", 883 "char", 884 "character", 885 "check", 886 "collate", 887 "column", 888 "condition", 889 "constraint", 890 "continue", 891 "convert", 892 "create", 893 "cross", 894 "cube", 895 "cume_dist", 896 "current_date", 897 "current_time", 898 "current_timestamp", 899 "current_user", 900 "cursor", 901 "database", 902 "databases", 903 "day_hour", 904 "day_microsecond", 905 "day_minute", 906 "day_second", 907 "dec", 908 "decimal", 909 "declare", 910 "default", 911 "delayed", 912 "delete", 913 "dense_rank", 914 "desc", 915 "describe", 916 "deterministic", 917 "distinct", 918 "distinctrow", 919 "div", 920 "double", 921 "drop", 922 "dual", 923 "each", 924 "else", 925 "elseif", 926 "empty", 927 "enclosed", 928 "escaped", 929 "except", 930 "exists", 931 "exit", 932 "explain", 933 "false", 934 "fetch", 935 "first_value", 936 "float", 937 "float4", 938 "float8", 939 "for", 940 "force", 941 "foreign", 942 "from", 943 "fulltext", 944 "function", 945 "generated", 946 "get", 947 "grant", 948 "group", 949 "grouping", 950 "groups", 951 "having", 952 "high_priority", 953 "hour_microsecond", 954 "hour_minute", 955 "hour_second", 956 "if", 957 "ignore", 958 "in", 959 "index", 960 "infile", 961 "inner", 962 "inout", 963 "insensitive", 964 "insert", 965 "int", 966 "int1", 967 "int2", 968 "int3", 969 "int4", 970 "int8", 971 "integer", 972 "intersect", 973 "interval", 974 "into", 975 "io_after_gtids", 976 "io_before_gtids", 977 "is", 978 "iterate", 979 "join", 980 "json_table", 981 "key", 982 "keys", 983 "kill", 984 "lag", 985 "last_value", 986 "lateral", 987 "lead", 988 "leading", 989 "leave", 990 "left", 991 "like", 992 "limit", 993 "linear", 994 "lines", 995 "load", 996 "localtime", 997 "localtimestamp", 998 "lock", 999 "long", 1000 "longblob", 1001 "longtext", 1002 "loop", 1003 "low_priority", 1004 "master_bind", 1005 "master_ssl_verify_server_cert", 1006 "match", 1007 "maxvalue", 1008 "mediumblob", 1009 "mediumint", 1010 "mediumtext", 1011 "middleint", 1012 "minute_microsecond", 1013 "minute_second", 1014 "mod", 1015 "modifies", 1016 "natural", 1017 "not", 1018 "no_write_to_binlog", 1019 "nth_value", 1020 "ntile", 1021 "null", 1022 "numeric", 1023 "of", 1024 "on", 1025 "optimize", 1026 "optimizer_costs", 1027 "option", 1028 "optionally", 1029 "or", 1030 "order", 1031 "out", 1032 "outer", 1033 "outfile", 1034 "over", 1035 "partition", 1036 "percent_rank", 1037 "precision", 1038 "primary", 1039 "procedure", 1040 "purge", 1041 "range", 1042 "rank", 1043 "read", 1044 "reads", 1045 "read_write", 1046 "real", 1047 "recursive", 1048 "references", 1049 "regexp", 1050 "release", 1051 "rename", 1052 "repeat", 1053 "replace", 1054 "require", 1055 "resignal", 1056 "restrict", 1057 "return", 1058 "revoke", 1059 "right", 1060 "rlike", 1061 "row", 1062 "rows", 1063 "row_number", 1064 "schema", 1065 "schemas", 1066 "second_microsecond", 1067 "select", 1068 "sensitive", 1069 "separator", 1070 "set", 1071 "show", 1072 "signal", 1073 "smallint", 1074 "spatial", 1075 "specific", 1076 "sql", 1077 "sqlexception", 1078 "sqlstate", 1079 "sqlwarning", 1080 "sql_big_result", 1081 "sql_calc_found_rows", 1082 "sql_small_result", 1083 "ssl", 1084 "starting", 1085 "stored", 1086 "straight_join", 1087 "system", 1088 "table", 1089 "terminated", 1090 "then", 1091 "tinyblob", 1092 "tinyint", 1093 "tinytext", 1094 "to", 1095 "trailing", 1096 "trigger", 1097 "true", 1098 "undo", 1099 "union", 1100 "unique", 1101 "unlock", 1102 "unsigned", 1103 "update", 1104 "usage", 1105 "use", 1106 "using", 1107 "utc_date", 1108 "utc_time", 1109 "utc_timestamp", 1110 "values", 1111 "varbinary", 1112 "varchar", 1113 "varcharacter", 1114 "varying", 1115 "virtual", 1116 "when", 1117 "where", 1118 "while", 1119 "window", 1120 "with", 1121 "write", 1122 "xor", 1123 "year_month", 1124 "zerofill", 1125 } 1126 1127 def array_sql(self, expression: exp.Array) -> str: 1128 self.unsupported("Arrays are not supported by MySQL") 1129 return self.function_fallback_sql(expression) 1130 1131 def arraycontainsall_sql(self, expression: exp.ArrayContainsAll) -> str: 1132 self.unsupported("Array operations are not supported by MySQL") 1133 return self.function_fallback_sql(expression) 1134 1135 def dpipe_sql(self, expression: exp.DPipe) -> str: 1136 return self.func("CONCAT", *expression.flatten()) 1137 1138 def extract_sql(self, expression: exp.Extract) -> str: 1139 unit = expression.name 1140 if unit and unit.lower() == "epoch": 1141 return self.func("UNIX_TIMESTAMP", expression.expression) 1142 1143 return super().extract_sql(expression) 1144 1145 def datatype_sql(self, expression: exp.DataType) -> str: 1146 if ( 1147 self.VARCHAR_REQUIRES_SIZE 1148 and expression.is_type(exp.DataType.Type.VARCHAR) 1149 and not expression.expressions 1150 ): 1151 # `VARCHAR` must always have a size - if it doesn't, we always generate `TEXT` 1152 return "TEXT" 1153 1154 # https://dev.mysql.com/doc/refman/8.0/en/numeric-type-syntax.html 1155 result = super().datatype_sql(expression) 1156 if expression.this in self.UNSIGNED_TYPE_MAPPING: 1157 result = f"{result} UNSIGNED" 1158 1159 return result 1160 1161 def jsonarraycontains_sql(self, expression: exp.JSONArrayContains) -> str: 1162 return f"{self.sql(expression, 'this')} MEMBER OF({self.sql(expression, 'expression')})" 1163 1164 def cast_sql(self, expression: exp.Cast, safe_prefix: t.Optional[str] = None) -> str: 1165 if expression.to.this in self.TIMESTAMP_FUNC_TYPES: 1166 return self.func("TIMESTAMP", expression.this) 1167 1168 to = self.CAST_MAPPING.get(expression.to.this) 1169 1170 if to: 1171 expression.to.set("this", to) 1172 return super().cast_sql(expression) 1173 1174 def show_sql(self, expression: exp.Show) -> str: 1175 this = f" {expression.name}" 1176 full = " FULL" if expression.args.get("full") else "" 1177 global_ = " GLOBAL" if expression.args.get("global") else "" 1178 1179 target = self.sql(expression, "target") 1180 target = f" {target}" if target else "" 1181 if expression.name in ("COLUMNS", "INDEX"): 1182 target = f" FROM{target}" 1183 elif expression.name == "GRANTS": 1184 target = f" FOR{target}" 1185 1186 db = self._prefixed_sql("FROM", expression, "db") 1187 1188 like = self._prefixed_sql("LIKE", expression, "like") 1189 where = self.sql(expression, "where") 1190 1191 types = self.expressions(expression, key="types") 1192 types = f" {types}" if types else types 1193 query = self._prefixed_sql("FOR QUERY", expression, "query") 1194 1195 if expression.name == "PROFILE": 1196 offset = self._prefixed_sql("OFFSET", expression, "offset") 1197 limit = self._prefixed_sql("LIMIT", expression, "limit") 1198 else: 1199 offset = "" 1200 limit = self._oldstyle_limit_sql(expression) 1201 1202 log = self._prefixed_sql("IN", expression, "log") 1203 position = self._prefixed_sql("FROM", expression, "position") 1204 1205 channel = self._prefixed_sql("FOR CHANNEL", expression, "channel") 1206 1207 if expression.name == "ENGINE": 1208 mutex_or_status = " MUTEX" if expression.args.get("mutex") else " STATUS" 1209 else: 1210 mutex_or_status = "" 1211 1212 return f"SHOW{full}{global_}{this}{target}{types}{db}{query}{log}{position}{channel}{mutex_or_status}{like}{where}{offset}{limit}" 1213 1214 def altercolumn_sql(self, expression: exp.AlterColumn) -> str: 1215 dtype = self.sql(expression, "dtype") 1216 if not dtype: 1217 return super().altercolumn_sql(expression) 1218 1219 this = self.sql(expression, "this") 1220 return f"MODIFY COLUMN {this} {dtype}" 1221 1222 def _prefixed_sql(self, prefix: str, expression: exp.Expression, arg: str) -> str: 1223 sql = self.sql(expression, arg) 1224 return f" {prefix} {sql}" if sql else "" 1225 1226 def _oldstyle_limit_sql(self, expression: exp.Show) -> str: 1227 limit = self.sql(expression, "limit") 1228 offset = self.sql(expression, "offset") 1229 if limit: 1230 limit_offset = f"{offset}, {limit}" if offset else limit 1231 return f" LIMIT {limit_offset}" 1232 return "" 1233 1234 def chr_sql(self, expression: exp.Chr) -> str: 1235 this = self.expressions(sqls=[expression.this] + expression.expressions) 1236 charset = expression.args.get("charset") 1237 using = f" USING {self.sql(charset)}" if charset else "" 1238 return f"CHAR({this}{using})" 1239 1240 def timestamptrunc_sql(self, expression: exp.TimestampTrunc) -> str: 1241 unit = expression.args.get("unit") 1242 1243 # Pick an old-enough date to avoid negative timestamp diffs 1244 start_ts = "'0000-01-01 00:00:00'" 1245 1246 # Source: https://stackoverflow.com/a/32955740 1247 timestamp_diff = build_date_delta(exp.TimestampDiff)([unit, start_ts, expression.this]) 1248 interval = exp.Interval(this=timestamp_diff, unit=unit) 1249 dateadd = build_date_delta_with_interval(exp.DateAdd)([start_ts, interval]) 1250 1251 return self.sql(dateadd) 1252 1253 def converttimezone_sql(self, expression: exp.ConvertTimezone) -> str: 1254 from_tz = expression.args.get("source_tz") 1255 to_tz = expression.args.get("target_tz") 1256 dt = expression.args.get("timestamp") 1257 1258 return self.func("CONVERT_TZ", dt, from_tz, to_tz) 1259 1260 def attimezone_sql(self, expression: exp.AtTimeZone) -> str: 1261 self.unsupported("AT TIME ZONE is not supported by MySQL") 1262 return self.sql(expression.this)
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.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.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.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.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 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 strposition_to_locate_sql>, <class 'sqlglot.expressions.StrToDate'>: <function _str_to_date_sql>, <class 'sqlglot.expressions.StrToTime'>: <function _str_to_date_sql>, <class 'sqlglot.expressions.Stuff'>: <function rename_func.<locals>.<lambda>>, <class 'sqlglot.expressions.TableSample'>: <function no_tablesample_sql>, <class 'sqlglot.expressions.TimeFromParts'>: <function rename_func.<locals>.<lambda>>, <class 'sqlglot.expressions.TimestampAdd'>: <function date_add_interval_sql.<locals>.func>, <class 'sqlglot.expressions.TimestampDiff'>: <function MySQL.Generator.<lambda>>, <class 'sqlglot.expressions.TimestampSub'>: <function date_add_interval_sql.<locals>.func>, <class 'sqlglot.expressions.TimeStrToUnix'>: <function rename_func.<locals>.<lambda>>, <class 'sqlglot.expressions.TimeStrToTime'>: <function MySQL.Generator.<lambda>>, <class 'sqlglot.expressions.TimeToStr'>: <function _remove_ts_or_ds_to_date.<locals>.func>, <class 'sqlglot.expressions.Trim'>: <function trim_sql>, <class 'sqlglot.expressions.TryCast'>: <function no_trycast_sql>, <class 'sqlglot.expressions.TsOrDsAdd'>: <function date_add_sql.<locals>.func>, <class 'sqlglot.expressions.TsOrDsDiff'>: <function MySQL.Generator.<lambda>>, <class 'sqlglot.expressions.TsOrDsToDate'>: <function _ts_or_ds_to_date_sql>, <class 'sqlglot.expressions.UnixToTime'>: <function _unix_to_time_sql>, <class 'sqlglot.expressions.Week'>: <function _remove_ts_or_ds_to_date.<locals>.func>, <class 'sqlglot.expressions.WeekOfYear'>: <function _remove_ts_or_ds_to_date.<locals>.func>, <class 'sqlglot.expressions.Year'>: <function _remove_ts_or_ds_to_date.<locals>.func>}
UNSIGNED_TYPE_MAPPING =
{<Type.UBIGINT: 'UBIGINT'>: 'BIGINT', <Type.UINT: 'UINT'>: 'INT', <Type.UMEDIUMINT: 'UMEDIUMINT'>: 'MEDIUMINT', <Type.USMALLINT: 'USMALLINT'>: 'SMALLINT', <Type.UTINYINT: 'UTINYINT'>: 'TINYINT', <Type.UDECIMAL: 'UDECIMAL'>: 'DECIMAL'}
TIMESTAMP_TYPE_MAPPING =
{<Type.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 =
{'io_after_gtids', 'row_number', 'where', 'elseif', 'ignore', 'character', 'fulltext', 'usage', 'integer', 'current_time', 'current_timestamp', 'rlike', 'char', 'varying', 'day_second', 'inout', 'join', 'case', 'as', 'separator', 'recursive', 'get', 'check', 'second_microsecond', 'long', 'null', 'right', 'row', 'index', 'read_write', 'modifies', 'fetch', 'leading', 'longtext', 'sql_calc_found_rows', 'range', 'float4', 'by', 'describe', 'schema', 'day_microsecond', 'mediumint', 'procedure', 'binary', 'year_month', 'ssl', 'hour_microsecond', 'false', 'out', 'double', 'call', 'interval', 'lead', 'from', 'hour_second', 'like', 'release', 'groups', 'resignal', 'sql', 'insensitive', 'schemas', 'tinyblob', 'system', 'outfile', 'order', 'force', 'signal', 'longblob', 'return', 'unsigned', 'day_hour', 'require', 'starting', 'minute_microsecond', 'repeat', 'trigger', 'lateral', 'cursor', 'day_minute', 'hour_minute', 'empty', 'unique', 'replace', 'escaped', 'use', 'change', 'convert', 'high_priority', 'natural', 'declare', 'sql_small_result', 'alter', 'reads', 'each', 'int8', 'except', 'or', 'function', 'sqlexception', 'no_write_to_binlog', 'while', 'specific', 'grouping', 'spatial', 'update', 'int3', 'virtual', 'limit', 'varbinary', 'desc', 'infile', 'float8', 'sql_big_result', 'table', 'create', 'current_date', 'outer', 'master_bind', 'real', 'explain', 'localtimestamp', 'utc_timestamp', 'is', 'write', 'values', 'optimize', 'minute_second', 'int4', 'int1', 'databases', 'condition', 'foreign', 'key', 'all', 'dual', 'enclosed', 'delete', 'leave', 'left', 'in', 'on', 'of', 'regexp', 'select', 'undo', 'set', 'xor', 'lag', 'over', 'accessible', 'union', 'distinct', 'between', 'master_ssl_verify_server_cert', 'show', 'match', 'ntile', 'unlock', 'linear', 'json_table', 'cascade', 'blob', 'both', 'dense_rank', 'delayed', 'generated', 'loop', 'for', 'with', 'io_before_gtids', 'sensitive', 'continue', 'column', 'not', 'keys', 'last_value', 'inner', 'low_priority', 'varcharacter', 'window', 'stored', 'optimizer_costs', 'default', 'cross', 'distinctrow', 'restrict', 'then', 'if', 'deterministic', 'percent_rank', 'utc_time', 'analyze', 'nth_value', 'asensitive', 'option', 'numeric', 'constraint', 'references', 'terminated', 'rows', 'tinyint', 'trailing', 'primary', 'kill', 'decimal', 'rename', 'collate', 'drop', 'insert', 'current_user', 'float', 'cube', 'intersect', 'tinytext', 'iterate', 'group', 'having', 'straight_join', 'read', 'zerofill', 'and', 'smallint', 'else', 'int2', 'mediumblob', 'database', 'exists', 'dec', 'grant', 'utc_date', 'cume_dist', 'partition', 'bigint', 'precision', 'before', 'varchar', 'sqlstate', 'sqlwarning', 'rank', 'purge', 'div', 'to', 'maxvalue', 'lines', 'load', 'revoke', 'middleint', 'int', 'true', 'first_value', 'mediumtext', 'asc', 'when', 'add', 'exit', 'optionally', 'lock', 'into', 'localtime', 'using', 'mod'}
1145 def datatype_sql(self, expression: exp.DataType) -> str: 1146 if ( 1147 self.VARCHAR_REQUIRES_SIZE 1148 and expression.is_type(exp.DataType.Type.VARCHAR) 1149 and not expression.expressions 1150 ): 1151 # `VARCHAR` must always have a size - if it doesn't, we always generate `TEXT` 1152 return "TEXT" 1153 1154 # https://dev.mysql.com/doc/refman/8.0/en/numeric-type-syntax.html 1155 result = super().datatype_sql(expression) 1156 if expression.this in self.UNSIGNED_TYPE_MAPPING: 1157 result = f"{result} UNSIGNED" 1158 1159 return result
def
cast_sql( self, expression: sqlglot.expressions.Cast, safe_prefix: Optional[str] = None) -> str:
1164 def cast_sql(self, expression: exp.Cast, safe_prefix: t.Optional[str] = None) -> str: 1165 if expression.to.this in self.TIMESTAMP_FUNC_TYPES: 1166 return self.func("TIMESTAMP", expression.this) 1167 1168 to = self.CAST_MAPPING.get(expression.to.this) 1169 1170 if to: 1171 expression.to.set("this", to) 1172 return super().cast_sql(expression)
1174 def show_sql(self, expression: exp.Show) -> str: 1175 this = f" {expression.name}" 1176 full = " FULL" if expression.args.get("full") else "" 1177 global_ = " GLOBAL" if expression.args.get("global") else "" 1178 1179 target = self.sql(expression, "target") 1180 target = f" {target}" if target else "" 1181 if expression.name in ("COLUMNS", "INDEX"): 1182 target = f" FROM{target}" 1183 elif expression.name == "GRANTS": 1184 target = f" FOR{target}" 1185 1186 db = self._prefixed_sql("FROM", expression, "db") 1187 1188 like = self._prefixed_sql("LIKE", expression, "like") 1189 where = self.sql(expression, "where") 1190 1191 types = self.expressions(expression, key="types") 1192 types = f" {types}" if types else types 1193 query = self._prefixed_sql("FOR QUERY", expression, "query") 1194 1195 if expression.name == "PROFILE": 1196 offset = self._prefixed_sql("OFFSET", expression, "offset") 1197 limit = self._prefixed_sql("LIMIT", expression, "limit") 1198 else: 1199 offset = "" 1200 limit = self._oldstyle_limit_sql(expression) 1201 1202 log = self._prefixed_sql("IN", expression, "log") 1203 position = self._prefixed_sql("FROM", expression, "position") 1204 1205 channel = self._prefixed_sql("FOR CHANNEL", expression, "channel") 1206 1207 if expression.name == "ENGINE": 1208 mutex_or_status = " MUTEX" if expression.args.get("mutex") else " STATUS" 1209 else: 1210 mutex_or_status = "" 1211 1212 return f"SHOW{full}{global_}{this}{target}{types}{db}{query}{log}{position}{channel}{mutex_or_status}{like}{where}{offset}{limit}"
1240 def timestamptrunc_sql(self, expression: exp.TimestampTrunc) -> str: 1241 unit = expression.args.get("unit") 1242 1243 # Pick an old-enough date to avoid negative timestamp diffs 1244 start_ts = "'0000-01-01 00:00:00'" 1245 1246 # Source: https://stackoverflow.com/a/32955740 1247 timestamp_diff = build_date_delta(exp.TimestampDiff)([unit, start_ts, expression.this]) 1248 interval = exp.Interval(this=timestamp_diff, unit=unit) 1249 dateadd = build_date_delta_with_interval(exp.DateAdd)([start_ts, interval]) 1250 1251 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
- overlaps_sql
- distance_sql
- dot_sql
- eq_sql
- propertyeq_sql
- escape_sql
- glob_sql
- gt_sql
- gte_sql
- ilike_sql
- ilikeany_sql
- is_sql
- like_sql
- likeany_sql
- similarto_sql
- lt_sql
- lte_sql
- mod_sql
- mul_sql
- neq_sql
- nullsafeeq_sql
- nullsafeneq_sql
- slice_sql
- sub_sql
- trycast_sql
- try_sql
- log_sql
- use_sql
- binary
- function_fallback_sql
- func
- format_args
- too_wide
- format_time
- expressions
- op_expressions
- naked_property
- tag_sql
- token_sql
- userdefinedfunction_sql
- joinhint_sql
- kwarg_sql
- when_sql
- 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
- 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