sqlglot.dialects.mysql
1from __future__ import annotations 2 3import typing as t 4 5from sqlglot import exp, generator, parser, tokens, transforms 6from sqlglot.dialects.dialect import ( 7 Dialect, 8 NormalizationStrategy, 9 arrow_json_extract_sql, 10 date_add_interval_sql, 11 datestrtodate_sql, 12 build_formatted_time, 13 isnull_to_is_null, 14 length_or_char_length_sql, 15 locate_to_strposition, 16 max_or_greatest, 17 min_or_least, 18 no_ilike_sql, 19 no_paren_current_date_sql, 20 no_pivot_sql, 21 no_tablesample_sql, 22 no_trycast_sql, 23 build_date_delta, 24 build_date_delta_with_interval, 25 rename_func, 26 strposition_to_locate_sql, 27 unit_to_var, 28 trim_sql, 29 timestrtotime_sql, 30) 31from sqlglot.helper import seq_get 32from sqlglot.tokens import TokenType 33 34 35def _show_parser(*args: t.Any, **kwargs: t.Any) -> t.Callable[[MySQL.Parser], exp.Show]: 36 def _parse(self: MySQL.Parser) -> exp.Show: 37 return self._parse_show_mysql(*args, **kwargs) 38 39 return _parse 40 41 42def _date_trunc_sql(self: MySQL.Generator, expression: exp.DateTrunc) -> str: 43 expr = self.sql(expression, "this") 44 unit = expression.text("unit").upper() 45 46 if unit == "WEEK": 47 concat = f"CONCAT(YEAR({expr}), ' ', WEEK({expr}, 1), ' 1')" 48 date_format = "%Y %u %w" 49 elif unit == "MONTH": 50 concat = f"CONCAT(YEAR({expr}), ' ', MONTH({expr}), ' 1')" 51 date_format = "%Y %c %e" 52 elif unit == "QUARTER": 53 concat = f"CONCAT(YEAR({expr}), ' ', QUARTER({expr}) * 3 - 2, ' 1')" 54 date_format = "%Y %c %e" 55 elif unit == "YEAR": 56 concat = f"CONCAT(YEAR({expr}), ' 1 1')" 57 date_format = "%Y %c %e" 58 else: 59 if unit != "DAY": 60 self.unsupported(f"Unexpected interval unit: {unit}") 61 return self.func("DATE", expr) 62 63 return self.func("STR_TO_DATE", concat, f"'{date_format}'") 64 65 66# All specifiers for time parts (as opposed to date parts) 67# https://dev.mysql.com/doc/refman/8.0/en/date-and-time-functions.html#function_date-format 68TIME_SPECIFIERS = {"f", "H", "h", "I", "i", "k", "l", "p", "r", "S", "s", "T"} 69 70 71def _has_time_specifier(date_format: str) -> bool: 72 i = 0 73 length = len(date_format) 74 75 while i < length: 76 if date_format[i] == "%": 77 i += 1 78 if i < length and date_format[i] in TIME_SPECIFIERS: 79 return True 80 i += 1 81 return False 82 83 84def _str_to_date(args: t.List) -> exp.StrToDate | exp.StrToTime: 85 mysql_date_format = seq_get(args, 1) 86 date_format = MySQL.format_time(mysql_date_format) 87 this = seq_get(args, 0) 88 89 if mysql_date_format and _has_time_specifier(mysql_date_format.name): 90 return exp.StrToTime(this=this, format=date_format) 91 92 return exp.StrToDate(this=this, format=date_format) 93 94 95def _str_to_date_sql( 96 self: MySQL.Generator, expression: exp.StrToDate | exp.StrToTime | exp.TsOrDsToDate 97) -> str: 98 return self.func("STR_TO_DATE", expression.this, self.format_time(expression)) 99 100 101def _unix_to_time_sql(self: MySQL.Generator, expression: exp.UnixToTime) -> str: 102 scale = expression.args.get("scale") 103 timestamp = expression.this 104 105 if scale in (None, exp.UnixToTime.SECONDS): 106 return self.func("FROM_UNIXTIME", timestamp, self.format_time(expression)) 107 108 return self.func( 109 "FROM_UNIXTIME", 110 exp.Div(this=timestamp, expression=exp.func("POW", 10, scale)), 111 self.format_time(expression), 112 ) 113 114 115def date_add_sql( 116 kind: str, 117) -> t.Callable[[generator.Generator, exp.Expression], str]: 118 def func(self: generator.Generator, expression: exp.Expression) -> str: 119 return self.func( 120 f"DATE_{kind}", 121 expression.this, 122 exp.Interval(this=expression.expression, unit=unit_to_var(expression)), 123 ) 124 125 return func 126 127 128def _ts_or_ds_to_date_sql(self: MySQL.Generator, expression: exp.TsOrDsToDate) -> str: 129 time_format = expression.args.get("format") 130 return _str_to_date_sql(self, expression) if time_format else self.func("DATE", expression.this) 131 132 133def _remove_ts_or_ds_to_date( 134 to_sql: t.Optional[t.Callable[[MySQL.Generator, exp.Expression], str]] = None, 135 args: t.Tuple[str, ...] = ("this",), 136) -> t.Callable[[MySQL.Generator, exp.Func], str]: 137 def func(self: MySQL.Generator, expression: exp.Func) -> str: 138 for arg_key in args: 139 arg = expression.args.get(arg_key) 140 if isinstance(arg, exp.TsOrDsToDate) and not arg.args.get("format"): 141 expression.set(arg_key, arg.this) 142 143 return to_sql(self, expression) if to_sql else self.function_fallback_sql(expression) 144 145 return func 146 147 148class MySQL(Dialect): 149 PROMOTE_TO_INFERRED_DATETIME_TYPE = True 150 151 # https://dev.mysql.com/doc/refman/8.0/en/identifiers.html 152 IDENTIFIERS_CAN_START_WITH_DIGIT = True 153 154 # We default to treating all identifiers as case-sensitive, since it matches MySQL's 155 # behavior on Linux systems. For MacOS and Windows systems, one can override this 156 # setting by specifying `dialect="mysql, normalization_strategy = lowercase"`. 157 # 158 # See also https://dev.mysql.com/doc/refman/8.2/en/identifier-case-sensitivity.html 159 NORMALIZATION_STRATEGY = NormalizationStrategy.CASE_SENSITIVE 160 161 TIME_FORMAT = "'%Y-%m-%d %T'" 162 DPIPE_IS_STRING_CONCAT = False 163 SUPPORTS_USER_DEFINED_TYPES = False 164 SUPPORTS_SEMI_ANTI_JOIN = False 165 SAFE_DIVISION = True 166 167 # https://prestodb.io/docs/current/functions/datetime.html#mysql-date-functions 168 TIME_MAPPING = { 169 "%M": "%B", 170 "%c": "%-m", 171 "%e": "%-d", 172 "%h": "%I", 173 "%i": "%M", 174 "%s": "%S", 175 "%u": "%W", 176 "%k": "%-H", 177 "%l": "%-I", 178 "%T": "%H:%M:%S", 179 "%W": "%A", 180 } 181 182 class Tokenizer(tokens.Tokenizer): 183 QUOTES = ["'", '"'] 184 COMMENTS = ["--", "#", ("/*", "*/")] 185 IDENTIFIERS = ["`"] 186 STRING_ESCAPES = ["'", '"', "\\"] 187 BIT_STRINGS = [("b'", "'"), ("B'", "'"), ("0b", "")] 188 HEX_STRINGS = [("x'", "'"), ("X'", "'"), ("0x", "")] 189 190 KEYWORDS = { 191 **tokens.Tokenizer.KEYWORDS, 192 "CHARSET": TokenType.CHARACTER_SET, 193 # The DESCRIBE and EXPLAIN statements are synonyms. 194 # https://dev.mysql.com/doc/refman/8.4/en/explain.html 195 "EXPLAIN": TokenType.DESCRIBE, 196 "FORCE": TokenType.FORCE, 197 "IGNORE": TokenType.IGNORE, 198 "KEY": TokenType.KEY, 199 "LOCK TABLES": TokenType.COMMAND, 200 "LONGBLOB": TokenType.LONGBLOB, 201 "LONGTEXT": TokenType.LONGTEXT, 202 "MEDIUMBLOB": TokenType.MEDIUMBLOB, 203 "TINYBLOB": TokenType.TINYBLOB, 204 "TINYTEXT": TokenType.TINYTEXT, 205 "MEDIUMTEXT": TokenType.MEDIUMTEXT, 206 "MEDIUMINT": TokenType.MEDIUMINT, 207 "MEMBER OF": TokenType.MEMBER_OF, 208 "SEPARATOR": TokenType.SEPARATOR, 209 "SERIAL": TokenType.SERIAL, 210 "START": TokenType.BEGIN, 211 "SIGNED": TokenType.BIGINT, 212 "SIGNED INTEGER": TokenType.BIGINT, 213 "UNLOCK TABLES": TokenType.COMMAND, 214 "UNSIGNED": TokenType.UBIGINT, 215 "UNSIGNED INTEGER": TokenType.UBIGINT, 216 "YEAR": TokenType.YEAR, 217 "_ARMSCII8": TokenType.INTRODUCER, 218 "_ASCII": TokenType.INTRODUCER, 219 "_BIG5": TokenType.INTRODUCER, 220 "_BINARY": TokenType.INTRODUCER, 221 "_CP1250": TokenType.INTRODUCER, 222 "_CP1251": TokenType.INTRODUCER, 223 "_CP1256": TokenType.INTRODUCER, 224 "_CP1257": TokenType.INTRODUCER, 225 "_CP850": TokenType.INTRODUCER, 226 "_CP852": TokenType.INTRODUCER, 227 "_CP866": TokenType.INTRODUCER, 228 "_CP932": TokenType.INTRODUCER, 229 "_DEC8": TokenType.INTRODUCER, 230 "_EUCJPMS": TokenType.INTRODUCER, 231 "_EUCKR": TokenType.INTRODUCER, 232 "_GB18030": TokenType.INTRODUCER, 233 "_GB2312": TokenType.INTRODUCER, 234 "_GBK": TokenType.INTRODUCER, 235 "_GEOSTD8": TokenType.INTRODUCER, 236 "_GREEK": TokenType.INTRODUCER, 237 "_HEBREW": TokenType.INTRODUCER, 238 "_HP8": TokenType.INTRODUCER, 239 "_KEYBCS2": TokenType.INTRODUCER, 240 "_KOI8R": TokenType.INTRODUCER, 241 "_KOI8U": TokenType.INTRODUCER, 242 "_LATIN1": TokenType.INTRODUCER, 243 "_LATIN2": TokenType.INTRODUCER, 244 "_LATIN5": TokenType.INTRODUCER, 245 "_LATIN7": TokenType.INTRODUCER, 246 "_MACCE": TokenType.INTRODUCER, 247 "_MACROMAN": TokenType.INTRODUCER, 248 "_SJIS": TokenType.INTRODUCER, 249 "_SWE7": TokenType.INTRODUCER, 250 "_TIS620": TokenType.INTRODUCER, 251 "_UCS2": TokenType.INTRODUCER, 252 "_UJIS": TokenType.INTRODUCER, 253 # https://dev.mysql.com/doc/refman/8.0/en/string-literals.html 254 "_UTF8": TokenType.INTRODUCER, 255 "_UTF16": TokenType.INTRODUCER, 256 "_UTF16LE": TokenType.INTRODUCER, 257 "_UTF32": TokenType.INTRODUCER, 258 "_UTF8MB3": TokenType.INTRODUCER, 259 "_UTF8MB4": TokenType.INTRODUCER, 260 "@@": TokenType.SESSION_PARAMETER, 261 } 262 263 COMMANDS = {*tokens.Tokenizer.COMMANDS, TokenType.REPLACE} - {TokenType.SHOW} 264 265 class Parser(parser.Parser): 266 FUNC_TOKENS = { 267 *parser.Parser.FUNC_TOKENS, 268 TokenType.DATABASE, 269 TokenType.SCHEMA, 270 TokenType.VALUES, 271 } 272 273 CONJUNCTION = { 274 **parser.Parser.CONJUNCTION, 275 TokenType.DAMP: exp.And, 276 TokenType.XOR: exp.Xor, 277 } 278 279 DISJUNCTION = { 280 **parser.Parser.DISJUNCTION, 281 TokenType.DPIPE: exp.Or, 282 } 283 284 TABLE_ALIAS_TOKENS = ( 285 parser.Parser.TABLE_ALIAS_TOKENS - parser.Parser.TABLE_INDEX_HINT_TOKENS 286 ) 287 288 RANGE_PARSERS = { 289 **parser.Parser.RANGE_PARSERS, 290 TokenType.MEMBER_OF: lambda self, this: self.expression( 291 exp.JSONArrayContains, 292 this=this, 293 expression=self._parse_wrapped(self._parse_expression), 294 ), 295 } 296 297 FUNCTIONS = { 298 **parser.Parser.FUNCTIONS, 299 "CONVERT_TZ": lambda args: exp.ConvertTimezone( 300 source_tz=seq_get(args, 1), target_tz=seq_get(args, 2), timestamp=seq_get(args, 0) 301 ), 302 "DATE": lambda args: exp.TsOrDsToDate(this=seq_get(args, 0)), 303 "DATE_ADD": build_date_delta_with_interval(exp.DateAdd), 304 "DATE_FORMAT": build_formatted_time(exp.TimeToStr, "mysql"), 305 "DATE_SUB": build_date_delta_with_interval(exp.DateSub), 306 "DAY": lambda args: exp.Day(this=exp.TsOrDsToDate(this=seq_get(args, 0))), 307 "DAYOFMONTH": lambda args: exp.DayOfMonth(this=exp.TsOrDsToDate(this=seq_get(args, 0))), 308 "DAYOFWEEK": lambda args: exp.DayOfWeek(this=exp.TsOrDsToDate(this=seq_get(args, 0))), 309 "DAYOFYEAR": lambda args: exp.DayOfYear(this=exp.TsOrDsToDate(this=seq_get(args, 0))), 310 "FORMAT": exp.NumberToStr.from_arg_list, 311 "FROM_UNIXTIME": build_formatted_time(exp.UnixToTime, "mysql"), 312 "ISNULL": isnull_to_is_null, 313 "LENGTH": lambda args: exp.Length(this=seq_get(args, 0), binary=True), 314 "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: length_or_char_length_sql, 735 exp.LogicalOr: rename_func("MAX"), 736 exp.LogicalAnd: rename_func("MIN"), 737 exp.Max: max_or_greatest, 738 exp.Min: min_or_least, 739 exp.Month: _remove_ts_or_ds_to_date(), 740 exp.NullSafeEQ: lambda self, e: self.binary(e, "<=>"), 741 exp.NullSafeNEQ: lambda self, e: f"NOT {self.binary(e, '<=>')}", 742 exp.NumberToStr: rename_func("FORMAT"), 743 exp.Pivot: no_pivot_sql, 744 exp.Select: transforms.preprocess( 745 [ 746 transforms.eliminate_distinct_on, 747 transforms.eliminate_semi_and_anti_joins, 748 transforms.eliminate_qualify, 749 transforms.eliminate_full_outer_join, 750 transforms.unnest_generate_date_array_using_recursive_cte, 751 ] 752 ), 753 exp.StrPosition: strposition_to_locate_sql, 754 exp.StrToDate: _str_to_date_sql, 755 exp.StrToTime: _str_to_date_sql, 756 exp.Stuff: rename_func("INSERT"), 757 exp.TableSample: no_tablesample_sql, 758 exp.TimeFromParts: rename_func("MAKETIME"), 759 exp.TimestampAdd: date_add_interval_sql("DATE", "ADD"), 760 exp.TimestampDiff: lambda self, e: self.func( 761 "TIMESTAMPDIFF", unit_to_var(e), e.expression, e.this 762 ), 763 exp.TimestampSub: date_add_interval_sql("DATE", "SUB"), 764 exp.TimeStrToUnix: rename_func("UNIX_TIMESTAMP"), 765 exp.TimeStrToTime: lambda self, e: timestrtotime_sql( 766 self, 767 e, 768 include_precision=not e.args.get("zone"), 769 ), 770 exp.TimeToStr: _remove_ts_or_ds_to_date( 771 lambda self, e: self.func("DATE_FORMAT", e.this, self.format_time(e)) 772 ), 773 exp.Trim: trim_sql, 774 exp.TryCast: no_trycast_sql, 775 exp.TsOrDsAdd: date_add_sql("ADD"), 776 exp.TsOrDsDiff: lambda self, e: self.func("DATEDIFF", e.this, e.expression), 777 exp.TsOrDsToDate: _ts_or_ds_to_date_sql, 778 exp.Unicode: lambda self, e: f"ORD(CONVERT({self.sql(e.this)} USING utf32))", 779 exp.UnixToTime: _unix_to_time_sql, 780 exp.Week: _remove_ts_or_ds_to_date(), 781 exp.WeekOfYear: _remove_ts_or_ds_to_date(rename_func("WEEKOFYEAR")), 782 exp.Year: _remove_ts_or_ds_to_date(), 783 } 784 785 UNSIGNED_TYPE_MAPPING = { 786 exp.DataType.Type.UBIGINT: "BIGINT", 787 exp.DataType.Type.UINT: "INT", 788 exp.DataType.Type.UMEDIUMINT: "MEDIUMINT", 789 exp.DataType.Type.USMALLINT: "SMALLINT", 790 exp.DataType.Type.UTINYINT: "TINYINT", 791 exp.DataType.Type.UDECIMAL: "DECIMAL", 792 } 793 794 TIMESTAMP_TYPE_MAPPING = { 795 exp.DataType.Type.DATETIME2: "DATETIME", 796 exp.DataType.Type.SMALLDATETIME: "DATETIME", 797 exp.DataType.Type.TIMESTAMP: "DATETIME", 798 exp.DataType.Type.TIMESTAMPTZ: "TIMESTAMP", 799 exp.DataType.Type.TIMESTAMPLTZ: "TIMESTAMP", 800 } 801 802 TYPE_MAPPING = { 803 **generator.Generator.TYPE_MAPPING, 804 **UNSIGNED_TYPE_MAPPING, 805 **TIMESTAMP_TYPE_MAPPING, 806 } 807 808 TYPE_MAPPING.pop(exp.DataType.Type.MEDIUMTEXT) 809 TYPE_MAPPING.pop(exp.DataType.Type.LONGTEXT) 810 TYPE_MAPPING.pop(exp.DataType.Type.TINYTEXT) 811 TYPE_MAPPING.pop(exp.DataType.Type.MEDIUMBLOB) 812 TYPE_MAPPING.pop(exp.DataType.Type.LONGBLOB) 813 TYPE_MAPPING.pop(exp.DataType.Type.TINYBLOB) 814 815 PROPERTIES_LOCATION = { 816 **generator.Generator.PROPERTIES_LOCATION, 817 exp.TransientProperty: exp.Properties.Location.UNSUPPORTED, 818 exp.VolatileProperty: exp.Properties.Location.UNSUPPORTED, 819 } 820 821 LIMIT_FETCH = "LIMIT" 822 823 LIMIT_ONLY_LITERALS = True 824 825 CHAR_CAST_MAPPING = dict.fromkeys( 826 ( 827 exp.DataType.Type.LONGTEXT, 828 exp.DataType.Type.LONGBLOB, 829 exp.DataType.Type.MEDIUMBLOB, 830 exp.DataType.Type.MEDIUMTEXT, 831 exp.DataType.Type.TEXT, 832 exp.DataType.Type.TINYBLOB, 833 exp.DataType.Type.TINYTEXT, 834 exp.DataType.Type.VARCHAR, 835 ), 836 "CHAR", 837 ) 838 SIGNED_CAST_MAPPING = dict.fromkeys( 839 ( 840 exp.DataType.Type.BIGINT, 841 exp.DataType.Type.BOOLEAN, 842 exp.DataType.Type.INT, 843 exp.DataType.Type.SMALLINT, 844 exp.DataType.Type.TINYINT, 845 exp.DataType.Type.MEDIUMINT, 846 ), 847 "SIGNED", 848 ) 849 850 # MySQL doesn't support many datatypes in cast. 851 # https://dev.mysql.com/doc/refman/8.0/en/cast-functions.html#function_cast 852 CAST_MAPPING = { 853 **CHAR_CAST_MAPPING, 854 **SIGNED_CAST_MAPPING, 855 exp.DataType.Type.UBIGINT: "UNSIGNED", 856 } 857 858 TIMESTAMP_FUNC_TYPES = { 859 exp.DataType.Type.TIMESTAMPTZ, 860 exp.DataType.Type.TIMESTAMPLTZ, 861 } 862 863 # https://dev.mysql.com/doc/refman/8.0/en/keywords.html 864 RESERVED_KEYWORDS = { 865 "accessible", 866 "add", 867 "all", 868 "alter", 869 "analyze", 870 "and", 871 "as", 872 "asc", 873 "asensitive", 874 "before", 875 "between", 876 "bigint", 877 "binary", 878 "blob", 879 "both", 880 "by", 881 "call", 882 "cascade", 883 "case", 884 "change", 885 "char", 886 "character", 887 "check", 888 "collate", 889 "column", 890 "condition", 891 "constraint", 892 "continue", 893 "convert", 894 "create", 895 "cross", 896 "cube", 897 "cume_dist", 898 "current_date", 899 "current_time", 900 "current_timestamp", 901 "current_user", 902 "cursor", 903 "database", 904 "databases", 905 "day_hour", 906 "day_microsecond", 907 "day_minute", 908 "day_second", 909 "dec", 910 "decimal", 911 "declare", 912 "default", 913 "delayed", 914 "delete", 915 "dense_rank", 916 "desc", 917 "describe", 918 "deterministic", 919 "distinct", 920 "distinctrow", 921 "div", 922 "double", 923 "drop", 924 "dual", 925 "each", 926 "else", 927 "elseif", 928 "empty", 929 "enclosed", 930 "escaped", 931 "except", 932 "exists", 933 "exit", 934 "explain", 935 "false", 936 "fetch", 937 "first_value", 938 "float", 939 "float4", 940 "float8", 941 "for", 942 "force", 943 "foreign", 944 "from", 945 "fulltext", 946 "function", 947 "generated", 948 "get", 949 "grant", 950 "group", 951 "grouping", 952 "groups", 953 "having", 954 "high_priority", 955 "hour_microsecond", 956 "hour_minute", 957 "hour_second", 958 "if", 959 "ignore", 960 "in", 961 "index", 962 "infile", 963 "inner", 964 "inout", 965 "insensitive", 966 "insert", 967 "int", 968 "int1", 969 "int2", 970 "int3", 971 "int4", 972 "int8", 973 "integer", 974 "intersect", 975 "interval", 976 "into", 977 "io_after_gtids", 978 "io_before_gtids", 979 "is", 980 "iterate", 981 "join", 982 "json_table", 983 "key", 984 "keys", 985 "kill", 986 "lag", 987 "last_value", 988 "lateral", 989 "lead", 990 "leading", 991 "leave", 992 "left", 993 "like", 994 "limit", 995 "linear", 996 "lines", 997 "load", 998 "localtime", 999 "localtimestamp", 1000 "lock", 1001 "long", 1002 "longblob", 1003 "longtext", 1004 "loop", 1005 "low_priority", 1006 "master_bind", 1007 "master_ssl_verify_server_cert", 1008 "match", 1009 "maxvalue", 1010 "mediumblob", 1011 "mediumint", 1012 "mediumtext", 1013 "middleint", 1014 "minute_microsecond", 1015 "minute_second", 1016 "mod", 1017 "modifies", 1018 "natural", 1019 "not", 1020 "no_write_to_binlog", 1021 "nth_value", 1022 "ntile", 1023 "null", 1024 "numeric", 1025 "of", 1026 "on", 1027 "optimize", 1028 "optimizer_costs", 1029 "option", 1030 "optionally", 1031 "or", 1032 "order", 1033 "out", 1034 "outer", 1035 "outfile", 1036 "over", 1037 "partition", 1038 "percent_rank", 1039 "precision", 1040 "primary", 1041 "procedure", 1042 "purge", 1043 "range", 1044 "rank", 1045 "read", 1046 "reads", 1047 "read_write", 1048 "real", 1049 "recursive", 1050 "references", 1051 "regexp", 1052 "release", 1053 "rename", 1054 "repeat", 1055 "replace", 1056 "require", 1057 "resignal", 1058 "restrict", 1059 "return", 1060 "revoke", 1061 "right", 1062 "rlike", 1063 "row", 1064 "rows", 1065 "row_number", 1066 "schema", 1067 "schemas", 1068 "second_microsecond", 1069 "select", 1070 "sensitive", 1071 "separator", 1072 "set", 1073 "show", 1074 "signal", 1075 "smallint", 1076 "spatial", 1077 "specific", 1078 "sql", 1079 "sqlexception", 1080 "sqlstate", 1081 "sqlwarning", 1082 "sql_big_result", 1083 "sql_calc_found_rows", 1084 "sql_small_result", 1085 "ssl", 1086 "starting", 1087 "stored", 1088 "straight_join", 1089 "system", 1090 "table", 1091 "terminated", 1092 "then", 1093 "tinyblob", 1094 "tinyint", 1095 "tinytext", 1096 "to", 1097 "trailing", 1098 "trigger", 1099 "true", 1100 "undo", 1101 "union", 1102 "unique", 1103 "unlock", 1104 "unsigned", 1105 "update", 1106 "usage", 1107 "use", 1108 "using", 1109 "utc_date", 1110 "utc_time", 1111 "utc_timestamp", 1112 "values", 1113 "varbinary", 1114 "varchar", 1115 "varcharacter", 1116 "varying", 1117 "virtual", 1118 "when", 1119 "where", 1120 "while", 1121 "window", 1122 "with", 1123 "write", 1124 "xor", 1125 "year_month", 1126 "zerofill", 1127 } 1128 1129 def array_sql(self, expression: exp.Array) -> str: 1130 self.unsupported("Arrays are not supported by MySQL") 1131 return self.function_fallback_sql(expression) 1132 1133 def arraycontainsall_sql(self, expression: exp.ArrayContainsAll) -> str: 1134 self.unsupported("Array operations are not supported by MySQL") 1135 return self.function_fallback_sql(expression) 1136 1137 def dpipe_sql(self, expression: exp.DPipe) -> str: 1138 return self.func("CONCAT", *expression.flatten()) 1139 1140 def extract_sql(self, expression: exp.Extract) -> str: 1141 unit = expression.name 1142 if unit and unit.lower() == "epoch": 1143 return self.func("UNIX_TIMESTAMP", expression.expression) 1144 1145 return super().extract_sql(expression) 1146 1147 def datatype_sql(self, expression: exp.DataType) -> str: 1148 if ( 1149 self.VARCHAR_REQUIRES_SIZE 1150 and expression.is_type(exp.DataType.Type.VARCHAR) 1151 and not expression.expressions 1152 ): 1153 # `VARCHAR` must always have a size - if it doesn't, we always generate `TEXT` 1154 return "TEXT" 1155 1156 # https://dev.mysql.com/doc/refman/8.0/en/numeric-type-syntax.html 1157 result = super().datatype_sql(expression) 1158 if expression.this in self.UNSIGNED_TYPE_MAPPING: 1159 result = f"{result} UNSIGNED" 1160 1161 return result 1162 1163 def jsonarraycontains_sql(self, expression: exp.JSONArrayContains) -> str: 1164 return f"{self.sql(expression, 'this')} MEMBER OF({self.sql(expression, 'expression')})" 1165 1166 def cast_sql(self, expression: exp.Cast, safe_prefix: t.Optional[str] = None) -> str: 1167 if expression.to.this in self.TIMESTAMP_FUNC_TYPES: 1168 return self.func("TIMESTAMP", expression.this) 1169 1170 to = self.CAST_MAPPING.get(expression.to.this) 1171 1172 if to: 1173 expression.to.set("this", to) 1174 return super().cast_sql(expression) 1175 1176 def show_sql(self, expression: exp.Show) -> str: 1177 this = f" {expression.name}" 1178 full = " FULL" if expression.args.get("full") else "" 1179 global_ = " GLOBAL" if expression.args.get("global") else "" 1180 1181 target = self.sql(expression, "target") 1182 target = f" {target}" if target else "" 1183 if expression.name in ("COLUMNS", "INDEX"): 1184 target = f" FROM{target}" 1185 elif expression.name == "GRANTS": 1186 target = f" FOR{target}" 1187 1188 db = self._prefixed_sql("FROM", expression, "db") 1189 1190 like = self._prefixed_sql("LIKE", expression, "like") 1191 where = self.sql(expression, "where") 1192 1193 types = self.expressions(expression, key="types") 1194 types = f" {types}" if types else types 1195 query = self._prefixed_sql("FOR QUERY", expression, "query") 1196 1197 if expression.name == "PROFILE": 1198 offset = self._prefixed_sql("OFFSET", expression, "offset") 1199 limit = self._prefixed_sql("LIMIT", expression, "limit") 1200 else: 1201 offset = "" 1202 limit = self._oldstyle_limit_sql(expression) 1203 1204 log = self._prefixed_sql("IN", expression, "log") 1205 position = self._prefixed_sql("FROM", expression, "position") 1206 1207 channel = self._prefixed_sql("FOR CHANNEL", expression, "channel") 1208 1209 if expression.name == "ENGINE": 1210 mutex_or_status = " MUTEX" if expression.args.get("mutex") else " STATUS" 1211 else: 1212 mutex_or_status = "" 1213 1214 return f"SHOW{full}{global_}{this}{target}{types}{db}{query}{log}{position}{channel}{mutex_or_status}{like}{where}{offset}{limit}" 1215 1216 def altercolumn_sql(self, expression: exp.AlterColumn) -> str: 1217 dtype = self.sql(expression, "dtype") 1218 if not dtype: 1219 return super().altercolumn_sql(expression) 1220 1221 this = self.sql(expression, "this") 1222 return f"MODIFY COLUMN {this} {dtype}" 1223 1224 def _prefixed_sql(self, prefix: str, expression: exp.Expression, arg: str) -> str: 1225 sql = self.sql(expression, arg) 1226 return f" {prefix} {sql}" if sql else "" 1227 1228 def _oldstyle_limit_sql(self, expression: exp.Show) -> str: 1229 limit = self.sql(expression, "limit") 1230 offset = self.sql(expression, "offset") 1231 if limit: 1232 limit_offset = f"{offset}, {limit}" if offset else limit 1233 return f" LIMIT {limit_offset}" 1234 return "" 1235 1236 def chr_sql(self, expression: exp.Chr) -> str: 1237 this = self.expressions(sqls=[expression.this] + expression.expressions) 1238 charset = expression.args.get("charset") 1239 using = f" USING {self.sql(charset)}" if charset else "" 1240 return f"CHAR({this}{using})" 1241 1242 def timestamptrunc_sql(self, expression: exp.TimestampTrunc) -> str: 1243 unit = expression.args.get("unit") 1244 1245 # Pick an old-enough date to avoid negative timestamp diffs 1246 start_ts = "'0000-01-01 00:00:00'" 1247 1248 # Source: https://stackoverflow.com/a/32955740 1249 timestamp_diff = build_date_delta(exp.TimestampDiff)([unit, start_ts, expression.this]) 1250 interval = exp.Interval(this=timestamp_diff, unit=unit) 1251 dateadd = build_date_delta_with_interval(exp.DateAdd)([start_ts, interval]) 1252 1253 return self.sql(dateadd) 1254 1255 def converttimezone_sql(self, expression: exp.ConvertTimezone) -> str: 1256 from_tz = expression.args.get("source_tz") 1257 to_tz = expression.args.get("target_tz") 1258 dt = expression.args.get("timestamp") 1259 1260 return self.func("CONVERT_TZ", dt, from_tz, to_tz) 1261 1262 def attimezone_sql(self, expression: exp.AtTimeZone) -> str: 1263 self.unsupported("AT TIME ZONE is not supported by MySQL") 1264 return self.sql(expression.this) 1265 1266 def isascii_sql(self, expression: exp.IsAscii) -> str: 1267 return f"REGEXP_LIKE({self.sql(expression.this)}, '^[[:ascii:]]*$')"
TIME_SPECIFIERS =
{'i', 'k', 's', 'H', 'f', 'h', 'l', 'S', 'r', 'I', 'p', 'T'}
def
date_add_sql( kind: str) -> Callable[[sqlglot.generator.Generator, sqlglot.expressions.Expression], str]:
116def date_add_sql( 117 kind: str, 118) -> t.Callable[[generator.Generator, exp.Expression], str]: 119 def func(self: generator.Generator, expression: exp.Expression) -> str: 120 return self.func( 121 f"DATE_{kind}", 122 expression.this, 123 exp.Interval(this=expression.expression, unit=unit_to_var(expression)), 124 ) 125 126 return func
149class MySQL(Dialect): 150 PROMOTE_TO_INFERRED_DATETIME_TYPE = True 151 152 # https://dev.mysql.com/doc/refman/8.0/en/identifiers.html 153 IDENTIFIERS_CAN_START_WITH_DIGIT = True 154 155 # We default to treating all identifiers as case-sensitive, since it matches MySQL's 156 # behavior on Linux systems. For MacOS and Windows systems, one can override this 157 # setting by specifying `dialect="mysql, normalization_strategy = lowercase"`. 158 # 159 # See also https://dev.mysql.com/doc/refman/8.2/en/identifier-case-sensitivity.html 160 NORMALIZATION_STRATEGY = NormalizationStrategy.CASE_SENSITIVE 161 162 TIME_FORMAT = "'%Y-%m-%d %T'" 163 DPIPE_IS_STRING_CONCAT = False 164 SUPPORTS_USER_DEFINED_TYPES = False 165 SUPPORTS_SEMI_ANTI_JOIN = False 166 SAFE_DIVISION = True 167 168 # https://prestodb.io/docs/current/functions/datetime.html#mysql-date-functions 169 TIME_MAPPING = { 170 "%M": "%B", 171 "%c": "%-m", 172 "%e": "%-d", 173 "%h": "%I", 174 "%i": "%M", 175 "%s": "%S", 176 "%u": "%W", 177 "%k": "%-H", 178 "%l": "%-I", 179 "%T": "%H:%M:%S", 180 "%W": "%A", 181 } 182 183 class Tokenizer(tokens.Tokenizer): 184 QUOTES = ["'", '"'] 185 COMMENTS = ["--", "#", ("/*", "*/")] 186 IDENTIFIERS = ["`"] 187 STRING_ESCAPES = ["'", '"', "\\"] 188 BIT_STRINGS = [("b'", "'"), ("B'", "'"), ("0b", "")] 189 HEX_STRINGS = [("x'", "'"), ("X'", "'"), ("0x", "")] 190 191 KEYWORDS = { 192 **tokens.Tokenizer.KEYWORDS, 193 "CHARSET": TokenType.CHARACTER_SET, 194 # The DESCRIBE and EXPLAIN statements are synonyms. 195 # https://dev.mysql.com/doc/refman/8.4/en/explain.html 196 "EXPLAIN": TokenType.DESCRIBE, 197 "FORCE": TokenType.FORCE, 198 "IGNORE": TokenType.IGNORE, 199 "KEY": TokenType.KEY, 200 "LOCK TABLES": TokenType.COMMAND, 201 "LONGBLOB": TokenType.LONGBLOB, 202 "LONGTEXT": TokenType.LONGTEXT, 203 "MEDIUMBLOB": TokenType.MEDIUMBLOB, 204 "TINYBLOB": TokenType.TINYBLOB, 205 "TINYTEXT": TokenType.TINYTEXT, 206 "MEDIUMTEXT": TokenType.MEDIUMTEXT, 207 "MEDIUMINT": TokenType.MEDIUMINT, 208 "MEMBER OF": TokenType.MEMBER_OF, 209 "SEPARATOR": TokenType.SEPARATOR, 210 "SERIAL": TokenType.SERIAL, 211 "START": TokenType.BEGIN, 212 "SIGNED": TokenType.BIGINT, 213 "SIGNED INTEGER": TokenType.BIGINT, 214 "UNLOCK TABLES": TokenType.COMMAND, 215 "UNSIGNED": TokenType.UBIGINT, 216 "UNSIGNED INTEGER": TokenType.UBIGINT, 217 "YEAR": TokenType.YEAR, 218 "_ARMSCII8": TokenType.INTRODUCER, 219 "_ASCII": TokenType.INTRODUCER, 220 "_BIG5": TokenType.INTRODUCER, 221 "_BINARY": TokenType.INTRODUCER, 222 "_CP1250": TokenType.INTRODUCER, 223 "_CP1251": TokenType.INTRODUCER, 224 "_CP1256": TokenType.INTRODUCER, 225 "_CP1257": TokenType.INTRODUCER, 226 "_CP850": TokenType.INTRODUCER, 227 "_CP852": TokenType.INTRODUCER, 228 "_CP866": TokenType.INTRODUCER, 229 "_CP932": TokenType.INTRODUCER, 230 "_DEC8": TokenType.INTRODUCER, 231 "_EUCJPMS": TokenType.INTRODUCER, 232 "_EUCKR": TokenType.INTRODUCER, 233 "_GB18030": TokenType.INTRODUCER, 234 "_GB2312": TokenType.INTRODUCER, 235 "_GBK": TokenType.INTRODUCER, 236 "_GEOSTD8": TokenType.INTRODUCER, 237 "_GREEK": TokenType.INTRODUCER, 238 "_HEBREW": TokenType.INTRODUCER, 239 "_HP8": TokenType.INTRODUCER, 240 "_KEYBCS2": TokenType.INTRODUCER, 241 "_KOI8R": TokenType.INTRODUCER, 242 "_KOI8U": TokenType.INTRODUCER, 243 "_LATIN1": TokenType.INTRODUCER, 244 "_LATIN2": TokenType.INTRODUCER, 245 "_LATIN5": TokenType.INTRODUCER, 246 "_LATIN7": TokenType.INTRODUCER, 247 "_MACCE": TokenType.INTRODUCER, 248 "_MACROMAN": TokenType.INTRODUCER, 249 "_SJIS": TokenType.INTRODUCER, 250 "_SWE7": TokenType.INTRODUCER, 251 "_TIS620": TokenType.INTRODUCER, 252 "_UCS2": TokenType.INTRODUCER, 253 "_UJIS": TokenType.INTRODUCER, 254 # https://dev.mysql.com/doc/refman/8.0/en/string-literals.html 255 "_UTF8": TokenType.INTRODUCER, 256 "_UTF16": TokenType.INTRODUCER, 257 "_UTF16LE": TokenType.INTRODUCER, 258 "_UTF32": TokenType.INTRODUCER, 259 "_UTF8MB3": TokenType.INTRODUCER, 260 "_UTF8MB4": TokenType.INTRODUCER, 261 "@@": TokenType.SESSION_PARAMETER, 262 } 263 264 COMMANDS = {*tokens.Tokenizer.COMMANDS, TokenType.REPLACE} - {TokenType.SHOW} 265 266 class Parser(parser.Parser): 267 FUNC_TOKENS = { 268 *parser.Parser.FUNC_TOKENS, 269 TokenType.DATABASE, 270 TokenType.SCHEMA, 271 TokenType.VALUES, 272 } 273 274 CONJUNCTION = { 275 **parser.Parser.CONJUNCTION, 276 TokenType.DAMP: exp.And, 277 TokenType.XOR: exp.Xor, 278 } 279 280 DISJUNCTION = { 281 **parser.Parser.DISJUNCTION, 282 TokenType.DPIPE: exp.Or, 283 } 284 285 TABLE_ALIAS_TOKENS = ( 286 parser.Parser.TABLE_ALIAS_TOKENS - parser.Parser.TABLE_INDEX_HINT_TOKENS 287 ) 288 289 RANGE_PARSERS = { 290 **parser.Parser.RANGE_PARSERS, 291 TokenType.MEMBER_OF: lambda self, this: self.expression( 292 exp.JSONArrayContains, 293 this=this, 294 expression=self._parse_wrapped(self._parse_expression), 295 ), 296 } 297 298 FUNCTIONS = { 299 **parser.Parser.FUNCTIONS, 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 "LENGTH": lambda args: exp.Length(this=seq_get(args, 0), binary=True), 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: length_or_char_length_sql, 736 exp.LogicalOr: rename_func("MAX"), 737 exp.LogicalAnd: rename_func("MIN"), 738 exp.Max: max_or_greatest, 739 exp.Min: min_or_least, 740 exp.Month: _remove_ts_or_ds_to_date(), 741 exp.NullSafeEQ: lambda self, e: self.binary(e, "<=>"), 742 exp.NullSafeNEQ: lambda self, e: f"NOT {self.binary(e, '<=>')}", 743 exp.NumberToStr: rename_func("FORMAT"), 744 exp.Pivot: no_pivot_sql, 745 exp.Select: transforms.preprocess( 746 [ 747 transforms.eliminate_distinct_on, 748 transforms.eliminate_semi_and_anti_joins, 749 transforms.eliminate_qualify, 750 transforms.eliminate_full_outer_join, 751 transforms.unnest_generate_date_array_using_recursive_cte, 752 ] 753 ), 754 exp.StrPosition: strposition_to_locate_sql, 755 exp.StrToDate: _str_to_date_sql, 756 exp.StrToTime: _str_to_date_sql, 757 exp.Stuff: rename_func("INSERT"), 758 exp.TableSample: no_tablesample_sql, 759 exp.TimeFromParts: rename_func("MAKETIME"), 760 exp.TimestampAdd: date_add_interval_sql("DATE", "ADD"), 761 exp.TimestampDiff: lambda self, e: self.func( 762 "TIMESTAMPDIFF", unit_to_var(e), e.expression, e.this 763 ), 764 exp.TimestampSub: date_add_interval_sql("DATE", "SUB"), 765 exp.TimeStrToUnix: rename_func("UNIX_TIMESTAMP"), 766 exp.TimeStrToTime: lambda self, e: timestrtotime_sql( 767 self, 768 e, 769 include_precision=not e.args.get("zone"), 770 ), 771 exp.TimeToStr: _remove_ts_or_ds_to_date( 772 lambda self, e: self.func("DATE_FORMAT", e.this, self.format_time(e)) 773 ), 774 exp.Trim: trim_sql, 775 exp.TryCast: no_trycast_sql, 776 exp.TsOrDsAdd: date_add_sql("ADD"), 777 exp.TsOrDsDiff: lambda self, e: self.func("DATEDIFF", e.this, e.expression), 778 exp.TsOrDsToDate: _ts_or_ds_to_date_sql, 779 exp.Unicode: lambda self, e: f"ORD(CONVERT({self.sql(e.this)} USING utf32))", 780 exp.UnixToTime: _unix_to_time_sql, 781 exp.Week: _remove_ts_or_ds_to_date(), 782 exp.WeekOfYear: _remove_ts_or_ds_to_date(rename_func("WEEKOFYEAR")), 783 exp.Year: _remove_ts_or_ds_to_date(), 784 } 785 786 UNSIGNED_TYPE_MAPPING = { 787 exp.DataType.Type.UBIGINT: "BIGINT", 788 exp.DataType.Type.UINT: "INT", 789 exp.DataType.Type.UMEDIUMINT: "MEDIUMINT", 790 exp.DataType.Type.USMALLINT: "SMALLINT", 791 exp.DataType.Type.UTINYINT: "TINYINT", 792 exp.DataType.Type.UDECIMAL: "DECIMAL", 793 } 794 795 TIMESTAMP_TYPE_MAPPING = { 796 exp.DataType.Type.DATETIME2: "DATETIME", 797 exp.DataType.Type.SMALLDATETIME: "DATETIME", 798 exp.DataType.Type.TIMESTAMP: "DATETIME", 799 exp.DataType.Type.TIMESTAMPTZ: "TIMESTAMP", 800 exp.DataType.Type.TIMESTAMPLTZ: "TIMESTAMP", 801 } 802 803 TYPE_MAPPING = { 804 **generator.Generator.TYPE_MAPPING, 805 **UNSIGNED_TYPE_MAPPING, 806 **TIMESTAMP_TYPE_MAPPING, 807 } 808 809 TYPE_MAPPING.pop(exp.DataType.Type.MEDIUMTEXT) 810 TYPE_MAPPING.pop(exp.DataType.Type.LONGTEXT) 811 TYPE_MAPPING.pop(exp.DataType.Type.TINYTEXT) 812 TYPE_MAPPING.pop(exp.DataType.Type.MEDIUMBLOB) 813 TYPE_MAPPING.pop(exp.DataType.Type.LONGBLOB) 814 TYPE_MAPPING.pop(exp.DataType.Type.TINYBLOB) 815 816 PROPERTIES_LOCATION = { 817 **generator.Generator.PROPERTIES_LOCATION, 818 exp.TransientProperty: exp.Properties.Location.UNSUPPORTED, 819 exp.VolatileProperty: exp.Properties.Location.UNSUPPORTED, 820 } 821 822 LIMIT_FETCH = "LIMIT" 823 824 LIMIT_ONLY_LITERALS = True 825 826 CHAR_CAST_MAPPING = dict.fromkeys( 827 ( 828 exp.DataType.Type.LONGTEXT, 829 exp.DataType.Type.LONGBLOB, 830 exp.DataType.Type.MEDIUMBLOB, 831 exp.DataType.Type.MEDIUMTEXT, 832 exp.DataType.Type.TEXT, 833 exp.DataType.Type.TINYBLOB, 834 exp.DataType.Type.TINYTEXT, 835 exp.DataType.Type.VARCHAR, 836 ), 837 "CHAR", 838 ) 839 SIGNED_CAST_MAPPING = dict.fromkeys( 840 ( 841 exp.DataType.Type.BIGINT, 842 exp.DataType.Type.BOOLEAN, 843 exp.DataType.Type.INT, 844 exp.DataType.Type.SMALLINT, 845 exp.DataType.Type.TINYINT, 846 exp.DataType.Type.MEDIUMINT, 847 ), 848 "SIGNED", 849 ) 850 851 # MySQL doesn't support many datatypes in cast. 852 # https://dev.mysql.com/doc/refman/8.0/en/cast-functions.html#function_cast 853 CAST_MAPPING = { 854 **CHAR_CAST_MAPPING, 855 **SIGNED_CAST_MAPPING, 856 exp.DataType.Type.UBIGINT: "UNSIGNED", 857 } 858 859 TIMESTAMP_FUNC_TYPES = { 860 exp.DataType.Type.TIMESTAMPTZ, 861 exp.DataType.Type.TIMESTAMPLTZ, 862 } 863 864 # https://dev.mysql.com/doc/refman/8.0/en/keywords.html 865 RESERVED_KEYWORDS = { 866 "accessible", 867 "add", 868 "all", 869 "alter", 870 "analyze", 871 "and", 872 "as", 873 "asc", 874 "asensitive", 875 "before", 876 "between", 877 "bigint", 878 "binary", 879 "blob", 880 "both", 881 "by", 882 "call", 883 "cascade", 884 "case", 885 "change", 886 "char", 887 "character", 888 "check", 889 "collate", 890 "column", 891 "condition", 892 "constraint", 893 "continue", 894 "convert", 895 "create", 896 "cross", 897 "cube", 898 "cume_dist", 899 "current_date", 900 "current_time", 901 "current_timestamp", 902 "current_user", 903 "cursor", 904 "database", 905 "databases", 906 "day_hour", 907 "day_microsecond", 908 "day_minute", 909 "day_second", 910 "dec", 911 "decimal", 912 "declare", 913 "default", 914 "delayed", 915 "delete", 916 "dense_rank", 917 "desc", 918 "describe", 919 "deterministic", 920 "distinct", 921 "distinctrow", 922 "div", 923 "double", 924 "drop", 925 "dual", 926 "each", 927 "else", 928 "elseif", 929 "empty", 930 "enclosed", 931 "escaped", 932 "except", 933 "exists", 934 "exit", 935 "explain", 936 "false", 937 "fetch", 938 "first_value", 939 "float", 940 "float4", 941 "float8", 942 "for", 943 "force", 944 "foreign", 945 "from", 946 "fulltext", 947 "function", 948 "generated", 949 "get", 950 "grant", 951 "group", 952 "grouping", 953 "groups", 954 "having", 955 "high_priority", 956 "hour_microsecond", 957 "hour_minute", 958 "hour_second", 959 "if", 960 "ignore", 961 "in", 962 "index", 963 "infile", 964 "inner", 965 "inout", 966 "insensitive", 967 "insert", 968 "int", 969 "int1", 970 "int2", 971 "int3", 972 "int4", 973 "int8", 974 "integer", 975 "intersect", 976 "interval", 977 "into", 978 "io_after_gtids", 979 "io_before_gtids", 980 "is", 981 "iterate", 982 "join", 983 "json_table", 984 "key", 985 "keys", 986 "kill", 987 "lag", 988 "last_value", 989 "lateral", 990 "lead", 991 "leading", 992 "leave", 993 "left", 994 "like", 995 "limit", 996 "linear", 997 "lines", 998 "load", 999 "localtime", 1000 "localtimestamp", 1001 "lock", 1002 "long", 1003 "longblob", 1004 "longtext", 1005 "loop", 1006 "low_priority", 1007 "master_bind", 1008 "master_ssl_verify_server_cert", 1009 "match", 1010 "maxvalue", 1011 "mediumblob", 1012 "mediumint", 1013 "mediumtext", 1014 "middleint", 1015 "minute_microsecond", 1016 "minute_second", 1017 "mod", 1018 "modifies", 1019 "natural", 1020 "not", 1021 "no_write_to_binlog", 1022 "nth_value", 1023 "ntile", 1024 "null", 1025 "numeric", 1026 "of", 1027 "on", 1028 "optimize", 1029 "optimizer_costs", 1030 "option", 1031 "optionally", 1032 "or", 1033 "order", 1034 "out", 1035 "outer", 1036 "outfile", 1037 "over", 1038 "partition", 1039 "percent_rank", 1040 "precision", 1041 "primary", 1042 "procedure", 1043 "purge", 1044 "range", 1045 "rank", 1046 "read", 1047 "reads", 1048 "read_write", 1049 "real", 1050 "recursive", 1051 "references", 1052 "regexp", 1053 "release", 1054 "rename", 1055 "repeat", 1056 "replace", 1057 "require", 1058 "resignal", 1059 "restrict", 1060 "return", 1061 "revoke", 1062 "right", 1063 "rlike", 1064 "row", 1065 "rows", 1066 "row_number", 1067 "schema", 1068 "schemas", 1069 "second_microsecond", 1070 "select", 1071 "sensitive", 1072 "separator", 1073 "set", 1074 "show", 1075 "signal", 1076 "smallint", 1077 "spatial", 1078 "specific", 1079 "sql", 1080 "sqlexception", 1081 "sqlstate", 1082 "sqlwarning", 1083 "sql_big_result", 1084 "sql_calc_found_rows", 1085 "sql_small_result", 1086 "ssl", 1087 "starting", 1088 "stored", 1089 "straight_join", 1090 "system", 1091 "table", 1092 "terminated", 1093 "then", 1094 "tinyblob", 1095 "tinyint", 1096 "tinytext", 1097 "to", 1098 "trailing", 1099 "trigger", 1100 "true", 1101 "undo", 1102 "union", 1103 "unique", 1104 "unlock", 1105 "unsigned", 1106 "update", 1107 "usage", 1108 "use", 1109 "using", 1110 "utc_date", 1111 "utc_time", 1112 "utc_timestamp", 1113 "values", 1114 "varbinary", 1115 "varchar", 1116 "varcharacter", 1117 "varying", 1118 "virtual", 1119 "when", 1120 "where", 1121 "while", 1122 "window", 1123 "with", 1124 "write", 1125 "xor", 1126 "year_month", 1127 "zerofill", 1128 } 1129 1130 def array_sql(self, expression: exp.Array) -> str: 1131 self.unsupported("Arrays are not supported by MySQL") 1132 return self.function_fallback_sql(expression) 1133 1134 def arraycontainsall_sql(self, expression: exp.ArrayContainsAll) -> str: 1135 self.unsupported("Array operations are not supported by MySQL") 1136 return self.function_fallback_sql(expression) 1137 1138 def dpipe_sql(self, expression: exp.DPipe) -> str: 1139 return self.func("CONCAT", *expression.flatten()) 1140 1141 def extract_sql(self, expression: exp.Extract) -> str: 1142 unit = expression.name 1143 if unit and unit.lower() == "epoch": 1144 return self.func("UNIX_TIMESTAMP", expression.expression) 1145 1146 return super().extract_sql(expression) 1147 1148 def datatype_sql(self, expression: exp.DataType) -> str: 1149 if ( 1150 self.VARCHAR_REQUIRES_SIZE 1151 and expression.is_type(exp.DataType.Type.VARCHAR) 1152 and not expression.expressions 1153 ): 1154 # `VARCHAR` must always have a size - if it doesn't, we always generate `TEXT` 1155 return "TEXT" 1156 1157 # https://dev.mysql.com/doc/refman/8.0/en/numeric-type-syntax.html 1158 result = super().datatype_sql(expression) 1159 if expression.this in self.UNSIGNED_TYPE_MAPPING: 1160 result = f"{result} UNSIGNED" 1161 1162 return result 1163 1164 def jsonarraycontains_sql(self, expression: exp.JSONArrayContains) -> str: 1165 return f"{self.sql(expression, 'this')} MEMBER OF({self.sql(expression, 'expression')})" 1166 1167 def cast_sql(self, expression: exp.Cast, safe_prefix: t.Optional[str] = None) -> str: 1168 if expression.to.this in self.TIMESTAMP_FUNC_TYPES: 1169 return self.func("TIMESTAMP", expression.this) 1170 1171 to = self.CAST_MAPPING.get(expression.to.this) 1172 1173 if to: 1174 expression.to.set("this", to) 1175 return super().cast_sql(expression) 1176 1177 def show_sql(self, expression: exp.Show) -> str: 1178 this = f" {expression.name}" 1179 full = " FULL" if expression.args.get("full") else "" 1180 global_ = " GLOBAL" if expression.args.get("global") else "" 1181 1182 target = self.sql(expression, "target") 1183 target = f" {target}" if target else "" 1184 if expression.name in ("COLUMNS", "INDEX"): 1185 target = f" FROM{target}" 1186 elif expression.name == "GRANTS": 1187 target = f" FOR{target}" 1188 1189 db = self._prefixed_sql("FROM", expression, "db") 1190 1191 like = self._prefixed_sql("LIKE", expression, "like") 1192 where = self.sql(expression, "where") 1193 1194 types = self.expressions(expression, key="types") 1195 types = f" {types}" if types else types 1196 query = self._prefixed_sql("FOR QUERY", expression, "query") 1197 1198 if expression.name == "PROFILE": 1199 offset = self._prefixed_sql("OFFSET", expression, "offset") 1200 limit = self._prefixed_sql("LIMIT", expression, "limit") 1201 else: 1202 offset = "" 1203 limit = self._oldstyle_limit_sql(expression) 1204 1205 log = self._prefixed_sql("IN", expression, "log") 1206 position = self._prefixed_sql("FROM", expression, "position") 1207 1208 channel = self._prefixed_sql("FOR CHANNEL", expression, "channel") 1209 1210 if expression.name == "ENGINE": 1211 mutex_or_status = " MUTEX" if expression.args.get("mutex") else " STATUS" 1212 else: 1213 mutex_or_status = "" 1214 1215 return f"SHOW{full}{global_}{this}{target}{types}{db}{query}{log}{position}{channel}{mutex_or_status}{like}{where}{offset}{limit}" 1216 1217 def altercolumn_sql(self, expression: exp.AlterColumn) -> str: 1218 dtype = self.sql(expression, "dtype") 1219 if not dtype: 1220 return super().altercolumn_sql(expression) 1221 1222 this = self.sql(expression, "this") 1223 return f"MODIFY COLUMN {this} {dtype}" 1224 1225 def _prefixed_sql(self, prefix: str, expression: exp.Expression, arg: str) -> str: 1226 sql = self.sql(expression, arg) 1227 return f" {prefix} {sql}" if sql else "" 1228 1229 def _oldstyle_limit_sql(self, expression: exp.Show) -> str: 1230 limit = self.sql(expression, "limit") 1231 offset = self.sql(expression, "offset") 1232 if limit: 1233 limit_offset = f"{offset}, {limit}" if offset else limit 1234 return f" LIMIT {limit_offset}" 1235 return "" 1236 1237 def chr_sql(self, expression: exp.Chr) -> str: 1238 this = self.expressions(sqls=[expression.this] + expression.expressions) 1239 charset = expression.args.get("charset") 1240 using = f" USING {self.sql(charset)}" if charset else "" 1241 return f"CHAR({this}{using})" 1242 1243 def timestamptrunc_sql(self, expression: exp.TimestampTrunc) -> str: 1244 unit = expression.args.get("unit") 1245 1246 # Pick an old-enough date to avoid negative timestamp diffs 1247 start_ts = "'0000-01-01 00:00:00'" 1248 1249 # Source: https://stackoverflow.com/a/32955740 1250 timestamp_diff = build_date_delta(exp.TimestampDiff)([unit, start_ts, expression.this]) 1251 interval = exp.Interval(this=timestamp_diff, unit=unit) 1252 dateadd = build_date_delta_with_interval(exp.DateAdd)([start_ts, interval]) 1253 1254 return self.sql(dateadd) 1255 1256 def converttimezone_sql(self, expression: exp.ConvertTimezone) -> str: 1257 from_tz = expression.args.get("source_tz") 1258 to_tz = expression.args.get("target_tz") 1259 dt = expression.args.get("timestamp") 1260 1261 return self.func("CONVERT_TZ", dt, from_tz, to_tz) 1262 1263 def attimezone_sql(self, expression: exp.AtTimeZone) -> str: 1264 self.unsupported("AT TIME ZONE is not supported by MySQL") 1265 return self.sql(expression.this) 1266 1267 def isascii_sql(self, expression: exp.IsAscii) -> str: 1268 return f"REGEXP_LIKE({self.sql(expression.this)}, '^[[:ascii:]]*$')"
PROMOTE_TO_INFERRED_DATETIME_TYPE =
True
This flag is used in the optimizer's canonicalize rule and determines whether x will be promoted to the literal's type in x::DATE < '2020-01-01 12:05:03' (i.e., DATETIME). When false, the literal is cast to x's type to match it instead.
NORMALIZATION_STRATEGY =
<NormalizationStrategy.CASE_SENSITIVE: 'CASE_SENSITIVE'>
Specifies the strategy according to which identifiers should be normalized.
TIME_MAPPING: Dict[str, str] =
{'%M': '%B', '%c': '%-m', '%e': '%-d', '%h': '%I', '%i': '%M', '%s': '%S', '%u': '%W', '%k': '%-H', '%l': '%-I', '%T': '%H:%M:%S', '%W': '%A'}
Associates this dialect's time formats with their equivalent Python strftime
formats.
UNESCAPED_SEQUENCES: Dict[str, str] =
{'\\a': '\x07', '\\b': '\x08', '\\f': '\x0c', '\\n': '\n', '\\r': '\r', '\\t': '\t', '\\v': '\x0b', '\\\\': '\\'}
Mapping of an escaped sequence (\n
) to its unescaped version (
).
tokenizer_class =
<class 'MySQL.Tokenizer'>
parser_class =
<class 'MySQL.Parser'>
generator_class =
<class 'MySQL.Generator'>
TIME_TRIE: Dict =
{'%': {'M': {0: True}, 'c': {0: True}, 'e': {0: True}, 'h': {0: True}, 'i': {0: True}, 's': {0: True}, 'u': {0: True}, 'k': {0: True}, 'l': {0: True}, 'T': {0: True}, 'W': {0: True}}}
FORMAT_TRIE: Dict =
{'%': {'M': {0: True}, 'c': {0: True}, 'e': {0: True}, 'h': {0: True}, 'i': {0: True}, 's': {0: True}, 'u': {0: True}, 'k': {0: True}, 'l': {0: True}, 'T': {0: True}, 'W': {0: True}}}
INVERSE_TIME_MAPPING: Dict[str, str] =
{'%B': '%M', '%-m': '%c', '%-d': '%e', '%I': '%h', '%M': '%i', '%S': '%s', '%W': '%u', '%-H': '%k', '%-I': '%l', '%H:%M:%S': '%T', '%A': '%W'}
INVERSE_TIME_TRIE: Dict =
{'%': {'B': {0: True}, '-': {'m': {0: True}, 'd': {0: True}, 'H': {0: True}, 'I': {0: True}}, 'I': {0: True}, 'M': {0: True}, 'S': {0: True}, 'W': {0: True}, 'H': {':': {'%': {'M': {':': {'%': {'S': {0: True}}}}}}}, 'A': {0: True}}}
ESCAPED_SEQUENCES: Dict[str, str] =
{'\x07': '\\a', '\x08': '\\b', '\x0c': '\\f', '\n': '\\n', '\r': '\\r', '\t': '\\t', '\x0b': '\\v', '\\': '\\\\'}
Inherited Members
- sqlglot.dialects.dialect.Dialect
- Dialect
- INDEX_OFFSET
- WEEK_OFFSET
- UNNEST_COLUMN_ONLY
- ALIAS_POST_TABLESAMPLE
- TABLESAMPLE_SIZE_IS_PERCENT
- STRICT_STRING_CONCAT
- COPY_PARAMS_ARE_CSV
- NORMALIZE_FUNCTIONS
- PRESERVE_ORIGINAL_NAMES
- LOG_BASE_FIRST
- NULL_ORDERING
- TYPED_DIVISION
- CONCAT_COALESCE
- HEX_LOWERCASE
- DATE_FORMAT
- DATEINT_FORMAT
- FORMAT_MAPPING
- PSEUDOCOLUMNS
- PREFER_CTE_ALIAS_COLUMN
- FORCE_EARLY_ALIAS_REF_EXPANSION
- EXPAND_ALIAS_REFS_EARLY_ONLY_IN_GROUP_BY
- SUPPORTS_ORDER_BY_ALL
- HAS_DISTINCT_ARRAY_CONSTRUCTORS
- SUPPORTS_FIXED_SIZE_ARRAYS
- STRICT_JSON_PATH_SYNTAX
- ON_CONDITION_EMPTY_BEFORE_ERROR
- ARRAY_AGG_INCLUDES_NULLS
- SUPPORTS_VALUES_DEFAULT
- NUMBERS_CAN_BE_UNDERSCORE_SEPARATED
- REGEXP_EXTRACT_DEFAULT_GROUP
- SET_OP_DISTINCT_BY_DEFAULT
- CREATABLE_KIND_MAPPING
- DATE_PART_MAPPING
- TYPE_TO_EXPRESSIONS
- ANNOTATORS
- get_or_raise
- format_time
- settings
- normalize_identifier
- case_sensitive
- can_identify
- quote_identifier
- to_json_path
- parse
- parse_into
- generate
- transpile
- tokenize
- tokenizer
- jsonpath_tokenizer
- parser
- generator
183 class Tokenizer(tokens.Tokenizer): 184 QUOTES = ["'", '"'] 185 COMMENTS = ["--", "#", ("/*", "*/")] 186 IDENTIFIERS = ["`"] 187 STRING_ESCAPES = ["'", '"', "\\"] 188 BIT_STRINGS = [("b'", "'"), ("B'", "'"), ("0b", "")] 189 HEX_STRINGS = [("x'", "'"), ("X'", "'"), ("0x", "")] 190 191 KEYWORDS = { 192 **tokens.Tokenizer.KEYWORDS, 193 "CHARSET": TokenType.CHARACTER_SET, 194 # The DESCRIBE and EXPLAIN statements are synonyms. 195 # https://dev.mysql.com/doc/refman/8.4/en/explain.html 196 "EXPLAIN": TokenType.DESCRIBE, 197 "FORCE": TokenType.FORCE, 198 "IGNORE": TokenType.IGNORE, 199 "KEY": TokenType.KEY, 200 "LOCK TABLES": TokenType.COMMAND, 201 "LONGBLOB": TokenType.LONGBLOB, 202 "LONGTEXT": TokenType.LONGTEXT, 203 "MEDIUMBLOB": TokenType.MEDIUMBLOB, 204 "TINYBLOB": TokenType.TINYBLOB, 205 "TINYTEXT": TokenType.TINYTEXT, 206 "MEDIUMTEXT": TokenType.MEDIUMTEXT, 207 "MEDIUMINT": TokenType.MEDIUMINT, 208 "MEMBER OF": TokenType.MEMBER_OF, 209 "SEPARATOR": TokenType.SEPARATOR, 210 "SERIAL": TokenType.SERIAL, 211 "START": TokenType.BEGIN, 212 "SIGNED": TokenType.BIGINT, 213 "SIGNED INTEGER": TokenType.BIGINT, 214 "UNLOCK TABLES": TokenType.COMMAND, 215 "UNSIGNED": TokenType.UBIGINT, 216 "UNSIGNED INTEGER": TokenType.UBIGINT, 217 "YEAR": TokenType.YEAR, 218 "_ARMSCII8": TokenType.INTRODUCER, 219 "_ASCII": TokenType.INTRODUCER, 220 "_BIG5": TokenType.INTRODUCER, 221 "_BINARY": TokenType.INTRODUCER, 222 "_CP1250": TokenType.INTRODUCER, 223 "_CP1251": TokenType.INTRODUCER, 224 "_CP1256": TokenType.INTRODUCER, 225 "_CP1257": TokenType.INTRODUCER, 226 "_CP850": TokenType.INTRODUCER, 227 "_CP852": TokenType.INTRODUCER, 228 "_CP866": TokenType.INTRODUCER, 229 "_CP932": TokenType.INTRODUCER, 230 "_DEC8": TokenType.INTRODUCER, 231 "_EUCJPMS": TokenType.INTRODUCER, 232 "_EUCKR": TokenType.INTRODUCER, 233 "_GB18030": TokenType.INTRODUCER, 234 "_GB2312": TokenType.INTRODUCER, 235 "_GBK": TokenType.INTRODUCER, 236 "_GEOSTD8": TokenType.INTRODUCER, 237 "_GREEK": TokenType.INTRODUCER, 238 "_HEBREW": TokenType.INTRODUCER, 239 "_HP8": TokenType.INTRODUCER, 240 "_KEYBCS2": TokenType.INTRODUCER, 241 "_KOI8R": TokenType.INTRODUCER, 242 "_KOI8U": TokenType.INTRODUCER, 243 "_LATIN1": TokenType.INTRODUCER, 244 "_LATIN2": TokenType.INTRODUCER, 245 "_LATIN5": TokenType.INTRODUCER, 246 "_LATIN7": TokenType.INTRODUCER, 247 "_MACCE": TokenType.INTRODUCER, 248 "_MACROMAN": TokenType.INTRODUCER, 249 "_SJIS": TokenType.INTRODUCER, 250 "_SWE7": TokenType.INTRODUCER, 251 "_TIS620": TokenType.INTRODUCER, 252 "_UCS2": TokenType.INTRODUCER, 253 "_UJIS": TokenType.INTRODUCER, 254 # https://dev.mysql.com/doc/refman/8.0/en/string-literals.html 255 "_UTF8": TokenType.INTRODUCER, 256 "_UTF16": TokenType.INTRODUCER, 257 "_UTF16LE": TokenType.INTRODUCER, 258 "_UTF32": TokenType.INTRODUCER, 259 "_UTF8MB3": TokenType.INTRODUCER, 260 "_UTF8MB4": TokenType.INTRODUCER, 261 "@@": TokenType.SESSION_PARAMETER, 262 } 263 264 COMMANDS = {*tokens.Tokenizer.COMMANDS, TokenType.REPLACE} - {TokenType.SHOW}
KEYWORDS =
{'{%': <TokenType.BLOCK_START: 'BLOCK_START'>, '{%+': <TokenType.BLOCK_START: 'BLOCK_START'>, '{%-': <TokenType.BLOCK_START: 'BLOCK_START'>, '%}': <TokenType.BLOCK_END: 'BLOCK_END'>, '+%}': <TokenType.BLOCK_END: 'BLOCK_END'>, '-%}': <TokenType.BLOCK_END: 'BLOCK_END'>, '{{+': <TokenType.BLOCK_START: 'BLOCK_START'>, '{{-': <TokenType.BLOCK_START: 'BLOCK_START'>, '+}}': <TokenType.BLOCK_END: 'BLOCK_END'>, '-}}': <TokenType.BLOCK_END: 'BLOCK_END'>, '/*+': <TokenType.HINT: 'HINT'>, '==': <TokenType.EQ: 'EQ'>, '::': <TokenType.DCOLON: 'DCOLON'>, '||': <TokenType.DPIPE: 'DPIPE'>, '>=': <TokenType.GTE: 'GTE'>, '<=': <TokenType.LTE: 'LTE'>, '<>': <TokenType.NEQ: 'NEQ'>, '!=': <TokenType.NEQ: 'NEQ'>, ':=': <TokenType.COLON_EQ: 'COLON_EQ'>, '<=>': <TokenType.NULLSAFE_EQ: 'NULLSAFE_EQ'>, '->': <TokenType.ARROW: 'ARROW'>, '->>': <TokenType.DARROW: 'DARROW'>, '=>': <TokenType.FARROW: 'FARROW'>, '#>': <TokenType.HASH_ARROW: 'HASH_ARROW'>, '#>>': <TokenType.DHASH_ARROW: 'DHASH_ARROW'>, '<->': <TokenType.LR_ARROW: 'LR_ARROW'>, '&&': <TokenType.DAMP: 'DAMP'>, '??': <TokenType.DQMARK: 'DQMARK'>, '~~~': <TokenType.GLOB: 'GLOB'>, '~~': <TokenType.LIKE: 'LIKE'>, '~~*': <TokenType.ILIKE: 'ILIKE'>, '~*': <TokenType.IRLIKE: 'IRLIKE'>, 'ALL': <TokenType.ALL: 'ALL'>, 'ALWAYS': <TokenType.ALWAYS: 'ALWAYS'>, 'AND': <TokenType.AND: 'AND'>, 'ANTI': <TokenType.ANTI: 'ANTI'>, 'ANY': <TokenType.ANY: 'ANY'>, 'ASC': <TokenType.ASC: 'ASC'>, 'AS': <TokenType.ALIAS: 'ALIAS'>, 'ASOF': <TokenType.ASOF: 'ASOF'>, 'AUTOINCREMENT': <TokenType.AUTO_INCREMENT: 'AUTO_INCREMENT'>, 'AUTO_INCREMENT': <TokenType.AUTO_INCREMENT: 'AUTO_INCREMENT'>, 'BEGIN': <TokenType.BEGIN: 'BEGIN'>, 'BETWEEN': <TokenType.BETWEEN: 'BETWEEN'>, 'CACHE': <TokenType.CACHE: 'CACHE'>, 'UNCACHE': <TokenType.UNCACHE: 'UNCACHE'>, 'CASE': <TokenType.CASE: 'CASE'>, 'CHARACTER SET': <TokenType.CHARACTER_SET: 'CHARACTER_SET'>, 'CLUSTER BY': <TokenType.CLUSTER_BY: 'CLUSTER_BY'>, 'COLLATE': <TokenType.COLLATE: 'COLLATE'>, 'COLUMN': <TokenType.COLUMN: 'COLUMN'>, 'COMMIT': <TokenType.COMMIT: 'COMMIT'>, 'CONNECT BY': <TokenType.CONNECT_BY: 'CONNECT_BY'>, 'CONSTRAINT': <TokenType.CONSTRAINT: 'CONSTRAINT'>, 'COPY': <TokenType.COPY: 'COPY'>, 'CREATE': <TokenType.CREATE: 'CREATE'>, 'CROSS': <TokenType.CROSS: 'CROSS'>, 'CUBE': <TokenType.CUBE: 'CUBE'>, 'CURRENT_DATE': <TokenType.CURRENT_DATE: 'CURRENT_DATE'>, 'CURRENT_TIME': <TokenType.CURRENT_TIME: 'CURRENT_TIME'>, 'CURRENT_TIMESTAMP': <TokenType.CURRENT_TIMESTAMP: 'CURRENT_TIMESTAMP'>, 'CURRENT_USER': <TokenType.CURRENT_USER: 'CURRENT_USER'>, 'DATABASE': <TokenType.DATABASE: 'DATABASE'>, 'DEFAULT': <TokenType.DEFAULT: 'DEFAULT'>, 'DELETE': <TokenType.DELETE: 'DELETE'>, 'DESC': <TokenType.DESC: 'DESC'>, 'DESCRIBE': <TokenType.DESCRIBE: 'DESCRIBE'>, 'DISTINCT': <TokenType.DISTINCT: 'DISTINCT'>, 'DISTRIBUTE BY': <TokenType.DISTRIBUTE_BY: 'DISTRIBUTE_BY'>, 'DIV': <TokenType.DIV: 'DIV'>, 'DROP': <TokenType.DROP: 'DROP'>, 'ELSE': <TokenType.ELSE: 'ELSE'>, 'END': <TokenType.END: 'END'>, 'ENUM': <TokenType.ENUM: 'ENUM'>, 'ESCAPE': <TokenType.ESCAPE: 'ESCAPE'>, 'EXCEPT': <TokenType.EXCEPT: 'EXCEPT'>, 'EXECUTE': <TokenType.EXECUTE: 'EXECUTE'>, 'EXISTS': <TokenType.EXISTS: 'EXISTS'>, 'FALSE': <TokenType.FALSE: 'FALSE'>, 'FETCH': <TokenType.FETCH: 'FETCH'>, 'FILTER': <TokenType.FILTER: 'FILTER'>, 'FIRST': <TokenType.FIRST: 'FIRST'>, 'FULL': <TokenType.FULL: 'FULL'>, 'FUNCTION': <TokenType.FUNCTION: 'FUNCTION'>, 'FOR': <TokenType.FOR: 'FOR'>, 'FOREIGN KEY': <TokenType.FOREIGN_KEY: 'FOREIGN_KEY'>, 'FORMAT': <TokenType.FORMAT: 'FORMAT'>, 'FROM': <TokenType.FROM: 'FROM'>, 'GEOGRAPHY': <TokenType.GEOGRAPHY: 'GEOGRAPHY'>, 'GEOMETRY': <TokenType.GEOMETRY: 'GEOMETRY'>, 'GLOB': <TokenType.GLOB: 'GLOB'>, 'GROUP BY': <TokenType.GROUP_BY: 'GROUP_BY'>, 'GROUPING SETS': <TokenType.GROUPING_SETS: 'GROUPING_SETS'>, 'HAVING': <TokenType.HAVING: 'HAVING'>, 'ILIKE': <TokenType.ILIKE: 'ILIKE'>, 'IN': <TokenType.IN: 'IN'>, 'INDEX': <TokenType.INDEX: 'INDEX'>, 'INET': <TokenType.INET: 'INET'>, 'INNER': <TokenType.INNER: 'INNER'>, 'INSERT': <TokenType.INSERT: 'INSERT'>, 'INTERVAL': <TokenType.INTERVAL: 'INTERVAL'>, 'INTERSECT': <TokenType.INTERSECT: 'INTERSECT'>, 'INTO': <TokenType.INTO: 'INTO'>, 'IS': <TokenType.IS: 'IS'>, 'ISNULL': <TokenType.ISNULL: 'ISNULL'>, 'JOIN': <TokenType.JOIN: 'JOIN'>, 'KEEP': <TokenType.KEEP: 'KEEP'>, 'KILL': <TokenType.KILL: 'KILL'>, 'LATERAL': <TokenType.LATERAL: 'LATERAL'>, 'LEFT': <TokenType.LEFT: 'LEFT'>, 'LIKE': <TokenType.LIKE: 'LIKE'>, 'LIMIT': <TokenType.LIMIT: 'LIMIT'>, 'LOAD': <TokenType.LOAD: 'LOAD'>, 'LOCK': <TokenType.LOCK: 'LOCK'>, 'MERGE': <TokenType.MERGE: 'MERGE'>, 'NAMESPACE': <TokenType.NAMESPACE: 'NAMESPACE'>, 'NATURAL': <TokenType.NATURAL: 'NATURAL'>, 'NEXT': <TokenType.NEXT: 'NEXT'>, 'NOT': <TokenType.NOT: 'NOT'>, 'NOTNULL': <TokenType.NOTNULL: 'NOTNULL'>, 'NULL': <TokenType.NULL: 'NULL'>, 'OBJECT': <TokenType.OBJECT: 'OBJECT'>, 'OFFSET': <TokenType.OFFSET: 'OFFSET'>, 'ON': <TokenType.ON: 'ON'>, 'OR': <TokenType.OR: 'OR'>, 'XOR': <TokenType.XOR: 'XOR'>, 'ORDER BY': <TokenType.ORDER_BY: 'ORDER_BY'>, 'ORDINALITY': <TokenType.ORDINALITY: 'ORDINALITY'>, 'OUTER': <TokenType.OUTER: 'OUTER'>, 'OVER': <TokenType.OVER: 'OVER'>, 'OVERLAPS': <TokenType.OVERLAPS: 'OVERLAPS'>, 'OVERWRITE': <TokenType.OVERWRITE: 'OVERWRITE'>, 'PARTITION': <TokenType.PARTITION: 'PARTITION'>, 'PARTITION BY': <TokenType.PARTITION_BY: 'PARTITION_BY'>, 'PARTITIONED BY': <TokenType.PARTITION_BY: 'PARTITION_BY'>, 'PARTITIONED_BY': <TokenType.PARTITION_BY: 'PARTITION_BY'>, 'PERCENT': <TokenType.PERCENT: 'PERCENT'>, 'PIVOT': <TokenType.PIVOT: 'PIVOT'>, 'PRAGMA': <TokenType.PRAGMA: 'PRAGMA'>, 'PRIMARY KEY': <TokenType.PRIMARY_KEY: 'PRIMARY_KEY'>, 'PROCEDURE': <TokenType.PROCEDURE: 'PROCEDURE'>, 'QUALIFY': <TokenType.QUALIFY: 'QUALIFY'>, 'RANGE': <TokenType.RANGE: 'RANGE'>, 'RECURSIVE': <TokenType.RECURSIVE: 'RECURSIVE'>, 'REGEXP': <TokenType.RLIKE: 'RLIKE'>, 'RENAME': <TokenType.RENAME: 'RENAME'>, 'REPLACE': <TokenType.REPLACE: 'REPLACE'>, 'RETURNING': <TokenType.RETURNING: 'RETURNING'>, 'REFERENCES': <TokenType.REFERENCES: 'REFERENCES'>, 'RIGHT': <TokenType.RIGHT: 'RIGHT'>, 'RLIKE': <TokenType.RLIKE: 'RLIKE'>, 'ROLLBACK': <TokenType.ROLLBACK: 'ROLLBACK'>, 'ROLLUP': <TokenType.ROLLUP: 'ROLLUP'>, 'ROW': <TokenType.ROW: 'ROW'>, 'ROWS': <TokenType.ROWS: 'ROWS'>, 'SCHEMA': <TokenType.SCHEMA: 'SCHEMA'>, 'SELECT': <TokenType.SELECT: 'SELECT'>, 'SEMI': <TokenType.SEMI: 'SEMI'>, 'SET': <TokenType.SET: 'SET'>, 'SETTINGS': <TokenType.SETTINGS: 'SETTINGS'>, 'SHOW': <TokenType.SHOW: 'SHOW'>, 'SIMILAR TO': <TokenType.SIMILAR_TO: 'SIMILAR_TO'>, 'SOME': <TokenType.SOME: 'SOME'>, 'SORT BY': <TokenType.SORT_BY: 'SORT_BY'>, 'START WITH': <TokenType.START_WITH: 'START_WITH'>, 'STRAIGHT_JOIN': <TokenType.STRAIGHT_JOIN: 'STRAIGHT_JOIN'>, 'TABLE': <TokenType.TABLE: 'TABLE'>, 'TABLESAMPLE': <TokenType.TABLE_SAMPLE: 'TABLE_SAMPLE'>, 'TEMP': <TokenType.TEMPORARY: 'TEMPORARY'>, 'TEMPORARY': <TokenType.TEMPORARY: 'TEMPORARY'>, 'THEN': <TokenType.THEN: 'THEN'>, 'TRUE': <TokenType.TRUE: 'TRUE'>, 'TRUNCATE': <TokenType.TRUNCATE: 'TRUNCATE'>, 'UNION': <TokenType.UNION: 'UNION'>, 'UNKNOWN': <TokenType.UNKNOWN: 'UNKNOWN'>, 'UNNEST': <TokenType.UNNEST: 'UNNEST'>, 'UNPIVOT': <TokenType.UNPIVOT: 'UNPIVOT'>, 'UPDATE': <TokenType.UPDATE: 'UPDATE'>, 'USE': <TokenType.USE: 'USE'>, 'USING': <TokenType.USING: 'USING'>, 'UUID': <TokenType.UUID: 'UUID'>, 'VALUES': <TokenType.VALUES: 'VALUES'>, 'VIEW': <TokenType.VIEW: 'VIEW'>, 'VOLATILE': <TokenType.VOLATILE: 'VOLATILE'>, 'WHEN': <TokenType.WHEN: 'WHEN'>, 'WHERE': <TokenType.WHERE: 'WHERE'>, 'WINDOW': <TokenType.WINDOW: 'WINDOW'>, 'WITH': <TokenType.WITH: 'WITH'>, 'APPLY': <TokenType.APPLY: 'APPLY'>, 'ARRAY': <TokenType.ARRAY: 'ARRAY'>, 'BIT': <TokenType.BIT: 'BIT'>, 'BOOL': <TokenType.BOOLEAN: 'BOOLEAN'>, 'BOOLEAN': <TokenType.BOOLEAN: 'BOOLEAN'>, 'BYTE': <TokenType.TINYINT: 'TINYINT'>, 'MEDIUMINT': <TokenType.MEDIUMINT: 'MEDIUMINT'>, 'INT1': <TokenType.TINYINT: 'TINYINT'>, 'TINYINT': <TokenType.TINYINT: 'TINYINT'>, 'INT16': <TokenType.SMALLINT: 'SMALLINT'>, 'SHORT': <TokenType.SMALLINT: 'SMALLINT'>, 'SMALLINT': <TokenType.SMALLINT: 'SMALLINT'>, 'INT128': <TokenType.INT128: 'INT128'>, 'HUGEINT': <TokenType.INT128: 'INT128'>, 'UHUGEINT': <TokenType.UINT128: 'UINT128'>, 'INT2': <TokenType.SMALLINT: 'SMALLINT'>, 'INTEGER': <TokenType.INT: 'INT'>, 'INT': <TokenType.INT: 'INT'>, 'INT4': <TokenType.INT: 'INT'>, 'INT32': <TokenType.INT: 'INT'>, 'INT64': <TokenType.BIGINT: 'BIGINT'>, 'LONG': <TokenType.BIGINT: 'BIGINT'>, 'BIGINT': <TokenType.BIGINT: 'BIGINT'>, 'INT8': <TokenType.TINYINT: 'TINYINT'>, 'UINT': <TokenType.UINT: 'UINT'>, 'DEC': <TokenType.DECIMAL: 'DECIMAL'>, 'DECIMAL': <TokenType.DECIMAL: 'DECIMAL'>, 'DECIMAL32': <TokenType.DECIMAL32: 'DECIMAL32'>, 'DECIMAL64': <TokenType.DECIMAL64: 'DECIMAL64'>, 'DECIMAL128': <TokenType.DECIMAL128: 'DECIMAL128'>, 'DECIMAL256': <TokenType.DECIMAL256: 'DECIMAL256'>, 'BIGDECIMAL': <TokenType.BIGDECIMAL: 'BIGDECIMAL'>, 'BIGNUMERIC': <TokenType.BIGDECIMAL: 'BIGDECIMAL'>, 'LIST': <TokenType.LIST: 'LIST'>, 'MAP': <TokenType.MAP: 'MAP'>, 'NULLABLE': <TokenType.NULLABLE: 'NULLABLE'>, 'NUMBER': <TokenType.DECIMAL: 'DECIMAL'>, 'NUMERIC': <TokenType.DECIMAL: 'DECIMAL'>, 'FIXED': <TokenType.DECIMAL: 'DECIMAL'>, 'REAL': <TokenType.FLOAT: 'FLOAT'>, 'FLOAT': <TokenType.FLOAT: 'FLOAT'>, 'FLOAT4': <TokenType.FLOAT: 'FLOAT'>, 'FLOAT8': <TokenType.DOUBLE: 'DOUBLE'>, 'DOUBLE': <TokenType.DOUBLE: 'DOUBLE'>, 'DOUBLE PRECISION': <TokenType.DOUBLE: 'DOUBLE'>, 'JSON': <TokenType.JSON: 'JSON'>, 'JSONB': <TokenType.JSONB: 'JSONB'>, 'CHAR': <TokenType.CHAR: 'CHAR'>, 'CHARACTER': <TokenType.CHAR: 'CHAR'>, 'NCHAR': <TokenType.NCHAR: 'NCHAR'>, 'VARCHAR': <TokenType.VARCHAR: 'VARCHAR'>, 'VARCHAR2': <TokenType.VARCHAR: 'VARCHAR'>, 'NVARCHAR': <TokenType.NVARCHAR: 'NVARCHAR'>, 'NVARCHAR2': <TokenType.NVARCHAR: 'NVARCHAR'>, 'BPCHAR': <TokenType.BPCHAR: 'BPCHAR'>, 'STR': <TokenType.TEXT: 'TEXT'>, 'STRING': <TokenType.TEXT: 'TEXT'>, 'TEXT': <TokenType.TEXT: 'TEXT'>, 'LONGTEXT': <TokenType.LONGTEXT: 'LONGTEXT'>, 'MEDIUMTEXT': <TokenType.MEDIUMTEXT: 'MEDIUMTEXT'>, 'TINYTEXT': <TokenType.TINYTEXT: 'TINYTEXT'>, 'CLOB': <TokenType.TEXT: 'TEXT'>, 'LONGVARCHAR': <TokenType.TEXT: 'TEXT'>, 'BINARY': <TokenType.BINARY: 'BINARY'>, 'BLOB': <TokenType.VARBINARY: 'VARBINARY'>, 'LONGBLOB': <TokenType.LONGBLOB: 'LONGBLOB'>, 'MEDIUMBLOB': <TokenType.MEDIUMBLOB: 'MEDIUMBLOB'>, 'TINYBLOB': <TokenType.TINYBLOB: 'TINYBLOB'>, 'BYTEA': <TokenType.VARBINARY: 'VARBINARY'>, 'VARBINARY': <TokenType.VARBINARY: 'VARBINARY'>, 'TIME': <TokenType.TIME: 'TIME'>, 'TIMETZ': <TokenType.TIMETZ: 'TIMETZ'>, 'TIMESTAMP': <TokenType.TIMESTAMP: 'TIMESTAMP'>, 'TIMESTAMPTZ': <TokenType.TIMESTAMPTZ: 'TIMESTAMPTZ'>, 'TIMESTAMPLTZ': <TokenType.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, 'TIMESTAMP_LTZ': <TokenType.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, 'TIMESTAMPNTZ': <TokenType.TIMESTAMPNTZ: 'TIMESTAMPNTZ'>, 'TIMESTAMP_NTZ': <TokenType.TIMESTAMPNTZ: 'TIMESTAMPNTZ'>, 'DATE': <TokenType.DATE: 'DATE'>, 'DATETIME': <TokenType.DATETIME: 'DATETIME'>, 'INT4RANGE': <TokenType.INT4RANGE: 'INT4RANGE'>, 'INT4MULTIRANGE': <TokenType.INT4MULTIRANGE: 'INT4MULTIRANGE'>, 'INT8RANGE': <TokenType.INT8RANGE: 'INT8RANGE'>, 'INT8MULTIRANGE': <TokenType.INT8MULTIRANGE: 'INT8MULTIRANGE'>, 'NUMRANGE': <TokenType.NUMRANGE: 'NUMRANGE'>, 'NUMMULTIRANGE': <TokenType.NUMMULTIRANGE: 'NUMMULTIRANGE'>, 'TSRANGE': <TokenType.TSRANGE: 'TSRANGE'>, 'TSMULTIRANGE': <TokenType.TSMULTIRANGE: 'TSMULTIRANGE'>, 'TSTZRANGE': <TokenType.TSTZRANGE: 'TSTZRANGE'>, 'TSTZMULTIRANGE': <TokenType.TSTZMULTIRANGE: 'TSTZMULTIRANGE'>, 'DATERANGE': <TokenType.DATERANGE: 'DATERANGE'>, 'DATEMULTIRANGE': <TokenType.DATEMULTIRANGE: 'DATEMULTIRANGE'>, 'UNIQUE': <TokenType.UNIQUE: 'UNIQUE'>, 'VECTOR': <TokenType.VECTOR: 'VECTOR'>, 'STRUCT': <TokenType.STRUCT: 'STRUCT'>, 'SEQUENCE': <TokenType.SEQUENCE: 'SEQUENCE'>, 'VARIANT': <TokenType.VARIANT: 'VARIANT'>, 'ALTER': <TokenType.ALTER: 'ALTER'>, 'ANALYZE': <TokenType.ANALYZE: 'ANALYZE'>, 'CALL': <TokenType.COMMAND: 'COMMAND'>, 'COMMENT': <TokenType.COMMENT: 'COMMENT'>, 'EXPLAIN': <TokenType.DESCRIBE: 'DESCRIBE'>, 'GRANT': <TokenType.GRANT: 'GRANT'>, 'OPTIMIZE': <TokenType.COMMAND: 'COMMAND'>, 'PREPARE': <TokenType.COMMAND: 'COMMAND'>, 'VACUUM': <TokenType.COMMAND: 'COMMAND'>, 'USER-DEFINED': <TokenType.USERDEFINED: 'USERDEFINED'>, 'FOR VERSION': <TokenType.VERSION_SNAPSHOT: 'VERSION_SNAPSHOT'>, 'FOR TIMESTAMP': <TokenType.TIMESTAMP_SNAPSHOT: 'TIMESTAMP_SNAPSHOT'>, 'CHARSET': <TokenType.CHARACTER_SET: 'CHARACTER_SET'>, 'FORCE': <TokenType.FORCE: 'FORCE'>, 'IGNORE': <TokenType.IGNORE: 'IGNORE'>, 'KEY': <TokenType.KEY: 'KEY'>, 'LOCK TABLES': <TokenType.COMMAND: 'COMMAND'>, 'MEMBER OF': <TokenType.MEMBER_OF: 'MEMBER_OF'>, 'SEPARATOR': <TokenType.SEPARATOR: 'SEPARATOR'>, 'SERIAL': <TokenType.SERIAL: 'SERIAL'>, 'START': <TokenType.BEGIN: 'BEGIN'>, 'SIGNED': <TokenType.BIGINT: 'BIGINT'>, 'SIGNED INTEGER': <TokenType.BIGINT: 'BIGINT'>, 'UNLOCK TABLES': <TokenType.COMMAND: 'COMMAND'>, 'UNSIGNED': <TokenType.UBIGINT: 'UBIGINT'>, 'UNSIGNED INTEGER': <TokenType.UBIGINT: 'UBIGINT'>, 'YEAR': <TokenType.YEAR: 'YEAR'>, '_ARMSCII8': <TokenType.INTRODUCER: 'INTRODUCER'>, '_ASCII': <TokenType.INTRODUCER: 'INTRODUCER'>, '_BIG5': <TokenType.INTRODUCER: 'INTRODUCER'>, '_BINARY': <TokenType.INTRODUCER: 'INTRODUCER'>, '_CP1250': <TokenType.INTRODUCER: 'INTRODUCER'>, '_CP1251': <TokenType.INTRODUCER: 'INTRODUCER'>, '_CP1256': <TokenType.INTRODUCER: 'INTRODUCER'>, '_CP1257': <TokenType.INTRODUCER: 'INTRODUCER'>, '_CP850': <TokenType.INTRODUCER: 'INTRODUCER'>, '_CP852': <TokenType.INTRODUCER: 'INTRODUCER'>, '_CP866': <TokenType.INTRODUCER: 'INTRODUCER'>, '_CP932': <TokenType.INTRODUCER: 'INTRODUCER'>, '_DEC8': <TokenType.INTRODUCER: 'INTRODUCER'>, '_EUCJPMS': <TokenType.INTRODUCER: 'INTRODUCER'>, '_EUCKR': <TokenType.INTRODUCER: 'INTRODUCER'>, '_GB18030': <TokenType.INTRODUCER: 'INTRODUCER'>, '_GB2312': <TokenType.INTRODUCER: 'INTRODUCER'>, '_GBK': <TokenType.INTRODUCER: 'INTRODUCER'>, '_GEOSTD8': <TokenType.INTRODUCER: 'INTRODUCER'>, '_GREEK': <TokenType.INTRODUCER: 'INTRODUCER'>, '_HEBREW': <TokenType.INTRODUCER: 'INTRODUCER'>, '_HP8': <TokenType.INTRODUCER: 'INTRODUCER'>, '_KEYBCS2': <TokenType.INTRODUCER: 'INTRODUCER'>, '_KOI8R': <TokenType.INTRODUCER: 'INTRODUCER'>, '_KOI8U': <TokenType.INTRODUCER: 'INTRODUCER'>, '_LATIN1': <TokenType.INTRODUCER: 'INTRODUCER'>, '_LATIN2': <TokenType.INTRODUCER: 'INTRODUCER'>, '_LATIN5': <TokenType.INTRODUCER: 'INTRODUCER'>, '_LATIN7': <TokenType.INTRODUCER: 'INTRODUCER'>, '_MACCE': <TokenType.INTRODUCER: 'INTRODUCER'>, '_MACROMAN': <TokenType.INTRODUCER: 'INTRODUCER'>, '_SJIS': <TokenType.INTRODUCER: 'INTRODUCER'>, '_SWE7': <TokenType.INTRODUCER: 'INTRODUCER'>, '_TIS620': <TokenType.INTRODUCER: 'INTRODUCER'>, '_UCS2': <TokenType.INTRODUCER: 'INTRODUCER'>, '_UJIS': <TokenType.INTRODUCER: 'INTRODUCER'>, '_UTF8': <TokenType.INTRODUCER: 'INTRODUCER'>, '_UTF16': <TokenType.INTRODUCER: 'INTRODUCER'>, '_UTF16LE': <TokenType.INTRODUCER: 'INTRODUCER'>, '_UTF32': <TokenType.INTRODUCER: 'INTRODUCER'>, '_UTF8MB3': <TokenType.INTRODUCER: 'INTRODUCER'>, '_UTF8MB4': <TokenType.INTRODUCER: 'INTRODUCER'>, '@@': <TokenType.SESSION_PARAMETER: 'SESSION_PARAMETER'>}
COMMANDS =
{<TokenType.COMMAND: 'COMMAND'>, <TokenType.EXECUTE: 'EXECUTE'>, <TokenType.REPLACE: 'REPLACE'>, <TokenType.FETCH: 'FETCH'>, <TokenType.RENAME: 'RENAME'>}
Inherited Members
- sqlglot.tokens.Tokenizer
- Tokenizer
- SINGLE_TOKENS
- BYTE_STRINGS
- RAW_STRINGS
- HEREDOC_STRINGS
- UNICODE_STRINGS
- VAR_SINGLE_TOKENS
- IDENTIFIER_ESCAPES
- HEREDOC_TAG_IS_IDENTIFIER
- HEREDOC_STRING_ALTERNATIVE
- STRING_ESCAPES_ALLOWED_IN_RAW_STRINGS
- NESTED_COMMENTS
- HINT_START
- TOKENS_PRECEDING_HINT
- WHITE_SPACE
- COMMAND_PREFIX_TOKENS
- NUMERIC_LITERALS
- dialect
- use_rs_tokenizer
- reset
- tokenize
- tokenize_rs
- size
- sql
- tokens
266 class Parser(parser.Parser): 267 FUNC_TOKENS = { 268 *parser.Parser.FUNC_TOKENS, 269 TokenType.DATABASE, 270 TokenType.SCHEMA, 271 TokenType.VALUES, 272 } 273 274 CONJUNCTION = { 275 **parser.Parser.CONJUNCTION, 276 TokenType.DAMP: exp.And, 277 TokenType.XOR: exp.Xor, 278 } 279 280 DISJUNCTION = { 281 **parser.Parser.DISJUNCTION, 282 TokenType.DPIPE: exp.Or, 283 } 284 285 TABLE_ALIAS_TOKENS = ( 286 parser.Parser.TABLE_ALIAS_TOKENS - parser.Parser.TABLE_INDEX_HINT_TOKENS 287 ) 288 289 RANGE_PARSERS = { 290 **parser.Parser.RANGE_PARSERS, 291 TokenType.MEMBER_OF: lambda self, this: self.expression( 292 exp.JSONArrayContains, 293 this=this, 294 expression=self._parse_wrapped(self._parse_expression), 295 ), 296 } 297 298 FUNCTIONS = { 299 **parser.Parser.FUNCTIONS, 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 "LENGTH": lambda args: exp.Length(this=seq_get(args, 0), binary=True), 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.TSTZRANGE: 'TSTZRANGE'>, <TokenType.INDEX: 'INDEX'>, <TokenType.RLIKE: 'RLIKE'>, <TokenType.CURRENT_USER: 'CURRENT_USER'>, <TokenType.MONEY: 'MONEY'>, <TokenType.NULLABLE: 'NULLABLE'>, <TokenType.DATETIME2: 'DATETIME2'>, <TokenType.SIMPLEAGGREGATEFUNCTION: 'SIMPLEAGGREGATEFUNCTION'>, <TokenType.DATEMULTIRANGE: 'DATEMULTIRANGE'>, <TokenType.TSMULTIRANGE: 'TSMULTIRANGE'>, <TokenType.INT128: 'INT128'>, <TokenType.MULTIPOLYGON: 'MULTIPOLYGON'>, <TokenType.INT8MULTIRANGE: 'INT8MULTIRANGE'>, <TokenType.UNION: 'UNION'>, <TokenType.FORMAT: 'FORMAT'>, <TokenType.UDECIMAL: 'UDECIMAL'>, <TokenType.CURRENT_TIME: 'CURRENT_TIME'>, <TokenType.LOWCARDINALITY: 'LOWCARDINALITY'>, <TokenType.UBIGINT: 'UBIGINT'>, <TokenType.XOR: 'XOR'>, <TokenType.AGGREGATEFUNCTION: 'AGGREGATEFUNCTION'>, <TokenType.BOOLEAN: 'BOOLEAN'>, <TokenType.MEDIUMTEXT: 'MEDIUMTEXT'>, <TokenType.ROWVERSION: 'ROWVERSION'>, <TokenType.INT: 'INT'>, <TokenType.DATABASE: 'DATABASE'>, <TokenType.PRIMARY_KEY: 'PRIMARY_KEY'>, <TokenType.DATERANGE: 'DATERANGE'>, <TokenType.LIST: 'LIST'>, <TokenType.SMALLMONEY: 'SMALLMONEY'>, <TokenType.STRUCT: 'STRUCT'>, <TokenType.TINYINT: 'TINYINT'>, <TokenType.DECIMAL64: 'DECIMAL64'>, <TokenType.SMALLSERIAL: 'SMALLSERIAL'>, <TokenType.VECTOR: 'VECTOR'>, <TokenType.INSERT: 'INSERT'>, <TokenType.OBJECT: 'OBJECT'>, <TokenType.TSRANGE: 'TSRANGE'>, <TokenType.UUID: 'UUID'>, <TokenType.NULL: 'NULL'>, <TokenType.USMALLINT: 'USMALLINT'>, <TokenType.DECIMAL: 'DECIMAL'>, <TokenType.UNIQUEIDENTIFIER: 'UNIQUEIDENTIFIER'>, <TokenType.LONGTEXT: 'LONGTEXT'>, <TokenType.NUMRANGE: 'NUMRANGE'>, <TokenType.NESTED: 'NESTED'>, <TokenType.TRUNCATE: 'TRUNCATE'>, <TokenType.UMEDIUMINT: 'UMEDIUMINT'>, <TokenType.SMALLDATETIME: 'SMALLDATETIME'>, <TokenType.EXISTS: 'EXISTS'>, <TokenType.FILTER: 'FILTER'>, <TokenType.DECIMAL256: 'DECIMAL256'>, <TokenType.TEXT: 'TEXT'>, <TokenType.COLLATE: 'COLLATE'>, <TokenType.NUMMULTIRANGE: 'NUMMULTIRANGE'>, <TokenType.UINT256: 'UINT256'>, <TokenType.BPCHAR: 'BPCHAR'>, <TokenType.INTERVAL: 'INTERVAL'>, <TokenType.NAME: 'NAME'>, <TokenType.IPV4: 'IPV4'>, <TokenType.SMALLINT: 'SMALLINT'>, <TokenType.CURRENT_TIMESTAMP: 'CURRENT_TIMESTAMP'>, <TokenType.YEAR: 'YEAR'>, <TokenType.SEQUENCE: 'SEQUENCE'>, <TokenType.OBJECT_IDENTIFIER: 'OBJECT_IDENTIFIER'>, <TokenType.MERGE: 'MERGE'>, <TokenType.RIGHT: 'RIGHT'>, <TokenType.IPV6: 'IPV6'>, <TokenType.VARBINARY: 'VARBINARY'>, <TokenType.DATE32: 'DATE32'>, <TokenType.TIMESTAMPTZ: 'TIMESTAMPTZ'>, <TokenType.TIMESTAMPNTZ: 'TIMESTAMPNTZ'>, <TokenType.OFFSET: 'OFFSET'>, <TokenType.TIMESTAMP_S: 'TIMESTAMP_S'>, <TokenType.ALL: 'ALL'>, <TokenType.VARIANT: 'VARIANT'>, <TokenType.HSTORE: 'HSTORE'>, <TokenType.TINYBLOB: 'TINYBLOB'>, <TokenType.LIKE: 'LIKE'>, <TokenType.INT256: 'INT256'>, <TokenType.BIT: 'BIT'>, <TokenType.BINARY: 'BINARY'>, <TokenType.DECIMAL32: 'DECIMAL32'>, <TokenType.REPLACE: 'REPLACE'>, <TokenType.CURRENT_DATE: 'CURRENT_DATE'>, <TokenType.GEOMETRY: 'GEOMETRY'>, <TokenType.FIRST: 'FIRST'>, <TokenType.DATE: 'DATE'>, <TokenType.USERDEFINED: 'USERDEFINED'>, <TokenType.TIME: 'TIME'>, <TokenType.RING: 'RING'>, <TokenType.SERIAL: 'SERIAL'>, <TokenType.LINESTRING: 'LINESTRING'>, <TokenType.ROW: 'ROW'>, <TokenType.ARRAY: 'ARRAY'>, <TokenType.POLYGON: 'POLYGON'>, <TokenType.ISNULL: 'ISNULL'>, <TokenType.MEDIUMBLOB: 'MEDIUMBLOB'>, <TokenType.INT4MULTIRANGE: 'INT4MULTIRANGE'>, <TokenType.BIGINT: 'BIGINT'>, <TokenType.NVARCHAR: 'NVARCHAR'>, <TokenType.LEFT: 'LEFT'>, <TokenType.ILIKE: 'ILIKE'>, <TokenType.TABLE: 'TABLE'>, <TokenType.MEDIUMINT: 'MEDIUMINT'>, <TokenType.JSONB: 'JSONB'>, <TokenType.ANY: 'ANY'>, <TokenType.HLLSKETCH: 'HLLSKETCH'>, <TokenType.GLOB: 'GLOB'>, <TokenType.UNKNOWN: 'UNKNOWN'>, <TokenType.TIMESTAMP_NS: 'TIMESTAMP_NS'>, <TokenType.LONGBLOB: 'LONGBLOB'>, <TokenType.XML: 'XML'>, <TokenType.IPADDRESS: 'IPADDRESS'>, <TokenType.IPPREFIX: 'IPPREFIX'>, <TokenType.ENUM16: 'ENUM16'>, <TokenType.INT4RANGE: 'INT4RANGE'>, <TokenType.VALUES: 'VALUES'>, <TokenType.SOME: 'SOME'>, <TokenType.DATETIME64: 'DATETIME64'>, <TokenType.COMMAND: 'COMMAND'>, <TokenType.INET: 'INET'>, <TokenType.SCHEMA: 'SCHEMA'>, <TokenType.INT8RANGE: 'INT8RANGE'>, <TokenType.IMAGE: 'IMAGE'>, <TokenType.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, <TokenType.IDENTIFIER: 'IDENTIFIER'>, <TokenType.UTINYINT: 'UTINYINT'>, <TokenType.ENUM8: 'ENUM8'>, <TokenType.VAR: 'VAR'>, <TokenType.TIMESTAMP_MS: 'TIMESTAMP_MS'>, <TokenType.GEOGRAPHY: 'GEOGRAPHY'>, <TokenType.BIGDECIMAL: 'BIGDECIMAL'>, <TokenType.NEXT: 'NEXT'>, <TokenType.MULTILINESTRING: 'MULTILINESTRING'>, <TokenType.VARCHAR: 'VARCHAR'>, <TokenType.TINYTEXT: 'TINYTEXT'>, <TokenType.JSON: 'JSON'>, <TokenType.CURRENT_DATETIME: 'CURRENT_DATETIME'>, <TokenType.PSEUDO_TYPE: 'PSEUDO_TYPE'>, <TokenType.DOUBLE: 'DOUBLE'>, <TokenType.TIMETZ: 'TIMETZ'>, <TokenType.TDIGEST: 'TDIGEST'>, <TokenType.WINDOW: 'WINDOW'>, <TokenType.POINT: 'POINT'>, <TokenType.MAP: 'MAP'>, <TokenType.ENUM: 'ENUM'>, <TokenType.RANGE: 'RANGE'>, <TokenType.DECIMAL128: 'DECIMAL128'>, <TokenType.FIXEDSTRING: 'FIXEDSTRING'>, <TokenType.TIMESTAMP: 'TIMESTAMP'>, <TokenType.TSTZMULTIRANGE: 'TSTZMULTIRANGE'>, <TokenType.CHAR: 'CHAR'>, <TokenType.UINT128: 'UINT128'>, <TokenType.DATETIME: 'DATETIME'>, <TokenType.NCHAR: 'NCHAR'>, <TokenType.UNNEST: 'UNNEST'>, <TokenType.UINT: 'UINT'>, <TokenType.SUPER: 'SUPER'>, <TokenType.BIGSERIAL: 'BIGSERIAL'>, <TokenType.FLOAT: 'FLOAT'>}
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.TSTZRANGE: 'TSTZRANGE'>, <TokenType.SETTINGS: 'SETTINGS'>, <TokenType.INDEX: 'INDEX'>, <TokenType.MONEY: 'MONEY'>, <TokenType.CURRENT_USER: 'CURRENT_USER'>, <TokenType.NULLABLE: 'NULLABLE'>, <TokenType.DATETIME2: 'DATETIME2'>, <TokenType.SIMPLEAGGREGATEFUNCTION: 'SIMPLEAGGREGATEFUNCTION'>, <TokenType.FOREIGN_KEY: 'FOREIGN_KEY'>, <TokenType.DATEMULTIRANGE: 'DATEMULTIRANGE'>, <TokenType.TSMULTIRANGE: 'TSMULTIRANGE'>, <TokenType.INT128: 'INT128'>, <TokenType.MULTIPOLYGON: 'MULTIPOLYGON'>, <TokenType.INT8MULTIRANGE: 'INT8MULTIRANGE'>, <TokenType.FORMAT: 'FORMAT'>, <TokenType.UDECIMAL: 'UDECIMAL'>, <TokenType.LOWCARDINALITY: 'LOWCARDINALITY'>, <TokenType.CURRENT_TIME: 'CURRENT_TIME'>, <TokenType.UBIGINT: 'UBIGINT'>, <TokenType.AGGREGATEFUNCTION: 'AGGREGATEFUNCTION'>, <TokenType.PIVOT: 'PIVOT'>, <TokenType.BOOLEAN: 'BOOLEAN'>, <TokenType.MEDIUMTEXT: 'MEDIUMTEXT'>, <TokenType.ROWVERSION: 'ROWVERSION'>, <TokenType.TOP: 'TOP'>, <TokenType.OVERLAPS: 'OVERLAPS'>, <TokenType.INT: 'INT'>, <TokenType.DATABASE: 'DATABASE'>, <TokenType.BEGIN: 'BEGIN'>, <TokenType.RECURSIVE: 'RECURSIVE'>, <TokenType.SET: 'SET'>, <TokenType.SHOW: 'SHOW'>, <TokenType.COLUMN: 'COLUMN'>, <TokenType.DATERANGE: 'DATERANGE'>, <TokenType.LIST: 'LIST'>, <TokenType.SMALLMONEY: 'SMALLMONEY'>, <TokenType.STRUCT: 'STRUCT'>, <TokenType.TINYINT: 'TINYINT'>, <TokenType.DECIMAL64: 'DECIMAL64'>, <TokenType.UNPIVOT: 'UNPIVOT'>, <TokenType.SMALLSERIAL: 'SMALLSERIAL'>, <TokenType.TEMPORARY: 'TEMPORARY'>, <TokenType.VECTOR: 'VECTOR'>, <TokenType.SINK: 'SINK'>, <TokenType.OBJECT: 'OBJECT'>, <TokenType.MODEL: 'MODEL'>, <TokenType.COMMIT: 'COMMIT'>, <TokenType.TSRANGE: 'TSRANGE'>, <TokenType.UUID: 'UUID'>, <TokenType.NULL: 'NULL'>, <TokenType.REFERENCES: 'REFERENCES'>, <TokenType.USMALLINT: 'USMALLINT'>, <TokenType.COMMENT: 'COMMENT'>, <TokenType.DECIMAL: 'DECIMAL'>, <TokenType.UNIQUEIDENTIFIER: 'UNIQUEIDENTIFIER'>, <TokenType.LONGTEXT: 'LONGTEXT'>, <TokenType.NUMRANGE: 'NUMRANGE'>, <TokenType.NESTED: 'NESTED'>, <TokenType.SEMI: 'SEMI'>, <TokenType.TRUNCATE: 'TRUNCATE'>, <TokenType.DEFAULT: 'DEFAULT'>, <TokenType.UMEDIUMINT: 'UMEDIUMINT'>, <TokenType.EXISTS: 'EXISTS'>, <TokenType.SMALLDATETIME: 'SMALLDATETIME'>, <TokenType.LOAD: 'LOAD'>, <TokenType.FILTER: 'FILTER'>, <TokenType.OPERATOR: 'OPERATOR'>, <TokenType.DECIMAL256: 'DECIMAL256'>, <TokenType.AUTO_INCREMENT: 'AUTO_INCREMENT'>, <TokenType.RENAME: 'RENAME'>, <TokenType.TEXT: 'TEXT'>, <TokenType.CUBE: 'CUBE'>, <TokenType.COLLATE: 'COLLATE'>, <TokenType.BPCHAR: 'BPCHAR'>, <TokenType.NUMMULTIRANGE: 'NUMMULTIRANGE'>, <TokenType.UINT256: 'UINT256'>, <TokenType.ANTI: 'ANTI'>, <TokenType.INTERVAL: 'INTERVAL'>, <TokenType.UPDATE: 'UPDATE'>, <TokenType.KILL: 'KILL'>, <TokenType.NAME: 'NAME'>, <TokenType.DESC: 'DESC'>, <TokenType.IPV4: 'IPV4'>, <TokenType.SMALLINT: 'SMALLINT'>, <TokenType.VOLATILE: 'VOLATILE'>, <TokenType.PARTITION: 'PARTITION'>, <TokenType.TRUE: 'TRUE'>, <TokenType.YEAR: 'YEAR'>, <TokenType.SEQUENCE: 'SEQUENCE'>, <TokenType.OBJECT_IDENTIFIER: 'OBJECT_IDENTIFIER'>, <TokenType.MERGE: 'MERGE'>, <TokenType.IPV6: 'IPV6'>, <TokenType.CURRENT_TIMESTAMP: 'CURRENT_TIMESTAMP'>, <TokenType.VARBINARY: 'VARBINARY'>, <TokenType.DATE32: 'DATE32'>, <TokenType.TIMESTAMPTZ: 'TIMESTAMPTZ'>, <TokenType.TIMESTAMPNTZ: 'TIMESTAMPNTZ'>, <TokenType.OFFSET: 'OFFSET'>, <TokenType.TIMESTAMP_S: 'TIMESTAMP_S'>, <TokenType.ALL: 'ALL'>, <TokenType.VARIANT: 'VARIANT'>, <TokenType.EXECUTE: 'EXECUTE'>, <TokenType.HSTORE: 'HSTORE'>, <TokenType.TINYBLOB: 'TINYBLOB'>, <TokenType.INT256: 'INT256'>, <TokenType.BIT: 'BIT'>, <TokenType.BINARY: 'BINARY'>, <TokenType.DECIMAL32: 'DECIMAL32'>, <TokenType.REPLACE: 'REPLACE'>, <TokenType.PERCENT: 'PERCENT'>, <TokenType.GEOMETRY: 'GEOMETRY'>, <TokenType.CURRENT_DATE: 'CURRENT_DATE'>, <TokenType.FIRST: 'FIRST'>, <TokenType.DATE: 'DATE'>, <TokenType.USERDEFINED: 'USERDEFINED'>, <TokenType.REFRESH: 'REFRESH'>, <TokenType.TIME: 'TIME'>, <TokenType.PRAGMA: 'PRAGMA'>, <TokenType.RING: 'RING'>, <TokenType.ESCAPE: 'ESCAPE'>, <TokenType.SERIAL: 'SERIAL'>, <TokenType.LINESTRING: 'LINESTRING'>, <TokenType.ROW: 'ROW'>, <TokenType.ARRAY: 'ARRAY'>, <TokenType.POLYGON: 'POLYGON'>, <TokenType.ISNULL: 'ISNULL'>, <TokenType.MEDIUMBLOB: 'MEDIUMBLOB'>, <TokenType.INT4MULTIRANGE: 'INT4MULTIRANGE'>, <TokenType.BIGINT: 'BIGINT'>, <TokenType.DELETE: 'DELETE'>, <TokenType.NVARCHAR: 'NVARCHAR'>, <TokenType.ROWS: 'ROWS'>, <TokenType.TABLE: 'TABLE'>, <TokenType.MEDIUMINT: 'MEDIUMINT'>, <TokenType.JSONB: 'JSONB'>, <TokenType.ANY: 'ANY'>, <TokenType.HLLSKETCH: 'HLLSKETCH'>, <TokenType.END: 'END'>, <TokenType.UNKNOWN: 'UNKNOWN'>, <TokenType.CONSTRAINT: 'CONSTRAINT'>, <TokenType.TIMESTAMP_NS: 'TIMESTAMP_NS'>, <TokenType.LONGBLOB: 'LONGBLOB'>, <TokenType.XML: 'XML'>, <TokenType.IPADDRESS: 'IPADDRESS'>, <TokenType.SOURCE: 'SOURCE'>, <TokenType.IPPREFIX: 'IPPREFIX'>, <TokenType.ENUM16: 'ENUM16'>, <TokenType.ATTACH: 'ATTACH'>, <TokenType.INT4RANGE: 'INT4RANGE'>, <TokenType.ROLLUP: 'ROLLUP'>, <TokenType.DETACH: 'DETACH'>, <TokenType.SOME: 'SOME'>, <TokenType.DATETIME64: 'DATETIME64'>, <TokenType.COMMAND: 'COMMAND'>, <TokenType.SCHEMA: 'SCHEMA'>, <TokenType.INET: 'INET'>, <TokenType.INT8RANGE: 'INT8RANGE'>, <TokenType.IMAGE: 'IMAGE'>, <TokenType.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, <TokenType.FALSE: 'FALSE'>, <TokenType.FUNCTION: 'FUNCTION'>, <TokenType.IDENTIFIER: 'IDENTIFIER'>, <TokenType.ORDINALITY: 'ORDINALITY'>, <TokenType.UTINYINT: 'UTINYINT'>, <TokenType.OVERWRITE: 'OVERWRITE'>, <TokenType.DIV: 'DIV'>, <TokenType.ENUM8: 'ENUM8'>, <TokenType.VAR: 'VAR'>, <TokenType.CASE: 'CASE'>, <TokenType.COPY: 'COPY'>, <TokenType.DESCRIBE: 'DESCRIBE'>, <TokenType.STORAGE_INTEGRATION: 'STORAGE_INTEGRATION'>, <TokenType.TIMESTAMP_MS: 'TIMESTAMP_MS'>, <TokenType.PROCEDURE: 'PROCEDURE'>, <TokenType.GEOGRAPHY: 'GEOGRAPHY'>, <TokenType.BIGDECIMAL: 'BIGDECIMAL'>, <TokenType.NEXT: 'NEXT'>, <TokenType.MULTILINESTRING: 'MULTILINESTRING'>, <TokenType.VARCHAR: 'VARCHAR'>, <TokenType.TINYTEXT: 'TINYTEXT'>, <TokenType.JSON: 'JSON'>, <TokenType.CURRENT_DATETIME: 'CURRENT_DATETIME'>, <TokenType.PSEUDO_TYPE: 'PSEUDO_TYPE'>, <TokenType.DOUBLE: 'DOUBLE'>, <TokenType.LIMIT: 'LIMIT'>, <TokenType.TAG: 'TAG'>, <TokenType.TIMETZ: 'TIMETZ'>, <TokenType.TDIGEST: 'TDIGEST'>, <TokenType.DICTIONARY: 'DICTIONARY'>, <TokenType.POINT: 'POINT'>, <TokenType.KEEP: 'KEEP'>, <TokenType.MAP: 'MAP'>, <TokenType.FINAL: 'FINAL'>, <TokenType.WAREHOUSE: 'WAREHOUSE'>, <TokenType.RANGE: 'RANGE'>, <TokenType.VIEW: 'VIEW'>, <TokenType.ENUM: 'ENUM'>, <TokenType.DECIMAL128: 'DECIMAL128'>, <TokenType.FIXEDSTRING: 'FIXEDSTRING'>, <TokenType.TIMESTAMP: 'TIMESTAMP'>, <TokenType.TSTZMULTIRANGE: 'TSTZMULTIRANGE'>, <TokenType.NAMESPACE: 'NAMESPACE'>, <TokenType.CHAR: 'CHAR'>, <TokenType.UINT128: 'UINT128'>, <TokenType.NCHAR: 'NCHAR'>, <TokenType.CACHE: 'CACHE'>, <TokenType.DATETIME: 'DATETIME'>, <TokenType.UNIQUE: 'UNIQUE'>, <TokenType.UNNEST: 'UNNEST'>, <TokenType.IS: 'IS'>, <TokenType.UINT: 'UINT'>, <TokenType.SUPER: 'SUPER'>, <TokenType.BIGSERIAL: 'BIGSERIAL'>, <TokenType.STREAMLIT: 'STREAMLIT'>, <TokenType.ASC: 'ASC'>, <TokenType.FLOAT: 'FLOAT'>}
RANGE_PARSERS =
{<TokenType.AT_GT: 'AT_GT'>: <function binary_range_parser.<locals>._parse_binary_range>, <TokenType.BETWEEN: 'BETWEEN'>: <function Parser.<lambda>>, <TokenType.GLOB: 'GLOB'>: <function binary_range_parser.<locals>._parse_binary_range>, <TokenType.ILIKE: 'ILIKE'>: <function binary_range_parser.<locals>._parse_binary_range>, <TokenType.IN: 'IN'>: <function Parser.<lambda>>, <TokenType.IRLIKE: 'IRLIKE'>: <function binary_range_parser.<locals>._parse_binary_range>, <TokenType.IS: 'IS'>: <function Parser.<lambda>>, <TokenType.LIKE: 'LIKE'>: <function binary_range_parser.<locals>._parse_binary_range>, <TokenType.LT_AT: 'LT_AT'>: <function binary_range_parser.<locals>._parse_binary_range>, <TokenType.OVERLAPS: 'OVERLAPS'>: <function binary_range_parser.<locals>._parse_binary_range>, <TokenType.RLIKE: 'RLIKE'>: <function binary_range_parser.<locals>._parse_binary_range>, <TokenType.SIMILAR_TO: 'SIMILAR_TO'>: <function binary_range_parser.<locals>._parse_binary_range>, <TokenType.FOR: 'FOR'>: <function Parser.<lambda>>, <TokenType.MEMBER_OF: 'MEMBER_OF'>: <function MySQL.Parser.<lambda>>}
FUNCTIONS =
{'ABS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Abs'>>, 'ADD_MONTHS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.AddMonths'>>, 'ANONYMOUS_AGG_FUNC': <bound method Func.from_arg_list of <class 'sqlglot.expressions.AnonymousAggFunc'>>, 'ANY_VALUE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.AnyValue'>>, 'APPLY': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Apply'>>, 'APPROX_DISTINCT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ApproxDistinct'>>, 'APPROX_COUNT_DISTINCT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ApproxDistinct'>>, 'APPROX_QUANTILE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ApproxQuantile'>>, 'APPROX_TOP_K': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ApproxTopK'>>, 'ARG_MAX': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArgMax'>>, 'ARGMAX': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArgMax'>>, 'MAX_BY': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArgMax'>>, 'ARG_MIN': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArgMin'>>, 'ARGMIN': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArgMin'>>, 'MIN_BY': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArgMin'>>, 'ARRAY': <function Parser.<lambda>>, 'ARRAY_AGG': <function Parser.<lambda>>, 'ARRAY_ALL': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArrayAll'>>, 'ARRAY_ANY': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArrayAny'>>, 'ARRAY_CONCAT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArrayConcat'>>, 'ARRAY_CAT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArrayConcat'>>, 'ARRAY_CONSTRUCT_COMPACT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArrayConstructCompact'>>, 'ARRAY_CONTAINS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArrayContains'>>, 'ARRAY_HAS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArrayContains'>>, 'ARRAY_CONTAINS_ALL': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArrayContainsAll'>>, 'ARRAY_HAS_ALL': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArrayContainsAll'>>, 'FILTER': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArrayFilter'>>, 'ARRAY_FILTER': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArrayFilter'>>, 'ARRAY_OVERLAPS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArrayOverlaps'>>, 'ARRAY_SIZE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArraySize'>>, 'ARRAY_LENGTH': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArraySize'>>, 'ARRAY_SORT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArraySort'>>, 'ARRAY_SUM': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArraySum'>>, 'ARRAY_TO_STRING': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArrayToString'>>, 'ARRAY_JOIN': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArrayToString'>>, 'ARRAY_UNION_AGG': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArrayUnionAgg'>>, 'ARRAY_UNIQUE_AGG': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArrayUniqueAgg'>>, 'AVG': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Avg'>>, 'CASE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Case'>>, 'CAST': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Cast'>>, 'CAST_TO_STR_TYPE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CastToStrType'>>, 'CBRT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Cbrt'>>, 'CEIL': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Ceil'>>, 'CEILING': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Ceil'>>, 'CHR': <function Parser.<lambda>>, 'CHAR': <function Parser.<lambda>>, 'COALESCE': <function build_coalesce>, 'IFNULL': <function build_coalesce>, 'NVL': <function build_coalesce>, 'COLLATE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Collate'>>, 'COLUMNS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Columns'>>, 'COMBINED_AGG_FUNC': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CombinedAggFunc'>>, 'COMBINED_PARAMETERIZED_AGG': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CombinedParameterizedAgg'>>, 'CONCAT': <function Parser.<lambda>>, 'CONCAT_WS': <function Parser.<lambda>>, 'CONNECT_BY_ROOT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ConnectByRoot'>>, 'CONTAINS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Contains'>>, 'CONVERT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Convert'>>, 'CONVERT_TIMEZONE': <function build_convert_timezone>, 'CORR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Corr'>>, 'COUNT': <function Parser.<lambda>>, 'COUNT_IF': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CountIf'>>, 'COUNTIF': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CountIf'>>, 'COVAR_POP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CovarPop'>>, 'COVAR_SAMP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CovarSamp'>>, 'CURRENT_DATE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CurrentDate'>>, 'CURRENT_DATETIME': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CurrentDatetime'>>, 'CURRENT_TIME': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CurrentTime'>>, 'CURRENT_TIMESTAMP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CurrentTimestamp'>>, 'CURRENT_USER': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CurrentUser'>>, 'DATE': <function MySQL.Parser.<lambda>>, 'DATE_ADD': <function build_date_delta_with_interval.<locals>._builder>, 'DATEDIFF': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DateDiff'>>, 'DATE_DIFF': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DateDiff'>>, 'DATE_FROM_PARTS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DateFromParts'>>, 'DATEFROMPARTS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DateFromParts'>>, 'DATE_STR_TO_DATE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DateStrToDate'>>, 'DATE_SUB': <function build_date_delta_with_interval.<locals>._builder>, 'DATE_TO_DATE_STR': <function Parser.<lambda>>, 'DATE_TO_DI': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DateToDi'>>, 'DATE_TRUNC': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DateTrunc'>>, 'DATETIME': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Datetime'>>, 'DATETIME_ADD': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DatetimeAdd'>>, 'DATETIME_DIFF': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DatetimeDiff'>>, 'DATETIME_SUB': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DatetimeSub'>>, 'DATETIME_TRUNC': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DatetimeTrunc'>>, 'DAY': <function MySQL.Parser.<lambda>>, 'DAY_OF_MONTH': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DayOfMonth'>>, 'DAYOFMONTH': <function MySQL.Parser.<lambda>>, 'DAY_OF_WEEK': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DayOfWeek'>>, 'DAYOFWEEK': <function MySQL.Parser.<lambda>>, 'DAYOFWEEK_ISO': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DayOfWeekIso'>>, 'ISODOW': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DayOfWeekIso'>>, 'DAY_OF_YEAR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DayOfYear'>>, 'DAYOFYEAR': <function MySQL.Parser.<lambda>>, 'DECODE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Decode'>>, 'DI_TO_DATE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DiToDate'>>, 'ENCODE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Encode'>>, 'EXISTS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Exists'>>, 'EXP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Exp'>>, 'EXPLODE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Explode'>>, 'EXPLODE_OUTER': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ExplodeOuter'>>, 'EXPLODING_GENERATE_SERIES': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ExplodingGenerateSeries'>>, 'EXTRACT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Extract'>>, 'FEATURES_AT_TIME': <bound method Func.from_arg_list of <class 'sqlglot.expressions.FeaturesAtTime'>>, 'FIRST': <bound method Func.from_arg_list of <class 'sqlglot.expressions.First'>>, 'FIRST_VALUE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.FirstValue'>>, 'FLATTEN': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Flatten'>>, 'FLOOR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Floor'>>, 'FROM_BASE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.FromBase'>>, 'FROM_BASE64': <bound method Func.from_arg_list of <class 'sqlglot.expressions.FromBase64'>>, 'FROM_ISO8601_TIMESTAMP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.FromISO8601Timestamp'>>, 'GAP_FILL': <bound method Func.from_arg_list of <class 'sqlglot.expressions.GapFill'>>, 'GENERATE_DATE_ARRAY': <function Parser.<lambda>>, 'GENERATE_SERIES': <bound method Func.from_arg_list of <class 'sqlglot.expressions.GenerateSeries'>>, 'GENERATE_TIMESTAMP_ARRAY': <bound method Func.from_arg_list of <class 'sqlglot.expressions.GenerateTimestampArray'>>, 'GREATEST': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Greatest'>>, 'GROUP_CONCAT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.GroupConcat'>>, 'HEX': <function build_hex>, 'HLL': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Hll'>>, 'IF': <bound method Func.from_arg_list of <class 'sqlglot.expressions.If'>>, 'IIF': <bound method Func.from_arg_list of <class 'sqlglot.expressions.If'>>, 'INITCAP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Initcap'>>, 'INLINE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Inline'>>, 'INT64': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Int64'>>, 'IS_ASCII': <bound method Func.from_arg_list of <class 'sqlglot.expressions.IsAscii'>>, 'IS_INF': <bound method Func.from_arg_list of <class 'sqlglot.expressions.IsInf'>>, 'ISINF': <bound method Func.from_arg_list of <class 'sqlglot.expressions.IsInf'>>, 'IS_NAN': <bound method Func.from_arg_list of <class 'sqlglot.expressions.IsNan'>>, 'ISNAN': <bound method Func.from_arg_list of <class 'sqlglot.expressions.IsNan'>>, 'J_S_O_N_ARRAY': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONArray'>>, 'J_S_O_N_ARRAY_AGG': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONArrayAgg'>>, 'JSON_ARRAY_CONTAINS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONArrayContains'>>, 'JSONB_CONTAINS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONBContains'>>, 'JSONB_EXISTS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONBExists'>>, 'JSONB_EXTRACT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONBExtract'>>, 'JSONB_EXTRACT_SCALAR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONBExtractScalar'>>, 'J_S_O_N_EXISTS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONExists'>>, 'JSON_EXTRACT': <function build_extract_json_with_path.<locals>._builder>, 'JSON_EXTRACT_ARRAY': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONExtractArray'>>, 'JSON_EXTRACT_SCALAR': <function build_extract_json_with_path.<locals>._builder>, 'JSON_FORMAT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONFormat'>>, 'J_S_O_N_OBJECT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONObject'>>, 'J_S_O_N_OBJECT_AGG': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONObjectAgg'>>, 'J_S_O_N_TABLE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONTable'>>, 'J_S_O_N_VALUE_ARRAY': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONValueArray'>>, 'LAG': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Lag'>>, 'LAST': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Last'>>, 'LAST_DAY': <bound method Func.from_arg_list of <class 'sqlglot.expressions.LastDay'>>, 'LAST_DAY_OF_MONTH': <bound method Func.from_arg_list of <class 'sqlglot.expressions.LastDay'>>, 'LAST_VALUE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.LastValue'>>, 'LEAD': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Lead'>>, 'LEAST': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Least'>>, 'LEFT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Left'>>, 'LENGTH': <function MySQL.Parser.<lambda>>, 'LEN': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Length'>>, 'CHAR_LENGTH': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Length'>>, 'CHARACTER_LENGTH': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Length'>>, 'LEVENSHTEIN': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Levenshtein'>>, 'LIST': <bound method Func.from_arg_list of <class 'sqlglot.expressions.List'>>, 'LN': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Ln'>>, 'LOG': <function build_logarithm>, 'LOGICAL_AND': <bound method Func.from_arg_list of <class 'sqlglot.expressions.LogicalAnd'>>, 'BOOL_AND': <bound method Func.from_arg_list of <class 'sqlglot.expressions.LogicalAnd'>>, 'BOOLAND_AGG': <bound method Func.from_arg_list of <class 'sqlglot.expressions.LogicalAnd'>>, 'LOGICAL_OR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.LogicalOr'>>, 'BOOL_OR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.LogicalOr'>>, 'BOOLOR_AGG': <bound method Func.from_arg_list of <class 'sqlglot.expressions.LogicalOr'>>, 'LOWER': <function build_lower>, 'LCASE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Lower'>>, 'LOWER_HEX': <bound method Func.from_arg_list of <class 'sqlglot.expressions.LowerHex'>>, 'MD5': <bound method Func.from_arg_list of <class 'sqlglot.expressions.MD5'>>, 'MD5_DIGEST': <bound method Func.from_arg_list of <class 'sqlglot.expressions.MD5Digest'>>, 'MAKE_INTERVAL': <bound method Func.from_arg_list of <class 'sqlglot.expressions.MakeInterval'>>, 'MAP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Map'>>, 'MAP_FROM_ENTRIES': <bound method Func.from_arg_list of <class 'sqlglot.expressions.MapFromEntries'>>, 'MATCH_AGAINST': <bound method Func.from_arg_list of <class 'sqlglot.expressions.MatchAgainst'>>, 'MAX': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Max'>>, 'MEDIAN': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Median'>>, 'MIN': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Min'>>, 'MONTH': <function MySQL.Parser.<lambda>>, 'MONTHS_BETWEEN': <bound method Func.from_arg_list of <class 'sqlglot.expressions.MonthsBetween'>>, 'NEXT_VALUE_FOR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.NextValueFor'>>, 'NORMALIZE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Normalize'>>, 'NTH_VALUE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.NthValue'>>, 'NULLIF': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Nullif'>>, 'NUMBER_TO_STR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.NumberToStr'>>, 'NVL2': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Nvl2'>>, 'OBJECT_INSERT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ObjectInsert'>>, 'OPEN_J_S_O_N': <bound method Func.from_arg_list of <class 'sqlglot.expressions.OpenJSON'>>, 'OVERLAY': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Overlay'>>, 'PAD': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Pad'>>, 'PARAMETERIZED_AGG': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ParameterizedAgg'>>, 'PARSE_JSON': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ParseJSON'>>, 'JSON_PARSE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ParseJSON'>>, 'PERCENTILE_CONT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.PercentileCont'>>, 'PERCENTILE_DISC': <bound method Func.from_arg_list of <class 'sqlglot.expressions.PercentileDisc'>>, 'POSEXPLODE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Posexplode'>>, 'POSEXPLODE_OUTER': <bound method Func.from_arg_list of <class 'sqlglot.expressions.PosexplodeOuter'>>, 'POWER': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Pow'>>, 'POW': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Pow'>>, 'PREDICT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Predict'>>, 'QUANTILE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Quantile'>>, 'QUARTER': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Quarter'>>, 'RAND': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Rand'>>, 'RANDOM': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Rand'>>, 'RANDN': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Randn'>>, 'RANGE_N': <bound method Func.from_arg_list of <class 'sqlglot.expressions.RangeN'>>, 'READ_CSV': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ReadCSV'>>, 'REDUCE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Reduce'>>, 'REGEXP_EXTRACT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.RegexpExtract'>>, 'REGEXP_EXTRACT_ALL': <bound method Func.from_arg_list of <class 'sqlglot.expressions.RegexpExtractAll'>>, 'REGEXP_I_LIKE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.RegexpILike'>>, 'REGEXP_LIKE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.RegexpLike'>>, 'REGEXP_REPLACE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.RegexpReplace'>>, 'REGEXP_SPLIT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.RegexpSplit'>>, 'REPEAT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Repeat'>>, 'RIGHT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Right'>>, 'ROUND': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Round'>>, 'ROW_NUMBER': <bound method Func.from_arg_list of <class 'sqlglot.expressions.RowNumber'>>, 'SHA': <bound method Func.from_arg_list of <class 'sqlglot.expressions.SHA'>>, 'SHA1': <bound method Func.from_arg_list of <class 'sqlglot.expressions.SHA'>>, 'SHA2': <bound method Func.from_arg_list of <class 'sqlglot.expressions.SHA2'>>, 'SAFE_DIVIDE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.SafeDivide'>>, 'SIGN': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Sign'>>, 'SIGNUM': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Sign'>>, 'SORT_ARRAY': <bound method Func.from_arg_list of <class 'sqlglot.expressions.SortArray'>>, 'SPLIT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Split'>>, 'SPLIT_PART': <bound method Func.from_arg_list of <class 'sqlglot.expressions.SplitPart'>>, 'SQRT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Sqrt'>>, 'STANDARD_HASH': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StandardHash'>>, 'STAR_MAP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StarMap'>>, 'STARTS_WITH': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StartsWith'>>, 'STARTSWITH': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StartsWith'>>, 'STDDEV': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Stddev'>>, 'STDEV': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Stddev'>>, 'STDDEV_POP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StddevPop'>>, 'STDDEV_SAMP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StddevSamp'>>, 'STR_POSITION': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StrPosition'>>, 'STR_TO_DATE': <function _str_to_date>, 'STR_TO_MAP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StrToMap'>>, 'STR_TO_TIME': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StrToTime'>>, 'STR_TO_UNIX': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StrToUnix'>>, 'STRING': <bound method Func.from_arg_list of <class 'sqlglot.expressions.String'>>, 'STRING_TO_ARRAY': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StringToArray'>>, 'SPLIT_BY_STRING': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StringToArray'>>, 'STRUCT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Struct'>>, 'STRUCT_EXTRACT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StructExtract'>>, 'STUFF': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Stuff'>>, 'INSERT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Stuff'>>, 'SUBSTRING': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Substring'>>, 'SUBSTR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Substring'>>, 'SUM': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Sum'>>, 'TIME': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Time'>>, 'TIME_ADD': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimeAdd'>>, 'TIME_DIFF': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimeDiff'>>, 'TIME_FROM_PARTS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimeFromParts'>>, 'TIMEFROMPARTS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimeFromParts'>>, 'TIME_STR_TO_DATE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimeStrToDate'>>, 'TIME_STR_TO_TIME': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimeStrToTime'>>, 'TIME_STR_TO_UNIX': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimeStrToUnix'>>, 'TIME_SUB': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimeSub'>>, 'TIME_TO_STR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimeToStr'>>, 'TIME_TO_TIME_STR': <function Parser.<lambda>>, 'TIME_TO_UNIX': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimeToUnix'>>, 'TIME_TRUNC': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimeTrunc'>>, 'TIMESTAMP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Timestamp'>>, 'TIMESTAMP_ADD': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimestampAdd'>>, 'TIMESTAMPDIFF': <function build_date_delta.<locals>._builder>, 'TIMESTAMP_DIFF': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimestampDiff'>>, 'TIMESTAMP_FROM_PARTS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimestampFromParts'>>, 'TIMESTAMPFROMPARTS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimestampFromParts'>>, 'TIMESTAMP_SUB': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimestampSub'>>, 'TIMESTAMP_TRUNC': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimestampTrunc'>>, 'TO_ARRAY': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ToArray'>>, 'TO_BASE64': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ToBase64'>>, 'TO_CHAR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ToChar'>>, 'TO_DAYS': <function MySQL.Parser.<lambda>>, 'TO_DOUBLE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ToDouble'>>, 'TO_MAP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ToMap'>>, 'TO_NUMBER': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ToNumber'>>, 'TRANSFORM': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Transform'>>, 'TRIM': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Trim'>>, 'TRY': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Try'>>, 'TRY_CAST': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TryCast'>>, 'TS_OR_DI_TO_DI': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TsOrDiToDi'>>, 'TS_OR_DS_ADD': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TsOrDsAdd'>>, 'TS_OR_DS_DIFF': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TsOrDsDiff'>>, 'TS_OR_DS_TO_DATE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TsOrDsToDate'>>, 'TS_OR_DS_TO_DATE_STR': <function Parser.<lambda>>, 'TS_OR_DS_TO_DATETIME': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TsOrDsToDatetime'>>, 'TS_OR_DS_TO_TIME': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TsOrDsToTime'>>, 'TS_OR_DS_TO_TIMESTAMP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TsOrDsToTimestamp'>>, 'UNHEX': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Unhex'>>, 'UNICODE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Unicode'>>, 'UNIX_DATE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.UnixDate'>>, 'UNIX_SECONDS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.UnixSeconds'>>, 'UNIX_TO_STR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.UnixToStr'>>, 'UNIX_TO_TIME': <bound method Func.from_arg_list of <class 'sqlglot.expressions.UnixToTime'>>, 'UNIX_TO_TIME_STR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.UnixToTimeStr'>>, 'UNNEST': <function Parser.<lambda>>, 'UPPER': <function build_upper>, 'UCASE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Upper'>>, 'UUID': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Uuid'>>, 'GEN_RANDOM_UUID': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Uuid'>>, 'GENERATE_UUID': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Uuid'>>, 'UUID_STRING': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Uuid'>>, 'VAR_MAP': <function build_var_map>, 'VARIANCE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Variance'>>, 'VARIANCE_SAMP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Variance'>>, 'VAR_SAMP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Variance'>>, 'VARIANCE_POP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.VariancePop'>>, 'VAR_POP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.VariancePop'>>, 'WEEK': <function MySQL.Parser.<lambda>>, 'WEEK_OF_YEAR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.WeekOfYear'>>, 'WEEKOFYEAR': <function MySQL.Parser.<lambda>>, 'XMLELEMENT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.XMLElement'>>, 'X_M_L_TABLE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.XMLTable'>>, 'XOR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Xor'>>, 'YEAR': <function MySQL.Parser.<lambda>>, 'ARRAYAGG': <function Parser.<lambda>>, 'GLOB': <function Parser.<lambda>>, '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>, '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>>, 'CEIL': <function Parser.<lambda>>, 'CONVERT': <function Parser.<lambda>>, 'DECODE': <function Parser.<lambda>>, 'EXTRACT': <function Parser.<lambda>>, 'FLOOR': <function Parser.<lambda>>, 'GAP_FILL': <function Parser.<lambda>>, 'JSON_OBJECT': <function Parser.<lambda>>, 'JSON_OBJECTAGG': <function Parser.<lambda>>, 'JSON_TABLE': <function Parser.<lambda>>, 'MATCH': <function Parser.<lambda>>, 'NORMALIZE': <function Parser.<lambda>>, 'OPENJSON': <function Parser.<lambda>>, 'OVERLAY': <function Parser.<lambda>>, 'POSITION': <function Parser.<lambda>>, 'PREDICT': <function Parser.<lambda>>, 'SAFE_CAST': <function Parser.<lambda>>, 'STRING_AGG': <function Parser.<lambda>>, 'SUBSTRING': <function Parser.<lambda>>, 'TRIM': <function Parser.<lambda>>, 'TRY_CAST': <function Parser.<lambda>>, 'TRY_CONVERT': <function Parser.<lambda>>, 'XMLELEMENT': <function Parser.<lambda>>, 'XMLTABLE': <function Parser.<lambda>>, 'CHAR': <function MySQL.Parser.<lambda>>, 'GROUP_CONCAT': <function MySQL.Parser.<lambda>>, 'VALUES': <function MySQL.Parser.<lambda>>, 'JSON_VALUE': <function MySQL.Parser.<lambda>>}
STATEMENT_PARSERS =
{<TokenType.ALTER: 'ALTER'>: <function Parser.<lambda>>, <TokenType.ANALYZE: 'ANALYZE'>: <function Parser.<lambda>>, <TokenType.BEGIN: 'BEGIN'>: <function Parser.<lambda>>, <TokenType.CACHE: 'CACHE'>: <function Parser.<lambda>>, <TokenType.COMMENT: 'COMMENT'>: <function Parser.<lambda>>, <TokenType.COMMIT: 'COMMIT'>: <function Parser.<lambda>>, <TokenType.COPY: 'COPY'>: <function Parser.<lambda>>, <TokenType.CREATE: 'CREATE'>: <function Parser.<lambda>>, <TokenType.DELETE: 'DELETE'>: <function Parser.<lambda>>, <TokenType.DESC: 'DESC'>: <function Parser.<lambda>>, <TokenType.DESCRIBE: 'DESCRIBE'>: <function Parser.<lambda>>, <TokenType.DROP: 'DROP'>: <function Parser.<lambda>>, <TokenType.GRANT: 'GRANT'>: <function Parser.<lambda>>, <TokenType.INSERT: 'INSERT'>: <function Parser.<lambda>>, <TokenType.KILL: 'KILL'>: <function Parser.<lambda>>, <TokenType.LOAD: 'LOAD'>: <function Parser.<lambda>>, <TokenType.MERGE: 'MERGE'>: <function Parser.<lambda>>, <TokenType.PIVOT: 'PIVOT'>: <function Parser.<lambda>>, <TokenType.PRAGMA: 'PRAGMA'>: <function Parser.<lambda>>, <TokenType.REFRESH: 'REFRESH'>: <function Parser.<lambda>>, <TokenType.ROLLBACK: 'ROLLBACK'>: <function Parser.<lambda>>, <TokenType.SET: 'SET'>: <function Parser.<lambda>>, <TokenType.TRUNCATE: 'TRUNCATE'>: <function Parser.<lambda>>, <TokenType.UNCACHE: 'UNCACHE'>: <function Parser.<lambda>>, <TokenType.UNPIVOT: 'UNPIVOT'>: <function Parser.<lambda>>, <TokenType.UPDATE: 'UPDATE'>: <function Parser.<lambda>>, <TokenType.USE: 'USE'>: <function Parser.<lambda>>, <TokenType.SEMICOLON: 'SEMICOLON'>: <function Parser.<lambda>>, <TokenType.SHOW: 'SHOW'>: <function MySQL.Parser.<lambda>>}
SHOW_PARSERS =
{'BINARY LOGS': <function _show_parser.<locals>._parse>, 'MASTER LOGS': <function _show_parser.<locals>._parse>, 'BINLOG EVENTS': <function _show_parser.<locals>._parse>, 'CHARACTER SET': <function _show_parser.<locals>._parse>, 'CHARSET': <function _show_parser.<locals>._parse>, 'COLLATION': <function _show_parser.<locals>._parse>, 'FULL COLUMNS': <function _show_parser.<locals>._parse>, 'COLUMNS': <function _show_parser.<locals>._parse>, 'CREATE DATABASE': <function _show_parser.<locals>._parse>, 'CREATE EVENT': <function _show_parser.<locals>._parse>, 'CREATE FUNCTION': <function _show_parser.<locals>._parse>, 'CREATE PROCEDURE': <function _show_parser.<locals>._parse>, 'CREATE TABLE': <function _show_parser.<locals>._parse>, 'CREATE TRIGGER': <function _show_parser.<locals>._parse>, 'CREATE VIEW': <function _show_parser.<locals>._parse>, 'DATABASES': <function _show_parser.<locals>._parse>, 'SCHEMAS': <function _show_parser.<locals>._parse>, 'ENGINE': <function _show_parser.<locals>._parse>, 'STORAGE ENGINES': <function _show_parser.<locals>._parse>, 'ENGINES': <function _show_parser.<locals>._parse>, 'ERRORS': <function _show_parser.<locals>._parse>, 'EVENTS': <function _show_parser.<locals>._parse>, 'FUNCTION CODE': <function _show_parser.<locals>._parse>, 'FUNCTION STATUS': <function _show_parser.<locals>._parse>, 'GRANTS': <function _show_parser.<locals>._parse>, 'INDEX': <function _show_parser.<locals>._parse>, 'MASTER STATUS': <function _show_parser.<locals>._parse>, 'OPEN TABLES': <function _show_parser.<locals>._parse>, 'PLUGINS': <function _show_parser.<locals>._parse>, 'PROCEDURE CODE': <function _show_parser.<locals>._parse>, 'PROCEDURE STATUS': <function _show_parser.<locals>._parse>, 'PRIVILEGES': <function _show_parser.<locals>._parse>, 'FULL PROCESSLIST': <function _show_parser.<locals>._parse>, 'PROCESSLIST': <function _show_parser.<locals>._parse>, 'PROFILE': <function _show_parser.<locals>._parse>, 'PROFILES': <function _show_parser.<locals>._parse>, 'RELAYLOG EVENTS': <function _show_parser.<locals>._parse>, 'REPLICAS': <function _show_parser.<locals>._parse>, 'SLAVE HOSTS': <function _show_parser.<locals>._parse>, 'REPLICA STATUS': <function _show_parser.<locals>._parse>, 'SLAVE STATUS': <function _show_parser.<locals>._parse>, 'GLOBAL STATUS': <function _show_parser.<locals>._parse>, 'SESSION STATUS': <function _show_parser.<locals>._parse>, 'STATUS': <function _show_parser.<locals>._parse>, 'TABLE STATUS': <function _show_parser.<locals>._parse>, 'FULL TABLES': <function _show_parser.<locals>._parse>, 'TABLES': <function _show_parser.<locals>._parse>, 'TRIGGERS': <function _show_parser.<locals>._parse>, 'GLOBAL VARIABLES': <function _show_parser.<locals>._parse>, 'SESSION VARIABLES': <function _show_parser.<locals>._parse>, 'VARIABLES': <function _show_parser.<locals>._parse>, 'WARNINGS': <function _show_parser.<locals>._parse>}
PROPERTY_PARSERS =
{'ALLOWED_VALUES': <function Parser.<lambda>>, 'ALGORITHM': <function Parser.<lambda>>, 'AUTO': <function Parser.<lambda>>, 'AUTO_INCREMENT': <function Parser.<lambda>>, 'BACKUP': <function Parser.<lambda>>, 'BLOCKCOMPRESSION': <function Parser.<lambda>>, 'CHARSET': <function Parser.<lambda>>, 'CHARACTER SET': <function Parser.<lambda>>, 'CHECKSUM': <function Parser.<lambda>>, 'CLUSTER BY': <function Parser.<lambda>>, 'CLUSTERED': <function Parser.<lambda>>, 'COLLATE': <function Parser.<lambda>>, 'COMMENT': <function Parser.<lambda>>, 'CONTAINS': <function Parser.<lambda>>, 'COPY': <function Parser.<lambda>>, 'DATABLOCKSIZE': <function Parser.<lambda>>, 'DATA_DELETION': <function Parser.<lambda>>, 'DEFINER': <function Parser.<lambda>>, 'DETERMINISTIC': <function Parser.<lambda>>, 'DISTRIBUTED': <function Parser.<lambda>>, 'DUPLICATE': <function Parser.<lambda>>, 'DYNAMIC': <function Parser.<lambda>>, 'DISTKEY': <function Parser.<lambda>>, 'DISTSTYLE': <function Parser.<lambda>>, 'EMPTY': <function Parser.<lambda>>, 'ENGINE': <function Parser.<lambda>>, 'EXECUTE': <function Parser.<lambda>>, 'EXTERNAL': <function Parser.<lambda>>, 'FALLBACK': <function Parser.<lambda>>, 'FORMAT': <function Parser.<lambda>>, 'FREESPACE': <function Parser.<lambda>>, 'GLOBAL': <function Parser.<lambda>>, 'HEAP': <function Parser.<lambda>>, 'ICEBERG': <function Parser.<lambda>>, 'IMMUTABLE': <function Parser.<lambda>>, 'INHERITS': <function Parser.<lambda>>, 'INPUT': <function Parser.<lambda>>, 'JOURNAL': <function Parser.<lambda>>, 'LANGUAGE': <function Parser.<lambda>>, 'LAYOUT': <function Parser.<lambda>>, 'LIFETIME': <function Parser.<lambda>>, 'LIKE': <function Parser.<lambda>>, 'LOCATION': <function Parser.<lambda>>, 'LOCK': <function MySQL.Parser.<lambda>>, 'LOCKING': <function Parser.<lambda>>, 'LOG': <function Parser.<lambda>>, 'MATERIALIZED': <function Parser.<lambda>>, 'MERGEBLOCKRATIO': <function Parser.<lambda>>, 'MODIFIES': <function Parser.<lambda>>, 'MULTISET': <function Parser.<lambda>>, 'NO': <function Parser.<lambda>>, 'ON': <function Parser.<lambda>>, 'ORDER BY': <function Parser.<lambda>>, 'OUTPUT': <function Parser.<lambda>>, 'PARTITION': <function Parser.<lambda>>, 'PARTITION BY': <function Parser.<lambda>>, 'PARTITIONED BY': <function Parser.<lambda>>, 'PARTITIONED_BY': <function Parser.<lambda>>, 'PRIMARY KEY': <function Parser.<lambda>>, 'RANGE': <function Parser.<lambda>>, 'READS': <function Parser.<lambda>>, 'REMOTE': <function Parser.<lambda>>, 'RETURNS': <function Parser.<lambda>>, 'STRICT': <function Parser.<lambda>>, 'STREAMING': <function Parser.<lambda>>, 'ROW': <function Parser.<lambda>>, 'ROW_FORMAT': <function Parser.<lambda>>, 'SAMPLE': <function Parser.<lambda>>, 'SECURE': <function Parser.<lambda>>, 'SECURITY': <function Parser.<lambda>>, 'SET': <function Parser.<lambda>>, 'SETTINGS': <function Parser.<lambda>>, 'SHARING': <function Parser.<lambda>>, 'SORTKEY': <function Parser.<lambda>>, 'SOURCE': <function Parser.<lambda>>, 'STABLE': <function Parser.<lambda>>, 'STORED': <function Parser.<lambda>>, 'SYSTEM_VERSIONING': <function Parser.<lambda>>, 'TBLPROPERTIES': <function Parser.<lambda>>, 'TEMP': <function Parser.<lambda>>, 'TEMPORARY': <function Parser.<lambda>>, 'TO': <function Parser.<lambda>>, 'TRANSIENT': <function Parser.<lambda>>, 'TRANSFORM': <function Parser.<lambda>>, 'TTL': <function Parser.<lambda>>, 'USING': <function Parser.<lambda>>, 'UNLOGGED': <function Parser.<lambda>>, 'VOLATILE': <function Parser.<lambda>>, 'WITH': <function Parser.<lambda>>}
SET_PARSERS =
{'GLOBAL': <function Parser.<lambda>>, 'LOCAL': <function Parser.<lambda>>, 'SESSION': <function Parser.<lambda>>, 'TRANSACTION': <function Parser.<lambda>>, 'PERSIST': <function MySQL.Parser.<lambda>>, 'PERSIST_ONLY': <function MySQL.Parser.<lambda>>, 'CHARACTER SET': <function MySQL.Parser.<lambda>>, 'CHARSET': <function MySQL.Parser.<lambda>>, 'NAMES': <function MySQL.Parser.<lambda>>}
CONSTRAINT_PARSERS =
{'AUTOINCREMENT': <function Parser.<lambda>>, 'AUTO_INCREMENT': <function Parser.<lambda>>, 'CASESPECIFIC': <function Parser.<lambda>>, 'CHARACTER SET': <function Parser.<lambda>>, 'CHECK': <function Parser.<lambda>>, 'COLLATE': <function Parser.<lambda>>, 'COMMENT': <function Parser.<lambda>>, 'COMPRESS': <function Parser.<lambda>>, 'CLUSTERED': <function Parser.<lambda>>, 'NONCLUSTERED': <function Parser.<lambda>>, 'DEFAULT': <function Parser.<lambda>>, 'ENCODE': <function Parser.<lambda>>, 'EPHEMERAL': <function Parser.<lambda>>, 'EXCLUDE': <function Parser.<lambda>>, 'FOREIGN KEY': <function Parser.<lambda>>, 'FORMAT': <function Parser.<lambda>>, 'GENERATED': <function Parser.<lambda>>, 'IDENTITY': <function Parser.<lambda>>, 'INLINE': <function Parser.<lambda>>, 'LIKE': <function Parser.<lambda>>, 'NOT': <function Parser.<lambda>>, 'NULL': <function Parser.<lambda>>, 'ON': <function Parser.<lambda>>, 'PATH': <function Parser.<lambda>>, 'PERIOD': <function Parser.<lambda>>, 'PRIMARY KEY': <function Parser.<lambda>>, 'REFERENCES': <function Parser.<lambda>>, 'TITLE': <function Parser.<lambda>>, 'TTL': <function Parser.<lambda>>, 'UNIQUE': <function Parser.<lambda>>, 'UPPERCASE': <function Parser.<lambda>>, 'WATERMARK': <function Parser.<lambda>>, 'WITH': <function Parser.<lambda>>, 'FULLTEXT': <function MySQL.Parser.<lambda>>, 'INDEX': <function MySQL.Parser.<lambda>>, 'KEY': <function MySQL.Parser.<lambda>>, 'SPATIAL': <function MySQL.Parser.<lambda>>}
ALTER_PARSERS =
{'ADD': <function Parser.<lambda>>, 'AS': <function Parser.<lambda>>, 'ALTER': <function Parser.<lambda>>, 'CLUSTER BY': <function Parser.<lambda>>, 'DELETE': <function Parser.<lambda>>, 'DROP': <function Parser.<lambda>>, 'RENAME': <function Parser.<lambda>>, 'SET': <function Parser.<lambda>>, 'SWAP': <function Parser.<lambda>>, 'MODIFY': <function MySQL.Parser.<lambda>>}
SCHEMA_UNNAMED_CONSTRAINTS =
{'CHECK', 'FOREIGN KEY', 'PERIOD', 'LIKE', 'UNIQUE', 'KEY', 'SPATIAL', 'INDEX', 'PRIMARY KEY', 'FULLTEXT', 'EXCLUDE', 'WATERMARK'}
PROFILE_TYPES: Dict[str, Sequence[Union[Sequence[str], str]]] =
{'ALL': (), 'CPU': (), 'IPC': (), 'MEMORY': (), 'SOURCE': (), 'SWAPS': (), 'BLOCK': ('IO',), 'CONTEXT': ('SWITCHES',), 'PAGE': ('FAULTS',)}
TYPE_TOKENS =
{<TokenType.TIMESTAMP_S: 'TIMESTAMP_S'>, <TokenType.VARIANT: 'VARIANT'>, <TokenType.TSTZRANGE: 'TSTZRANGE'>, <TokenType.HSTORE: 'HSTORE'>, <TokenType.TINYBLOB: 'TINYBLOB'>, <TokenType.INT256: 'INT256'>, <TokenType.BIT: 'BIT'>, <TokenType.BINARY: 'BINARY'>, <TokenType.DECIMAL32: 'DECIMAL32'>, <TokenType.MONEY: 'MONEY'>, <TokenType.NULLABLE: 'NULLABLE'>, <TokenType.DATETIME2: 'DATETIME2'>, <TokenType.SIMPLEAGGREGATEFUNCTION: 'SIMPLEAGGREGATEFUNCTION'>, <TokenType.GEOMETRY: 'GEOMETRY'>, <TokenType.DATE: 'DATE'>, <TokenType.DATEMULTIRANGE: 'DATEMULTIRANGE'>, <TokenType.USERDEFINED: 'USERDEFINED'>, <TokenType.TIME: 'TIME'>, <TokenType.RING: 'RING'>, <TokenType.TSMULTIRANGE: 'TSMULTIRANGE'>, <TokenType.INT128: 'INT128'>, <TokenType.MULTIPOLYGON: 'MULTIPOLYGON'>, <TokenType.INT8MULTIRANGE: 'INT8MULTIRANGE'>, <TokenType.SERIAL: 'SERIAL'>, <TokenType.UNION: 'UNION'>, <TokenType.LINESTRING: 'LINESTRING'>, <TokenType.ARRAY: 'ARRAY'>, <TokenType.POLYGON: 'POLYGON'>, <TokenType.UDECIMAL: 'UDECIMAL'>, <TokenType.LOWCARDINALITY: 'LOWCARDINALITY'>, <TokenType.MEDIUMBLOB: 'MEDIUMBLOB'>, <TokenType.INT4MULTIRANGE: 'INT4MULTIRANGE'>, <TokenType.UBIGINT: 'UBIGINT'>, <TokenType.BIGINT: 'BIGINT'>, <TokenType.AGGREGATEFUNCTION: 'AGGREGATEFUNCTION'>, <TokenType.BOOLEAN: 'BOOLEAN'>, <TokenType.NVARCHAR: 'NVARCHAR'>, <TokenType.MEDIUMTEXT: 'MEDIUMTEXT'>, <TokenType.ROWVERSION: 'ROWVERSION'>, <TokenType.MEDIUMINT: 'MEDIUMINT'>, <TokenType.INT: 'INT'>, <TokenType.JSONB: 'JSONB'>, <TokenType.HLLSKETCH: 'HLLSKETCH'>, <TokenType.SET: 'SET'>, <TokenType.DATERANGE: 'DATERANGE'>, <TokenType.LIST: 'LIST'>, <TokenType.SMALLMONEY: 'SMALLMONEY'>, <TokenType.STRUCT: 'STRUCT'>, <TokenType.UNKNOWN: 'UNKNOWN'>, <TokenType.TINYINT: 'TINYINT'>, <TokenType.DECIMAL64: 'DECIMAL64'>, <TokenType.TIMESTAMP_NS: 'TIMESTAMP_NS'>, <TokenType.LONGBLOB: 'LONGBLOB'>, <TokenType.XML: 'XML'>, <TokenType.IPADDRESS: 'IPADDRESS'>, <TokenType.SMALLSERIAL: 'SMALLSERIAL'>, <TokenType.IPPREFIX: 'IPPREFIX'>, <TokenType.ENUM16: 'ENUM16'>, <TokenType.VECTOR: 'VECTOR'>, <TokenType.INT4RANGE: 'INT4RANGE'>, <TokenType.OBJECT: 'OBJECT'>, <TokenType.TSRANGE: 'TSRANGE'>, <TokenType.UUID: 'UUID'>, <TokenType.NULL: 'NULL'>, <TokenType.DATETIME64: 'DATETIME64'>, <TokenType.USMALLINT: 'USMALLINT'>, <TokenType.INET: 'INET'>, <TokenType.INT8RANGE: 'INT8RANGE'>, <TokenType.IMAGE: 'IMAGE'>, <TokenType.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, <TokenType.DECIMAL: 'DECIMAL'>, <TokenType.UNIQUEIDENTIFIER: 'UNIQUEIDENTIFIER'>, <TokenType.LONGTEXT: 'LONGTEXT'>, <TokenType.NUMRANGE: 'NUMRANGE'>, <TokenType.NESTED: 'NESTED'>, <TokenType.UTINYINT: 'UTINYINT'>, <TokenType.UMEDIUMINT: 'UMEDIUMINT'>, <TokenType.SMALLDATETIME: 'SMALLDATETIME'>, <TokenType.ENUM8: 'ENUM8'>, <TokenType.DECIMAL256: 'DECIMAL256'>, <TokenType.TIMESTAMP_MS: 'TIMESTAMP_MS'>, <TokenType.GEOGRAPHY: 'GEOGRAPHY'>, <TokenType.TEXT: 'TEXT'>, <TokenType.BIGDECIMAL: 'BIGDECIMAL'>, <TokenType.MULTILINESTRING: 'MULTILINESTRING'>, <TokenType.NUMMULTIRANGE: 'NUMMULTIRANGE'>, <TokenType.UINT256: 'UINT256'>, <TokenType.BPCHAR: 'BPCHAR'>, <TokenType.VARCHAR: 'VARCHAR'>, <TokenType.TINYTEXT: 'TINYTEXT'>, <TokenType.INTERVAL: 'INTERVAL'>, <TokenType.JSON: 'JSON'>, <TokenType.PSEUDO_TYPE: 'PSEUDO_TYPE'>, <TokenType.DOUBLE: 'DOUBLE'>, <TokenType.TIMETZ: 'TIMETZ'>, <TokenType.TDIGEST: 'TDIGEST'>, <TokenType.NAME: 'NAME'>, <TokenType.POINT: 'POINT'>, <TokenType.MAP: 'MAP'>, <TokenType.IPV4: 'IPV4'>, <TokenType.SMALLINT: 'SMALLINT'>, <TokenType.ENUM: 'ENUM'>, <TokenType.DECIMAL128: 'DECIMAL128'>, <TokenType.RANGE: 'RANGE'>, <TokenType.FIXEDSTRING: 'FIXEDSTRING'>, <TokenType.TIMESTAMP: 'TIMESTAMP'>, <TokenType.TSTZMULTIRANGE: 'TSTZMULTIRANGE'>, <TokenType.CHAR: 'CHAR'>, <TokenType.YEAR: 'YEAR'>, <TokenType.UINT128: 'UINT128'>, <TokenType.OBJECT_IDENTIFIER: 'OBJECT_IDENTIFIER'>, <TokenType.IPV6: 'IPV6'>, <TokenType.NCHAR: 'NCHAR'>, <TokenType.DATETIME: 'DATETIME'>, <TokenType.VARBINARY: 'VARBINARY'>, <TokenType.DATE32: 'DATE32'>, <TokenType.TIMESTAMPTZ: 'TIMESTAMPTZ'>, <TokenType.UINT: 'UINT'>, <TokenType.SUPER: 'SUPER'>, <TokenType.BIGSERIAL: 'BIGSERIAL'>, <TokenType.TIMESTAMPNTZ: 'TIMESTAMPNTZ'>, <TokenType.FLOAT: 'FLOAT'>}
ENUM_TYPE_TOKENS =
{<TokenType.ENUM8: 'ENUM8'>, <TokenType.ENUM16: 'ENUM16'>, <TokenType.SET: 'SET'>, <TokenType.ENUM: 'ENUM'>}
OPERATION_MODIFIERS =
{'SQL_BIG_RESULT', 'SQL_SMALL_RESULT', 'SQL_NO_CACHE', 'SQL_CALC_FOUND_ROWS', 'STRAIGHT_JOIN', 'SQL_BUFFER_RESULT', 'HIGH_PRIORITY'}
SHOW_TRIE: Dict =
{'BINARY': {'LOGS': {0: True}}, 'MASTER': {'LOGS': {0: True}, 'STATUS': {0: True}}, 'BINLOG': {'EVENTS': {0: True}}, 'CHARACTER': {'SET': {0: True}}, 'CHARSET': {0: True}, 'COLLATION': {0: True}, 'FULL': {'COLUMNS': {0: True}, 'PROCESSLIST': {0: True}, 'TABLES': {0: True}}, 'COLUMNS': {0: True}, 'CREATE': {'DATABASE': {0: True}, 'EVENT': {0: True}, 'FUNCTION': {0: True}, 'PROCEDURE': {0: True}, 'TABLE': {0: True}, 'TRIGGER': {0: True}, 'VIEW': {0: True}}, 'DATABASES': {0: True}, 'SCHEMAS': {0: True}, 'ENGINE': {0: True}, 'STORAGE': {'ENGINES': {0: True}}, 'ENGINES': {0: True}, 'ERRORS': {0: True}, 'EVENTS': {0: True}, 'FUNCTION': {'CODE': {0: True}, 'STATUS': {0: True}}, 'GRANTS': {0: True}, 'INDEX': {0: True}, 'OPEN': {'TABLES': {0: True}}, 'PLUGINS': {0: True}, 'PROCEDURE': {'CODE': {0: True}, 'STATUS': {0: True}}, 'PRIVILEGES': {0: True}, 'PROCESSLIST': {0: True}, 'PROFILE': {0: True}, 'PROFILES': {0: True}, 'RELAYLOG': {'EVENTS': {0: True}}, 'REPLICAS': {0: True}, 'SLAVE': {'HOSTS': {0: True}, 'STATUS': {0: True}}, 'REPLICA': {'STATUS': {0: True}}, 'GLOBAL': {'STATUS': {0: True}, 'VARIABLES': {0: True}}, 'SESSION': {'STATUS': {0: True}, 'VARIABLES': {0: True}}, 'STATUS': {0: True}, 'TABLE': {'STATUS': {0: True}}, 'TABLES': {0: True}, 'TRIGGERS': {0: True}, 'VARIABLES': {0: True}, 'WARNINGS': {0: True}}
SET_TRIE: Dict =
{'GLOBAL': {0: True}, 'LOCAL': {0: True}, 'SESSION': {0: True}, 'TRANSACTION': {0: True}, 'PERSIST': {0: True}, 'PERSIST_ONLY': {0: True}, 'CHARACTER': {'SET': {0: True}}, 'CHARSET': {0: True}, 'NAMES': {0: True}}
Inherited Members
- sqlglot.parser.Parser
- Parser
- NO_PAREN_FUNCTIONS
- STRUCT_TYPE_TOKENS
- NESTED_TYPE_TOKENS
- AGGREGATE_TYPE_TOKENS
- SIGNED_TO_UNSIGNED_TYPE_TOKEN
- SUBQUERY_PREDICATES
- RESERVED_TOKENS
- DB_CREATABLES
- CREATABLES
- ALTERABLES
- ID_VAR_TOKENS
- INTERVAL_VARS
- ALIAS_TOKENS
- ARRAY_CONSTRUCTORS
- COMMENT_TABLE_ALIAS_TOKENS
- UPDATE_ALIAS_TOKENS
- TRIM_TYPES
- ASSIGNMENT
- EQUALITY
- COMPARISON
- BITWISE
- TERM
- FACTOR
- EXPONENT
- TIMES
- TIMESTAMPS
- SET_OPERATIONS
- JOIN_METHODS
- JOIN_SIDES
- JOIN_KINDS
- JOIN_HINTS
- LAMBDAS
- COLUMN_OPERATORS
- EXPRESSION_PARSERS
- UNARY_PARSERS
- STRING_PARSERS
- NUMERIC_PARSERS
- PRIMARY_PARSERS
- PLACEHOLDER_PARSERS
- ALTER_ALTER_PARSERS
- NO_PAREN_FUNCTION_PARSERS
- INVALID_FUNC_NAME_TOKENS
- FUNCTIONS_WITH_ALIASED_ARGS
- KEY_VALUE_DEFINITIONS
- QUERY_MODIFIER_PARSERS
- TYPE_LITERAL_PARSERS
- TYPE_CONVERTERS
- DDL_SELECT_TOKENS
- PRE_VOLATILE_TOKENS
- TRANSACTION_KIND
- TRANSACTION_CHARACTERISTICS
- CONFLICT_ACTIONS
- CREATE_SEQUENCE
- ISOLATED_LOADING_OPTIONS
- USABLES
- CAST_ACTIONS
- SCHEMA_BINDING_OPTIONS
- PROCEDURE_OPTIONS
- EXECUTE_AS_OPTIONS
- KEY_CONSTRAINT_OPTIONS
- INSERT_ALTERNATIVES
- CLONE_KEYWORDS
- HISTORICAL_DATA_PREFIX
- HISTORICAL_DATA_KIND
- OPCLASS_FOLLOW_KEYWORDS
- OPTYPE_FOLLOW_TOKENS
- TABLE_INDEX_HINT_TOKENS
- VIEW_ATTRIBUTES
- WINDOW_ALIAS_TOKENS
- WINDOW_BEFORE_PAREN_TOKENS
- WINDOW_SIDES
- JSON_KEY_VALUE_SEPARATOR_TOKENS
- FETCH_TOKENS
- ADD_CONSTRAINT_TOKENS
- DISTINCT_TOKENS
- NULL_TOKENS
- UNNEST_OFFSET_ALIAS_TOKENS
- SELECT_START_TOKENS
- COPY_INTO_VARLEN_OPTIONS
- IS_JSON_PREDICATE_KIND
- ODBC_DATETIME_LITERALS
- ON_CONDITION_TOKENS
- PRIVILEGE_FOLLOW_TOKENS
- DESCRIBE_STYLES
- ANALYZE_STYLES
- ANALYZE_EXPRESSION_PARSERS
- PARTITION_KEYWORDS
- AMBIGUOUS_ALIAS_TOKENS
- STRICT_CAST
- PREFIXED_PIVOT_COLUMNS
- IDENTIFY_PIVOT_STRINGS
- ALTER_TABLE_ADD_REQUIRED_FOR_EACH_COLUMN
- TABLESAMPLE_CSV
- DEFAULT_SAMPLING_METHOD
- SET_REQUIRES_ASSIGNMENT_DELIMITER
- TRIM_PATTERN_FIRST
- MODIFIERS_ATTACHED_TO_SET_OP
- SET_OP_MODIFIERS
- NO_PAREN_IF_COMMANDS
- JSON_ARROWS_REQUIRE_JSON_TYPE
- COLON_IS_VARIANT_EXTRACT
- SUPPORTS_IMPLICIT_UNNEST
- INTERVAL_SPANS
- WRAPPED_TRANSFORM_COLUMN_CONSTRAINT
- OPTIONAL_ALIAS_TOKEN_CTE
- error_level
- error_message_context
- max_errors
- dialect
- reset
- parse
- parse_into
- check_errors
- raise_error
- expression
- validate_expression
- errors
- sql
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: length_or_char_length_sql, 736 exp.LogicalOr: rename_func("MAX"), 737 exp.LogicalAnd: rename_func("MIN"), 738 exp.Max: max_or_greatest, 739 exp.Min: min_or_least, 740 exp.Month: _remove_ts_or_ds_to_date(), 741 exp.NullSafeEQ: lambda self, e: self.binary(e, "<=>"), 742 exp.NullSafeNEQ: lambda self, e: f"NOT {self.binary(e, '<=>')}", 743 exp.NumberToStr: rename_func("FORMAT"), 744 exp.Pivot: no_pivot_sql, 745 exp.Select: transforms.preprocess( 746 [ 747 transforms.eliminate_distinct_on, 748 transforms.eliminate_semi_and_anti_joins, 749 transforms.eliminate_qualify, 750 transforms.eliminate_full_outer_join, 751 transforms.unnest_generate_date_array_using_recursive_cte, 752 ] 753 ), 754 exp.StrPosition: strposition_to_locate_sql, 755 exp.StrToDate: _str_to_date_sql, 756 exp.StrToTime: _str_to_date_sql, 757 exp.Stuff: rename_func("INSERT"), 758 exp.TableSample: no_tablesample_sql, 759 exp.TimeFromParts: rename_func("MAKETIME"), 760 exp.TimestampAdd: date_add_interval_sql("DATE", "ADD"), 761 exp.TimestampDiff: lambda self, e: self.func( 762 "TIMESTAMPDIFF", unit_to_var(e), e.expression, e.this 763 ), 764 exp.TimestampSub: date_add_interval_sql("DATE", "SUB"), 765 exp.TimeStrToUnix: rename_func("UNIX_TIMESTAMP"), 766 exp.TimeStrToTime: lambda self, e: timestrtotime_sql( 767 self, 768 e, 769 include_precision=not e.args.get("zone"), 770 ), 771 exp.TimeToStr: _remove_ts_or_ds_to_date( 772 lambda self, e: self.func("DATE_FORMAT", e.this, self.format_time(e)) 773 ), 774 exp.Trim: trim_sql, 775 exp.TryCast: no_trycast_sql, 776 exp.TsOrDsAdd: date_add_sql("ADD"), 777 exp.TsOrDsDiff: lambda self, e: self.func("DATEDIFF", e.this, e.expression), 778 exp.TsOrDsToDate: _ts_or_ds_to_date_sql, 779 exp.Unicode: lambda self, e: f"ORD(CONVERT({self.sql(e.this)} USING utf32))", 780 exp.UnixToTime: _unix_to_time_sql, 781 exp.Week: _remove_ts_or_ds_to_date(), 782 exp.WeekOfYear: _remove_ts_or_ds_to_date(rename_func("WEEKOFYEAR")), 783 exp.Year: _remove_ts_or_ds_to_date(), 784 } 785 786 UNSIGNED_TYPE_MAPPING = { 787 exp.DataType.Type.UBIGINT: "BIGINT", 788 exp.DataType.Type.UINT: "INT", 789 exp.DataType.Type.UMEDIUMINT: "MEDIUMINT", 790 exp.DataType.Type.USMALLINT: "SMALLINT", 791 exp.DataType.Type.UTINYINT: "TINYINT", 792 exp.DataType.Type.UDECIMAL: "DECIMAL", 793 } 794 795 TIMESTAMP_TYPE_MAPPING = { 796 exp.DataType.Type.DATETIME2: "DATETIME", 797 exp.DataType.Type.SMALLDATETIME: "DATETIME", 798 exp.DataType.Type.TIMESTAMP: "DATETIME", 799 exp.DataType.Type.TIMESTAMPTZ: "TIMESTAMP", 800 exp.DataType.Type.TIMESTAMPLTZ: "TIMESTAMP", 801 } 802 803 TYPE_MAPPING = { 804 **generator.Generator.TYPE_MAPPING, 805 **UNSIGNED_TYPE_MAPPING, 806 **TIMESTAMP_TYPE_MAPPING, 807 } 808 809 TYPE_MAPPING.pop(exp.DataType.Type.MEDIUMTEXT) 810 TYPE_MAPPING.pop(exp.DataType.Type.LONGTEXT) 811 TYPE_MAPPING.pop(exp.DataType.Type.TINYTEXT) 812 TYPE_MAPPING.pop(exp.DataType.Type.MEDIUMBLOB) 813 TYPE_MAPPING.pop(exp.DataType.Type.LONGBLOB) 814 TYPE_MAPPING.pop(exp.DataType.Type.TINYBLOB) 815 816 PROPERTIES_LOCATION = { 817 **generator.Generator.PROPERTIES_LOCATION, 818 exp.TransientProperty: exp.Properties.Location.UNSUPPORTED, 819 exp.VolatileProperty: exp.Properties.Location.UNSUPPORTED, 820 } 821 822 LIMIT_FETCH = "LIMIT" 823 824 LIMIT_ONLY_LITERALS = True 825 826 CHAR_CAST_MAPPING = dict.fromkeys( 827 ( 828 exp.DataType.Type.LONGTEXT, 829 exp.DataType.Type.LONGBLOB, 830 exp.DataType.Type.MEDIUMBLOB, 831 exp.DataType.Type.MEDIUMTEXT, 832 exp.DataType.Type.TEXT, 833 exp.DataType.Type.TINYBLOB, 834 exp.DataType.Type.TINYTEXT, 835 exp.DataType.Type.VARCHAR, 836 ), 837 "CHAR", 838 ) 839 SIGNED_CAST_MAPPING = dict.fromkeys( 840 ( 841 exp.DataType.Type.BIGINT, 842 exp.DataType.Type.BOOLEAN, 843 exp.DataType.Type.INT, 844 exp.DataType.Type.SMALLINT, 845 exp.DataType.Type.TINYINT, 846 exp.DataType.Type.MEDIUMINT, 847 ), 848 "SIGNED", 849 ) 850 851 # MySQL doesn't support many datatypes in cast. 852 # https://dev.mysql.com/doc/refman/8.0/en/cast-functions.html#function_cast 853 CAST_MAPPING = { 854 **CHAR_CAST_MAPPING, 855 **SIGNED_CAST_MAPPING, 856 exp.DataType.Type.UBIGINT: "UNSIGNED", 857 } 858 859 TIMESTAMP_FUNC_TYPES = { 860 exp.DataType.Type.TIMESTAMPTZ, 861 exp.DataType.Type.TIMESTAMPLTZ, 862 } 863 864 # https://dev.mysql.com/doc/refman/8.0/en/keywords.html 865 RESERVED_KEYWORDS = { 866 "accessible", 867 "add", 868 "all", 869 "alter", 870 "analyze", 871 "and", 872 "as", 873 "asc", 874 "asensitive", 875 "before", 876 "between", 877 "bigint", 878 "binary", 879 "blob", 880 "both", 881 "by", 882 "call", 883 "cascade", 884 "case", 885 "change", 886 "char", 887 "character", 888 "check", 889 "collate", 890 "column", 891 "condition", 892 "constraint", 893 "continue", 894 "convert", 895 "create", 896 "cross", 897 "cube", 898 "cume_dist", 899 "current_date", 900 "current_time", 901 "current_timestamp", 902 "current_user", 903 "cursor", 904 "database", 905 "databases", 906 "day_hour", 907 "day_microsecond", 908 "day_minute", 909 "day_second", 910 "dec", 911 "decimal", 912 "declare", 913 "default", 914 "delayed", 915 "delete", 916 "dense_rank", 917 "desc", 918 "describe", 919 "deterministic", 920 "distinct", 921 "distinctrow", 922 "div", 923 "double", 924 "drop", 925 "dual", 926 "each", 927 "else", 928 "elseif", 929 "empty", 930 "enclosed", 931 "escaped", 932 "except", 933 "exists", 934 "exit", 935 "explain", 936 "false", 937 "fetch", 938 "first_value", 939 "float", 940 "float4", 941 "float8", 942 "for", 943 "force", 944 "foreign", 945 "from", 946 "fulltext", 947 "function", 948 "generated", 949 "get", 950 "grant", 951 "group", 952 "grouping", 953 "groups", 954 "having", 955 "high_priority", 956 "hour_microsecond", 957 "hour_minute", 958 "hour_second", 959 "if", 960 "ignore", 961 "in", 962 "index", 963 "infile", 964 "inner", 965 "inout", 966 "insensitive", 967 "insert", 968 "int", 969 "int1", 970 "int2", 971 "int3", 972 "int4", 973 "int8", 974 "integer", 975 "intersect", 976 "interval", 977 "into", 978 "io_after_gtids", 979 "io_before_gtids", 980 "is", 981 "iterate", 982 "join", 983 "json_table", 984 "key", 985 "keys", 986 "kill", 987 "lag", 988 "last_value", 989 "lateral", 990 "lead", 991 "leading", 992 "leave", 993 "left", 994 "like", 995 "limit", 996 "linear", 997 "lines", 998 "load", 999 "localtime", 1000 "localtimestamp", 1001 "lock", 1002 "long", 1003 "longblob", 1004 "longtext", 1005 "loop", 1006 "low_priority", 1007 "master_bind", 1008 "master_ssl_verify_server_cert", 1009 "match", 1010 "maxvalue", 1011 "mediumblob", 1012 "mediumint", 1013 "mediumtext", 1014 "middleint", 1015 "minute_microsecond", 1016 "minute_second", 1017 "mod", 1018 "modifies", 1019 "natural", 1020 "not", 1021 "no_write_to_binlog", 1022 "nth_value", 1023 "ntile", 1024 "null", 1025 "numeric", 1026 "of", 1027 "on", 1028 "optimize", 1029 "optimizer_costs", 1030 "option", 1031 "optionally", 1032 "or", 1033 "order", 1034 "out", 1035 "outer", 1036 "outfile", 1037 "over", 1038 "partition", 1039 "percent_rank", 1040 "precision", 1041 "primary", 1042 "procedure", 1043 "purge", 1044 "range", 1045 "rank", 1046 "read", 1047 "reads", 1048 "read_write", 1049 "real", 1050 "recursive", 1051 "references", 1052 "regexp", 1053 "release", 1054 "rename", 1055 "repeat", 1056 "replace", 1057 "require", 1058 "resignal", 1059 "restrict", 1060 "return", 1061 "revoke", 1062 "right", 1063 "rlike", 1064 "row", 1065 "rows", 1066 "row_number", 1067 "schema", 1068 "schemas", 1069 "second_microsecond", 1070 "select", 1071 "sensitive", 1072 "separator", 1073 "set", 1074 "show", 1075 "signal", 1076 "smallint", 1077 "spatial", 1078 "specific", 1079 "sql", 1080 "sqlexception", 1081 "sqlstate", 1082 "sqlwarning", 1083 "sql_big_result", 1084 "sql_calc_found_rows", 1085 "sql_small_result", 1086 "ssl", 1087 "starting", 1088 "stored", 1089 "straight_join", 1090 "system", 1091 "table", 1092 "terminated", 1093 "then", 1094 "tinyblob", 1095 "tinyint", 1096 "tinytext", 1097 "to", 1098 "trailing", 1099 "trigger", 1100 "true", 1101 "undo", 1102 "union", 1103 "unique", 1104 "unlock", 1105 "unsigned", 1106 "update", 1107 "usage", 1108 "use", 1109 "using", 1110 "utc_date", 1111 "utc_time", 1112 "utc_timestamp", 1113 "values", 1114 "varbinary", 1115 "varchar", 1116 "varcharacter", 1117 "varying", 1118 "virtual", 1119 "when", 1120 "where", 1121 "while", 1122 "window", 1123 "with", 1124 "write", 1125 "xor", 1126 "year_month", 1127 "zerofill", 1128 } 1129 1130 def array_sql(self, expression: exp.Array) -> str: 1131 self.unsupported("Arrays are not supported by MySQL") 1132 return self.function_fallback_sql(expression) 1133 1134 def arraycontainsall_sql(self, expression: exp.ArrayContainsAll) -> str: 1135 self.unsupported("Array operations are not supported by MySQL") 1136 return self.function_fallback_sql(expression) 1137 1138 def dpipe_sql(self, expression: exp.DPipe) -> str: 1139 return self.func("CONCAT", *expression.flatten()) 1140 1141 def extract_sql(self, expression: exp.Extract) -> str: 1142 unit = expression.name 1143 if unit and unit.lower() == "epoch": 1144 return self.func("UNIX_TIMESTAMP", expression.expression) 1145 1146 return super().extract_sql(expression) 1147 1148 def datatype_sql(self, expression: exp.DataType) -> str: 1149 if ( 1150 self.VARCHAR_REQUIRES_SIZE 1151 and expression.is_type(exp.DataType.Type.VARCHAR) 1152 and not expression.expressions 1153 ): 1154 # `VARCHAR` must always have a size - if it doesn't, we always generate `TEXT` 1155 return "TEXT" 1156 1157 # https://dev.mysql.com/doc/refman/8.0/en/numeric-type-syntax.html 1158 result = super().datatype_sql(expression) 1159 if expression.this in self.UNSIGNED_TYPE_MAPPING: 1160 result = f"{result} UNSIGNED" 1161 1162 return result 1163 1164 def jsonarraycontains_sql(self, expression: exp.JSONArrayContains) -> str: 1165 return f"{self.sql(expression, 'this')} MEMBER OF({self.sql(expression, 'expression')})" 1166 1167 def cast_sql(self, expression: exp.Cast, safe_prefix: t.Optional[str] = None) -> str: 1168 if expression.to.this in self.TIMESTAMP_FUNC_TYPES: 1169 return self.func("TIMESTAMP", expression.this) 1170 1171 to = self.CAST_MAPPING.get(expression.to.this) 1172 1173 if to: 1174 expression.to.set("this", to) 1175 return super().cast_sql(expression) 1176 1177 def show_sql(self, expression: exp.Show) -> str: 1178 this = f" {expression.name}" 1179 full = " FULL" if expression.args.get("full") else "" 1180 global_ = " GLOBAL" if expression.args.get("global") else "" 1181 1182 target = self.sql(expression, "target") 1183 target = f" {target}" if target else "" 1184 if expression.name in ("COLUMNS", "INDEX"): 1185 target = f" FROM{target}" 1186 elif expression.name == "GRANTS": 1187 target = f" FOR{target}" 1188 1189 db = self._prefixed_sql("FROM", expression, "db") 1190 1191 like = self._prefixed_sql("LIKE", expression, "like") 1192 where = self.sql(expression, "where") 1193 1194 types = self.expressions(expression, key="types") 1195 types = f" {types}" if types else types 1196 query = self._prefixed_sql("FOR QUERY", expression, "query") 1197 1198 if expression.name == "PROFILE": 1199 offset = self._prefixed_sql("OFFSET", expression, "offset") 1200 limit = self._prefixed_sql("LIMIT", expression, "limit") 1201 else: 1202 offset = "" 1203 limit = self._oldstyle_limit_sql(expression) 1204 1205 log = self._prefixed_sql("IN", expression, "log") 1206 position = self._prefixed_sql("FROM", expression, "position") 1207 1208 channel = self._prefixed_sql("FOR CHANNEL", expression, "channel") 1209 1210 if expression.name == "ENGINE": 1211 mutex_or_status = " MUTEX" if expression.args.get("mutex") else " STATUS" 1212 else: 1213 mutex_or_status = "" 1214 1215 return f"SHOW{full}{global_}{this}{target}{types}{db}{query}{log}{position}{channel}{mutex_or_status}{like}{where}{offset}{limit}" 1216 1217 def altercolumn_sql(self, expression: exp.AlterColumn) -> str: 1218 dtype = self.sql(expression, "dtype") 1219 if not dtype: 1220 return super().altercolumn_sql(expression) 1221 1222 this = self.sql(expression, "this") 1223 return f"MODIFY COLUMN {this} {dtype}" 1224 1225 def _prefixed_sql(self, prefix: str, expression: exp.Expression, arg: str) -> str: 1226 sql = self.sql(expression, arg) 1227 return f" {prefix} {sql}" if sql else "" 1228 1229 def _oldstyle_limit_sql(self, expression: exp.Show) -> str: 1230 limit = self.sql(expression, "limit") 1231 offset = self.sql(expression, "offset") 1232 if limit: 1233 limit_offset = f"{offset}, {limit}" if offset else limit 1234 return f" LIMIT {limit_offset}" 1235 return "" 1236 1237 def chr_sql(self, expression: exp.Chr) -> str: 1238 this = self.expressions(sqls=[expression.this] + expression.expressions) 1239 charset = expression.args.get("charset") 1240 using = f" USING {self.sql(charset)}" if charset else "" 1241 return f"CHAR({this}{using})" 1242 1243 def timestamptrunc_sql(self, expression: exp.TimestampTrunc) -> str: 1244 unit = expression.args.get("unit") 1245 1246 # Pick an old-enough date to avoid negative timestamp diffs 1247 start_ts = "'0000-01-01 00:00:00'" 1248 1249 # Source: https://stackoverflow.com/a/32955740 1250 timestamp_diff = build_date_delta(exp.TimestampDiff)([unit, start_ts, expression.this]) 1251 interval = exp.Interval(this=timestamp_diff, unit=unit) 1252 dateadd = build_date_delta_with_interval(exp.DateAdd)([start_ts, interval]) 1253 1254 return self.sql(dateadd) 1255 1256 def converttimezone_sql(self, expression: exp.ConvertTimezone) -> str: 1257 from_tz = expression.args.get("source_tz") 1258 to_tz = expression.args.get("target_tz") 1259 dt = expression.args.get("timestamp") 1260 1261 return self.func("CONVERT_TZ", dt, from_tz, to_tz) 1262 1263 def attimezone_sql(self, expression: exp.AtTimeZone) -> str: 1264 self.unsupported("AT TIME ZONE is not supported by MySQL") 1265 return self.sql(expression.this) 1266 1267 def isascii_sql(self, expression: exp.IsAscii) -> str: 1268 return f"REGEXP_LIKE({self.sql(expression.this)}, '^[[:ascii:]]*$')"
Generator converts a given syntax tree to the corresponding SQL string.
Arguments:
- pretty: Whether to format the produced SQL string. Default: False.
- identify: Determines when an identifier should be quoted. Possible values are: False (default): Never quote, except in cases where it's mandatory by the dialect. True or 'always': Always quote. 'safe': Only quote identifiers that are case insensitive.
- normalize: Whether to normalize identifiers to lowercase. Default: False.
- pad: The pad size in a formatted string. For example, this affects the indentation of a projection in a query, relative to its nesting level. Default: 2.
- indent: The indentation size in a formatted string. For example, this affects the
indentation of subqueries and filters under a
WHERE
clause. Default: 2. - normalize_functions: How to normalize function names. Possible values are: "upper" or True (default): Convert names to uppercase. "lower": Convert names to lowercase. False: Disables function name normalization.
- unsupported_level: Determines the generator's behavior when it encounters unsupported expressions. Default ErrorLevel.WARN.
- max_unsupported: Maximum number of unsupported messages to include in a raised UnsupportedError. This is only relevant if unsupported_level is ErrorLevel.RAISE. Default: 3
- leading_comma: Whether the comma is leading or trailing in select expressions. This is only relevant when generating in pretty mode. Default: False
- max_text_width: The max number of characters in a segment before creating new lines in pretty mode. The default is on the smaller end because the length only represents a segment and not the true line length. Default: 80
- comments: Whether to preserve comments in the output SQL code. Default: True
TRANSFORMS =
{<class 'sqlglot.expressions.JSONPathFilter'>: <function <lambda>>, <class 'sqlglot.expressions.JSONPathKey'>: <function <lambda>>, <class 'sqlglot.expressions.JSONPathRecursive'>: <function <lambda>>, <class 'sqlglot.expressions.JSONPathRoot'>: <function <lambda>>, <class 'sqlglot.expressions.JSONPathScript'>: <function <lambda>>, <class 'sqlglot.expressions.JSONPathSelector'>: <function <lambda>>, <class 'sqlglot.expressions.JSONPathSlice'>: <function <lambda>>, <class 'sqlglot.expressions.JSONPathSubscript'>: <function <lambda>>, <class 'sqlglot.expressions.JSONPathUnion'>: <function <lambda>>, <class 'sqlglot.expressions.JSONPathWildcard'>: <function <lambda>>, <class 'sqlglot.expressions.AllowedValuesProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.AnalyzeColumns'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.AnalyzeWith'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.ArrayContainsAll'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.ArrayOverlaps'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.AutoRefreshProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.BackupProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.CaseSpecificColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.Ceil'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.CharacterSetColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.CharacterSetProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.ClusteredColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.CollateColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.CommentColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.ConnectByRoot'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.CopyGrantsProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.DateFormatColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.DefaultColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.DynamicProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.EmptyProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.EncodeColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.EphemeralColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.ExcludeColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.ExecuteAsProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.Except'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.ExternalProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.Floor'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.GlobalProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.HeapProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.IcebergProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.InheritsProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.InlineLengthColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.InputModelProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.Intersect'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.IntervalSpan'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.Int64'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.LanguageProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.LocationProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.LogProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.MaterializedProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.NonClusteredColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.NoPrimaryIndexProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.NotForReplicationColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.OnCommitProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.OnProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.OnUpdateColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.Operator'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.OutputModelProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.PathColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.PivotAny'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.ProjectionPolicyColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.RemoteWithConnectionModelProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.ReturnsProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.SampleProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.SecureProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.SecurityProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.SetConfigProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.SetProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.SettingsProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.SharingProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.SqlReadWriteProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.SqlSecurityProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.StabilityProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.Stream'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.StreamingTableProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.StrictProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.SwapTable'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.TemporaryProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.Tags'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.TitleColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.ToMap'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.ToTableProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.TransformModelProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.TransientProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.Union'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.UnloggedProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.UsingData'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.Uuid'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.UppercaseColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.VarMap'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.ViewAttributeProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.VolatileProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.WithJournalTableProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.WithProcedureOptions'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.WithSchemaBindingProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.WithOperator'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.ArrayAgg'>: <function rename_func.<locals>.<lambda>>, <class 'sqlglot.expressions.CurrentDate'>: <function no_paren_current_date_sql>, <class 'sqlglot.expressions.DateDiff'>: <function _remove_ts_or_ds_to_date.<locals>.func>, <class 'sqlglot.expressions.DateAdd'>: <function _remove_ts_or_ds_to_date.<locals>.func>, <class 'sqlglot.expressions.DateStrToDate'>: <function datestrtodate_sql>, <class 'sqlglot.expressions.DateSub'>: <function _remove_ts_or_ds_to_date.<locals>.func>, <class 'sqlglot.expressions.DateTrunc'>: <function _date_trunc_sql>, <class 'sqlglot.expressions.Day'>: <function _remove_ts_or_ds_to_date.<locals>.func>, <class 'sqlglot.expressions.DayOfMonth'>: <function _remove_ts_or_ds_to_date.<locals>.func>, <class 'sqlglot.expressions.DayOfWeek'>: <function _remove_ts_or_ds_to_date.<locals>.func>, <class 'sqlglot.expressions.DayOfYear'>: <function _remove_ts_or_ds_to_date.<locals>.func>, <class 'sqlglot.expressions.GroupConcat'>: <function MySQL.Generator.<lambda>>, <class 'sqlglot.expressions.ILike'>: <function no_ilike_sql>, <class 'sqlglot.expressions.JSONExtractScalar'>: <function arrow_json_extract_sql>, <class 'sqlglot.expressions.Length'>: <function length_or_char_length_sql>, <class 'sqlglot.expressions.LogicalOr'>: <function rename_func.<locals>.<lambda>>, <class 'sqlglot.expressions.LogicalAnd'>: <function rename_func.<locals>.<lambda>>, <class 'sqlglot.expressions.Max'>: <function max_or_greatest>, <class 'sqlglot.expressions.Min'>: <function min_or_least>, <class 'sqlglot.expressions.Month'>: <function _remove_ts_or_ds_to_date.<locals>.func>, <class 'sqlglot.expressions.NullSafeEQ'>: <function MySQL.Generator.<lambda>>, <class 'sqlglot.expressions.NullSafeNEQ'>: <function MySQL.Generator.<lambda>>, <class 'sqlglot.expressions.NumberToStr'>: <function rename_func.<locals>.<lambda>>, <class 'sqlglot.expressions.Pivot'>: <function no_pivot_sql>, <class 'sqlglot.expressions.Select'>: <function preprocess.<locals>._to_sql>, <class 'sqlglot.expressions.StrPosition'>: <function 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.Unicode'>: <function MySQL.Generator.<lambda>>, <class 'sqlglot.expressions.UnixToTime'>: <function _unix_to_time_sql>, <class 'sqlglot.expressions.Week'>: <function _remove_ts_or_ds_to_date.<locals>.func>, <class 'sqlglot.expressions.WeekOfYear'>: <function _remove_ts_or_ds_to_date.<locals>.func>, <class 'sqlglot.expressions.Year'>: <function _remove_ts_or_ds_to_date.<locals>.func>}
UNSIGNED_TYPE_MAPPING =
{<Type.UBIGINT: 'UBIGINT'>: 'BIGINT', <Type.UINT: 'UINT'>: 'INT', <Type.UMEDIUMINT: 'UMEDIUMINT'>: 'MEDIUMINT', <Type.USMALLINT: 'USMALLINT'>: 'SMALLINT', <Type.UTINYINT: 'UTINYINT'>: 'TINYINT', <Type.UDECIMAL: 'UDECIMAL'>: 'DECIMAL'}
TIMESTAMP_TYPE_MAPPING =
{<Type.DATETIME2: 'DATETIME2'>: 'DATETIME', <Type.SMALLDATETIME: 'SMALLDATETIME'>: 'DATETIME', <Type.TIMESTAMP: 'TIMESTAMP'>: 'DATETIME', <Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>: 'TIMESTAMP', <Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>: 'TIMESTAMP'}
TYPE_MAPPING =
{<Type.DATETIME2: 'DATETIME2'>: 'DATETIME', <Type.NCHAR: 'NCHAR'>: 'CHAR', <Type.NVARCHAR: 'NVARCHAR'>: 'VARCHAR', <Type.INET: 'INET'>: 'INET', <Type.ROWVERSION: 'ROWVERSION'>: 'VARBINARY', <Type.SMALLDATETIME: 'SMALLDATETIME'>: 'DATETIME', <Type.UBIGINT: 'UBIGINT'>: 'BIGINT', <Type.UINT: 'UINT'>: 'INT', <Type.UMEDIUMINT: 'UMEDIUMINT'>: 'MEDIUMINT', <Type.USMALLINT: 'USMALLINT'>: 'SMALLINT', <Type.UTINYINT: 'UTINYINT'>: 'TINYINT', <Type.UDECIMAL: 'UDECIMAL'>: 'DECIMAL', <Type.TIMESTAMP: 'TIMESTAMP'>: 'DATETIME', <Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>: 'TIMESTAMP', <Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>: 'TIMESTAMP'}
PROPERTIES_LOCATION =
{<class 'sqlglot.expressions.AllowedValuesProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.AlgorithmProperty'>: <Location.POST_CREATE: 'POST_CREATE'>, <class 'sqlglot.expressions.AutoIncrementProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.AutoRefreshProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.BackupProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.BlockCompressionProperty'>: <Location.POST_NAME: 'POST_NAME'>, <class 'sqlglot.expressions.CharacterSetProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.ChecksumProperty'>: <Location.POST_NAME: 'POST_NAME'>, <class 'sqlglot.expressions.CollateProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.CopyGrantsProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.Cluster'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.ClusteredByProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.DistributedByProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.DuplicateKeyProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.DataBlocksizeProperty'>: <Location.POST_NAME: 'POST_NAME'>, <class 'sqlglot.expressions.DataDeletionProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.DefinerProperty'>: <Location.POST_CREATE: 'POST_CREATE'>, <class 'sqlglot.expressions.DictRange'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.DictProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.DynamicProperty'>: <Location.POST_CREATE: 'POST_CREATE'>, <class 'sqlglot.expressions.DistKeyProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.DistStyleProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.EmptyProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.EncodeProperty'>: <Location.POST_EXPRESSION: 'POST_EXPRESSION'>, <class 'sqlglot.expressions.EngineProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.ExecuteAsProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.ExternalProperty'>: <Location.POST_CREATE: 'POST_CREATE'>, <class 'sqlglot.expressions.FallbackProperty'>: <Location.POST_NAME: 'POST_NAME'>, <class 'sqlglot.expressions.FileFormatProperty'>: <Location.POST_WITH: 'POST_WITH'>, <class 'sqlglot.expressions.FreespaceProperty'>: <Location.POST_NAME: 'POST_NAME'>, <class 'sqlglot.expressions.GlobalProperty'>: <Location.POST_CREATE: 'POST_CREATE'>, <class 'sqlglot.expressions.HeapProperty'>: <Location.POST_WITH: 'POST_WITH'>, <class 'sqlglot.expressions.InheritsProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.IcebergProperty'>: <Location.POST_CREATE: 'POST_CREATE'>, <class 'sqlglot.expressions.IncludeProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.InputModelProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.IsolatedLoadingProperty'>: <Location.POST_NAME: 'POST_NAME'>, <class 'sqlglot.expressions.JournalProperty'>: <Location.POST_NAME: 'POST_NAME'>, <class 'sqlglot.expressions.LanguageProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.LikeProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.LocationProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.LockProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.LockingProperty'>: <Location.POST_ALIAS: 'POST_ALIAS'>, <class 'sqlglot.expressions.LogProperty'>: <Location.POST_NAME: 'POST_NAME'>, <class 'sqlglot.expressions.MaterializedProperty'>: <Location.POST_CREATE: 'POST_CREATE'>, <class 'sqlglot.expressions.MergeBlockRatioProperty'>: <Location.POST_NAME: 'POST_NAME'>, <class 'sqlglot.expressions.NoPrimaryIndexProperty'>: <Location.POST_EXPRESSION: 'POST_EXPRESSION'>, <class 'sqlglot.expressions.OnProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.OnCommitProperty'>: <Location.POST_EXPRESSION: 'POST_EXPRESSION'>, <class 'sqlglot.expressions.Order'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.OutputModelProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.PartitionedByProperty'>: <Location.POST_WITH: 'POST_WITH'>, <class 'sqlglot.expressions.PartitionedOfProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.PrimaryKey'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.Property'>: <Location.POST_WITH: 'POST_WITH'>, <class 'sqlglot.expressions.RemoteWithConnectionModelProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.ReturnsProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.RowFormatProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.RowFormatDelimitedProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.RowFormatSerdeProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.SampleProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.SchemaCommentProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.SecureProperty'>: <Location.POST_CREATE: 'POST_CREATE'>, <class 'sqlglot.expressions.SecurityProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.SerdeProperties'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.Set'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.SettingsProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.SetProperty'>: <Location.POST_CREATE: 'POST_CREATE'>, <class 'sqlglot.expressions.SetConfigProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.SharingProperty'>: <Location.POST_EXPRESSION: 'POST_EXPRESSION'>, <class 'sqlglot.expressions.SequenceProperties'>: <Location.POST_EXPRESSION: 'POST_EXPRESSION'>, <class 'sqlglot.expressions.SortKeyProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.SqlReadWriteProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.SqlSecurityProperty'>: <Location.POST_CREATE: 'POST_CREATE'>, <class 'sqlglot.expressions.StabilityProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.StreamingTableProperty'>: <Location.POST_CREATE: 'POST_CREATE'>, <class 'sqlglot.expressions.StrictProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.Tags'>: <Location.POST_WITH: 'POST_WITH'>, <class 'sqlglot.expressions.TemporaryProperty'>: <Location.POST_CREATE: 'POST_CREATE'>, <class 'sqlglot.expressions.ToTableProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.TransientProperty'>: <Location.UNSUPPORTED: 'UNSUPPORTED'>, <class 'sqlglot.expressions.TransformModelProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.MergeTreeTTL'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.UnloggedProperty'>: <Location.POST_CREATE: 'POST_CREATE'>, <class 'sqlglot.expressions.ViewAttributeProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.VolatileProperty'>: <Location.UNSUPPORTED: 'UNSUPPORTED'>, <class 'sqlglot.expressions.WithDataProperty'>: <Location.POST_EXPRESSION: 'POST_EXPRESSION'>, <class 'sqlglot.expressions.WithJournalTableProperty'>: <Location.POST_NAME: 'POST_NAME'>, <class 'sqlglot.expressions.WithProcedureOptions'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.WithSchemaBindingProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.WithSystemVersioningProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>}
CHAR_CAST_MAPPING =
{<Type.LONGTEXT: 'LONGTEXT'>: 'CHAR', <Type.LONGBLOB: 'LONGBLOB'>: 'CHAR', <Type.MEDIUMBLOB: 'MEDIUMBLOB'>: 'CHAR', <Type.MEDIUMTEXT: 'MEDIUMTEXT'>: 'CHAR', <Type.TEXT: 'TEXT'>: 'CHAR', <Type.TINYBLOB: 'TINYBLOB'>: 'CHAR', <Type.TINYTEXT: 'TINYTEXT'>: 'CHAR', <Type.VARCHAR: 'VARCHAR'>: 'CHAR'}
SIGNED_CAST_MAPPING =
{<Type.BIGINT: 'BIGINT'>: 'SIGNED', <Type.BOOLEAN: 'BOOLEAN'>: 'SIGNED', <Type.INT: 'INT'>: 'SIGNED', <Type.SMALLINT: 'SMALLINT'>: 'SIGNED', <Type.TINYINT: 'TINYINT'>: 'SIGNED', <Type.MEDIUMINT: 'MEDIUMINT'>: 'SIGNED'}
CAST_MAPPING =
{<Type.LONGTEXT: 'LONGTEXT'>: 'CHAR', <Type.LONGBLOB: 'LONGBLOB'>: 'CHAR', <Type.MEDIUMBLOB: 'MEDIUMBLOB'>: 'CHAR', <Type.MEDIUMTEXT: 'MEDIUMTEXT'>: 'CHAR', <Type.TEXT: 'TEXT'>: 'CHAR', <Type.TINYBLOB: 'TINYBLOB'>: 'CHAR', <Type.TINYTEXT: 'TINYTEXT'>: 'CHAR', <Type.VARCHAR: 'VARCHAR'>: 'CHAR', <Type.BIGINT: 'BIGINT'>: 'SIGNED', <Type.BOOLEAN: 'BOOLEAN'>: 'SIGNED', <Type.INT: 'INT'>: 'SIGNED', <Type.SMALLINT: 'SMALLINT'>: 'SIGNED', <Type.TINYINT: 'TINYINT'>: 'SIGNED', <Type.MEDIUMINT: 'MEDIUMINT'>: 'SIGNED', <Type.UBIGINT: 'UBIGINT'>: 'UNSIGNED'}
RESERVED_KEYWORDS =
{'database', 'lateral', 'real', 'not', 'of', 'varbinary', 'databases', 'schemas', 'long', 'rank', 'into', 'stored', 'references', 'continue', 'maxvalue', 'nth_value', 'rlike', 'integer', 'row_number', 'separator', 'with', 'and', 'accessible', 'cascade', 'then', 'for', 'numeric', 'dual', 'match', 'release', 'minute_microsecond', 'rename', 'declare', 'ssl', 'group', 'leave', 'undo', 'last_value', 'day_microsecond', 'interval', 'out', 'partition', 'while', 'varying', 'sqlexception', 'groups', 'primary', 'utc_date', 'describe', 'require', 'case', 'dec', 'constraint', 'kill', 'over', 'all', 'outer', 'limit', 'collate', 'mediumint', 'read_write', 'specific', 'sql_small_result', 'on', 'desc', 'lag', 'json_table', 'xor', 'decimal', 'explain', 'sqlwarning', 'cursor', 'write', 'from', 'procedure', 'revoke', 'distinctrow', 'smallint', 'in', 'order', 'sql_calc_found_rows', 'mediumtext', 'distinct', 'window', 'lines', 'double', 'reads', 'leading', 'longtext', 'key', 'default', 'mod', 'system', 'unique', 'before', 'grant', 'fulltext', 'elseif', 'left', 'year_month', 'middleint', 'low_priority', 'int2', 'schema', 'signal', 'hour_second', 'set', 'div', 'tinyblob', 'repeat', 'optionally', 'exists', 'empty', 'resignal', 'day_minute', 'delayed', 'change', 'each', 'iterate', 'between', 'index', 'utc_timestamp', 'no_write_to_binlog', 'read', 'sqlstate', 'use', 'current_timestamp', 'column', 'delete', 'loop', 'trailing', 'fetch', 'high_priority', 'values', 'utc_time', 'by', 'regexp', 'inout', 'cube', 'grouping', 'asc', 'is', 'lock', 'return', 'if', 'linear', 'unsigned', 'blob', 'float8', 'cume_dist', 'call', 'current_time', 'second_microsecond', 'select', 'localtime', 'varchar', 'binary', 'ntile', 'keys', 'int', 'virtual', 'precision', 'mediumblob', 'zerofill', 'current_date', 'get', 'sql', 'true', 'lead', 'dense_rank', 'rows', 'drop', 'deterministic', 'trigger', 'current_user', 'sensitive', 'alter', 'foreign', 'master_ssl_verify_server_cert', 'right', 'localtimestamp', 'insert', 'spatial', 'range', 'as', 'replace', 'row', 'hour_microsecond', 'restrict', 'sql_big_result', 'unlock', 'float', 'straight_join', 'enclosed', 'percent_rank', 'first_value', 'terminated', 'convert', 'when', 'exit', 'create', 'bigint', 'hour_minute', 'varcharacter', 'force', 'both', 'character', 'join', 'master_bind', 'check', 'to', 'minute_second', 'infile', 'like', 'float4', 'intersect', 'outfile', 'except', 'condition', 'int8', 'insensitive', 'tinytext', 'char', 'asensitive', 'modifies', 'inner', 'int1', 'generated', 'recursive', 'having', 'day_hour', 'function', 'optimizer_costs', 'tinyint', 'escaped', 'null', 'union', 'starting', 'io_after_gtids', 'add', 'natural', 'longblob', 'ignore', 'false', 'analyze', 'purge', 'usage', 'int3', 'update', 'table', 'optimize', 'option', 'where', 'day_second', 'io_before_gtids', 'else', 'cross', 'load', 'int4', 'using', 'show', 'or'}
1148 def datatype_sql(self, expression: exp.DataType) -> str: 1149 if ( 1150 self.VARCHAR_REQUIRES_SIZE 1151 and expression.is_type(exp.DataType.Type.VARCHAR) 1152 and not expression.expressions 1153 ): 1154 # `VARCHAR` must always have a size - if it doesn't, we always generate `TEXT` 1155 return "TEXT" 1156 1157 # https://dev.mysql.com/doc/refman/8.0/en/numeric-type-syntax.html 1158 result = super().datatype_sql(expression) 1159 if expression.this in self.UNSIGNED_TYPE_MAPPING: 1160 result = f"{result} UNSIGNED" 1161 1162 return result
def
cast_sql( self, expression: sqlglot.expressions.Cast, safe_prefix: Optional[str] = None) -> str:
1167 def cast_sql(self, expression: exp.Cast, safe_prefix: t.Optional[str] = None) -> str: 1168 if expression.to.this in self.TIMESTAMP_FUNC_TYPES: 1169 return self.func("TIMESTAMP", expression.this) 1170 1171 to = self.CAST_MAPPING.get(expression.to.this) 1172 1173 if to: 1174 expression.to.set("this", to) 1175 return super().cast_sql(expression)
1177 def show_sql(self, expression: exp.Show) -> str: 1178 this = f" {expression.name}" 1179 full = " FULL" if expression.args.get("full") else "" 1180 global_ = " GLOBAL" if expression.args.get("global") else "" 1181 1182 target = self.sql(expression, "target") 1183 target = f" {target}" if target else "" 1184 if expression.name in ("COLUMNS", "INDEX"): 1185 target = f" FROM{target}" 1186 elif expression.name == "GRANTS": 1187 target = f" FOR{target}" 1188 1189 db = self._prefixed_sql("FROM", expression, "db") 1190 1191 like = self._prefixed_sql("LIKE", expression, "like") 1192 where = self.sql(expression, "where") 1193 1194 types = self.expressions(expression, key="types") 1195 types = f" {types}" if types else types 1196 query = self._prefixed_sql("FOR QUERY", expression, "query") 1197 1198 if expression.name == "PROFILE": 1199 offset = self._prefixed_sql("OFFSET", expression, "offset") 1200 limit = self._prefixed_sql("LIMIT", expression, "limit") 1201 else: 1202 offset = "" 1203 limit = self._oldstyle_limit_sql(expression) 1204 1205 log = self._prefixed_sql("IN", expression, "log") 1206 position = self._prefixed_sql("FROM", expression, "position") 1207 1208 channel = self._prefixed_sql("FOR CHANNEL", expression, "channel") 1209 1210 if expression.name == "ENGINE": 1211 mutex_or_status = " MUTEX" if expression.args.get("mutex") else " STATUS" 1212 else: 1213 mutex_or_status = "" 1214 1215 return f"SHOW{full}{global_}{this}{target}{types}{db}{query}{log}{position}{channel}{mutex_or_status}{like}{where}{offset}{limit}"
1243 def timestamptrunc_sql(self, expression: exp.TimestampTrunc) -> str: 1244 unit = expression.args.get("unit") 1245 1246 # Pick an old-enough date to avoid negative timestamp diffs 1247 start_ts = "'0000-01-01 00:00:00'" 1248 1249 # Source: https://stackoverflow.com/a/32955740 1250 timestamp_diff = build_date_delta(exp.TimestampDiff)([unit, start_ts, expression.this]) 1251 interval = exp.Interval(this=timestamp_diff, unit=unit) 1252 dateadd = build_date_delta_with_interval(exp.DateAdd)([start_ts, interval]) 1253 1254 return self.sql(dateadd)
AFTER_HAVING_MODIFIER_TRANSFORMS =
{'windows': <function Generator.<lambda>>, 'qualify': <function Generator.<lambda>>}
Inherited Members
- sqlglot.generator.Generator
- Generator
- IGNORE_NULLS_IN_FUNC
- EXCEPT_INTERSECT_SUPPORT_ALL_CLAUSE
- CREATE_FUNCTION_RETURN_AS
- MATCHED_BY_SOURCE
- SINGLE_STRING_INTERVAL
- RENAME_TABLE_WITH_DB
- GROUPINGS_SEP
- INDEX_ON
- QUERY_HINTS
- IS_BOOL_ALLOWED
- LIMIT_IS_TOP
- RETURNING_END
- EXTRACT_ALLOWS_QUOTES
- TZ_TO_WITH_TIME_ZONE
- ALTER_TABLE_INCLUDE_COLUMN_KEYWORD
- UNNEST_WITH_ORDINALITY
- AGGREGATE_FILTER_SUPPORTED
- SEMI_ANTI_JOIN_WITH_SIDE
- COMPUTED_COLUMN_WITH_TYPE
- SUPPORTS_TABLE_COPY
- TABLESAMPLE_REQUIRES_PARENS
- TABLESAMPLE_SIZE_IS_ROWS
- TABLESAMPLE_KEYWORDS
- TABLESAMPLE_WITH_METHOD
- TABLESAMPLE_SEED_KEYWORD
- COLLATE_IS_FUNC
- DATA_TYPE_SPECIFIERS_ALLOWED
- ENSURE_BOOLS
- CTE_RECURSIVE_KEYWORD_REQUIRED
- SUPPORTS_SINGLE_ARG_CONCAT
- SUPPORTS_TABLE_ALIAS_COLUMNS
- UNPIVOT_ALIASES_ARE_IDENTIFIERS
- INSERT_OVERWRITE
- SUPPORTS_SELECT_INTO
- SUPPORTS_UNLOGGED_TABLES
- SUPPORTS_CREATE_TABLE_LIKE
- LIKE_PROPERTY_INSIDE_SCHEMA
- MULTI_ARG_DISTINCT
- JSON_PATH_SINGLE_QUOTE_ESCAPE
- SUPPORTED_JSON_PATH_PARTS
- CAN_IMPLEMENT_ARRAY_ANY
- SET_OP_MODIFIERS
- COPY_PARAMS_ARE_WRAPPED
- COPY_PARAMS_EQ_REQUIRED
- COPY_HAS_INTO_KEYWORD
- STAR_EXCEPT
- HEX_FUNC
- WITH_PROPERTIES_PREFIX
- QUOTE_JSON_PATH
- SUPPORTS_EXPLODING_PROJECTIONS
- ARRAY_CONCAT_IS_VAR_LEN
- SUPPORTS_CONVERT_TIMEZONE
- SUPPORTS_UNIX_SECONDS
- ARRAY_SIZE_NAME
- ARRAY_SIZE_DIM_REQUIRED
- TIME_PART_SINGULARS
- TOKEN_MAPPING
- STRUCT_DELIMITER
- PARAMETER_TOKEN
- NAMED_PLACEHOLDER_TOKEN
- EXPRESSION_PRECEDES_PROPERTIES_CREATABLES
- WITH_SEPARATED_COMMENTS
- EXCLUDE_COMMENTS
- UNWRAPPED_INTERVAL_VALUES
- PARAMETERIZABLE_TEXT_TYPES
- EXPRESSIONS_WITHOUT_NESTED_CTES
- SENTINEL_LINE_BREAK
- pretty
- identify
- normalize
- pad
- unsupported_level
- max_unsupported
- leading_comma
- max_text_width
- comments
- dialect
- normalize_functions
- unsupported_messages
- generate
- preprocess
- unsupported
- sep
- seg
- pad_comment
- maybe_comment
- wrap
- no_identify
- normalize_func
- indent
- sql
- uncache_sql
- cache_sql
- characterset_sql
- column_parts
- column_sql
- columnposition_sql
- columndef_sql
- columnconstraint_sql
- computedcolumnconstraint_sql
- autoincrementcolumnconstraint_sql
- compresscolumnconstraint_sql
- generatedasidentitycolumnconstraint_sql
- generatedasrowcolumnconstraint_sql
- periodforsystemtimeconstraint_sql
- notnullcolumnconstraint_sql
- transformcolumnconstraint_sql
- primarykeycolumnconstraint_sql
- uniquecolumnconstraint_sql
- createable_sql
- create_sql
- sequenceproperties_sql
- clone_sql
- describe_sql
- heredoc_sql
- prepend_ctes
- with_sql
- cte_sql
- tablealias_sql
- bitstring_sql
- hexstring_sql
- bytestring_sql
- unicodestring_sql
- rawstring_sql
- datatypeparam_sql
- directory_sql
- delete_sql
- drop_sql
- set_operation
- set_operations
- fetch_sql
- filter_sql
- hint_sql
- indexparameters_sql
- index_sql
- identifier_sql
- hex_sql
- lowerhex_sql
- inputoutputformat_sql
- national_sql
- partition_sql
- properties_sql
- root_properties
- properties
- with_properties
- locate_properties
- property_name
- property_sql
- likeproperty_sql
- fallbackproperty_sql
- journalproperty_sql
- freespaceproperty_sql
- checksumproperty_sql
- mergeblockratioproperty_sql
- datablocksizeproperty_sql
- blockcompressionproperty_sql
- isolatedloadingproperty_sql
- partitionboundspec_sql
- partitionedofproperty_sql
- lockingproperty_sql
- withdataproperty_sql
- withsystemversioningproperty_sql
- insert_sql
- introducer_sql
- kill_sql
- pseudotype_sql
- objectidentifier_sql
- onconflict_sql
- returning_sql
- rowformatdelimitedproperty_sql
- withtablehint_sql
- indextablehint_sql
- historicaldata_sql
- table_parts
- table_sql
- tablesample_sql
- pivot_sql
- version_sql
- tuple_sql
- update_sql
- values_sql
- var_sql
- into_sql
- from_sql
- groupingsets_sql
- rollup_sql
- cube_sql
- group_sql
- having_sql
- connect_sql
- prior_sql
- join_sql
- lambda_sql
- lateral_op
- lateral_sql
- limit_sql
- offset_sql
- setitem_sql
- set_sql
- pragma_sql
- lock_sql
- literal_sql
- escape_str
- loaddata_sql
- null_sql
- boolean_sql
- order_sql
- withfill_sql
- cluster_sql
- distribute_sql
- sort_sql
- ordered_sql
- matchrecognizemeasure_sql
- matchrecognize_sql
- query_modifiers
- options_modifier
- queryoption_sql
- offset_limit_modifiers
- after_limit_modifiers
- select_sql
- schema_sql
- schema_columns_sql
- star_sql
- parameter_sql
- sessionparameter_sql
- placeholder_sql
- subquery_sql
- qualify_sql
- unnest_sql
- prewhere_sql
- where_sql
- window_sql
- partition_by_sql
- windowspec_sql
- withingroup_sql
- between_sql
- bracket_offset_expressions
- bracket_sql
- all_sql
- any_sql
- exists_sql
- case_sql
- constraint_sql
- nextvaluefor_sql
- trim_sql
- convert_concat_args
- concat_sql
- concatws_sql
- check_sql
- foreignkey_sql
- primarykey_sql
- if_sql
- matchagainst_sql
- jsonkeyvalue_sql
- jsonpath_sql
- json_path_part
- formatjson_sql
- jsonobject_sql
- jsonobjectagg_sql
- jsonarray_sql
- jsonarrayagg_sql
- jsoncolumndef_sql
- jsonschema_sql
- jsontable_sql
- openjsoncolumndef_sql
- openjson_sql
- in_sql
- in_unnest_op
- interval_sql
- return_sql
- reference_sql
- anonymous_sql
- paren_sql
- neg_sql
- not_sql
- alias_sql
- pivotalias_sql
- aliases_sql
- atindex_sql
- fromtimezone_sql
- add_sql
- and_sql
- or_sql
- xor_sql
- connector_sql
- bitwiseand_sql
- bitwiseleftshift_sql
- bitwisenot_sql
- bitwiseor_sql
- bitwiserightshift_sql
- bitwisexor_sql
- currentdate_sql
- collate_sql
- command_sql
- comment_sql
- mergetreettlaction_sql
- mergetreettl_sql
- transaction_sql
- commit_sql
- rollback_sql
- alterdiststyle_sql
- altersortkey_sql
- alterrename_sql
- renamecolumn_sql
- alterset_sql
- alter_sql
- add_column_sql
- droppartition_sql
- addconstraint_sql
- distinct_sql
- ignorenulls_sql
- respectnulls_sql
- havingmax_sql
- intdiv_sql
- div_sql
- overlaps_sql
- distance_sql
- dot_sql
- eq_sql
- propertyeq_sql
- escape_sql
- glob_sql
- gt_sql
- gte_sql
- ilike_sql
- ilikeany_sql
- is_sql
- like_sql
- likeany_sql
- similarto_sql
- lt_sql
- lte_sql
- mod_sql
- mul_sql
- neq_sql
- nullsafeeq_sql
- nullsafeneq_sql
- slice_sql
- sub_sql
- trycast_sql
- try_sql
- log_sql
- use_sql
- binary
- ceil_floor
- function_fallback_sql
- func
- format_args
- too_wide
- format_time
- expressions
- op_expressions
- naked_property
- tag_sql
- token_sql
- userdefinedfunction_sql
- joinhint_sql
- kwarg_sql
- when_sql
- whens_sql
- merge_sql
- tochar_sql
- tonumber_sql
- dictproperty_sql
- dictrange_sql
- dictsubproperty_sql
- duplicatekeyproperty_sql
- uniquekeyproperty_sql
- distributedbyproperty_sql
- oncluster_sql
- clusteredbyproperty_sql
- anyvalue_sql
- querytransform_sql
- indexconstraintoption_sql
- checkcolumnconstraint_sql
- indexcolumnconstraint_sql
- nvl2_sql
- comprehension_sql
- columnprefix_sql
- opclass_sql
- predict_sql
- forin_sql
- refresh_sql
- toarray_sql
- tsordstotime_sql
- tsordstotimestamp_sql
- tsordstodatetime_sql
- tsordstodate_sql
- unixdate_sql
- lastday_sql
- dateadd_sql
- arrayany_sql
- struct_sql
- partitionrange_sql
- truncatetable_sql
- convert_sql
- copyparameter_sql
- credentials_sql
- copy_sql
- semicolon_sql
- datadeletionproperty_sql
- maskingpolicycolumnconstraint_sql
- gapfill_sql
- scope_resolution
- scoperesolution_sql
- parsejson_sql
- rand_sql
- changes_sql
- pad_sql
- summarize_sql
- explodinggenerateseries_sql
- arrayconcat_sql
- json_sql
- jsonvalue_sql
- conditionalinsert_sql
- multitableinserts_sql
- oncondition_sql
- jsonexists_sql
- arrayagg_sql
- apply_sql
- grant_sql
- grantprivilege_sql
- grantprincipal_sql
- columns_sql
- overlay_sql
- todouble_sql
- string_sql
- median_sql
- overflowtruncatebehavior_sql
- unixseconds_sql
- arraysize_sql
- attach_sql
- detach_sql
- attachoption_sql
- featuresattime_sql
- watermarkcolumnconstraint_sql
- encodeproperty_sql
- includeproperty_sql
- xmlelement_sql
- partitionbyrangeproperty_sql
- partitionbyrangepropertydynamic_sql
- unpivotcolumns_sql
- analyzesample_sql
- analyzestatistics_sql
- analyzehistogram_sql
- analyzedelete_sql
- analyzelistchainedrows_sql
- analyzevalidate_sql
- analyze_sql
- xmltable_sql