sqlglot.dialects.mysql
1from __future__ import annotations 2 3import typing as t 4 5from sqlglot import exp, generator, parser, tokens, transforms 6from sqlglot.dialects.dialect import ( 7 Dialect, 8 NormalizationStrategy, 9 arrow_json_extract_sql, 10 date_add_interval_sql, 11 datestrtodate_sql, 12 build_formatted_time, 13 isnull_to_is_null, 14 length_or_char_length_sql, 15 max_or_greatest, 16 min_or_least, 17 no_ilike_sql, 18 no_paren_current_date_sql, 19 no_pivot_sql, 20 no_tablesample_sql, 21 no_trycast_sql, 22 build_date_delta, 23 build_date_delta_with_interval, 24 rename_func, 25 strposition_sql, 26 unit_to_var, 27 trim_sql, 28 timestrtotime_sql, 29) 30from sqlglot.generator import unsupported_args 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 "BLOB": TokenType.BLOB, 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 "CURDATE": exp.CurrentDate.from_arg_list, 304 "DATE": lambda args: exp.TsOrDsToDate(this=seq_get(args, 0)), 305 "DATE_ADD": build_date_delta_with_interval(exp.DateAdd), 306 "DATE_FORMAT": build_formatted_time(exp.TimeToStr, "mysql"), 307 "DATE_SUB": build_date_delta_with_interval(exp.DateSub), 308 "DAY": lambda args: exp.Day(this=exp.TsOrDsToDate(this=seq_get(args, 0))), 309 "DAYOFMONTH": lambda args: exp.DayOfMonth(this=exp.TsOrDsToDate(this=seq_get(args, 0))), 310 "DAYOFWEEK": lambda args: exp.DayOfWeek(this=exp.TsOrDsToDate(this=seq_get(args, 0))), 311 "DAYOFYEAR": lambda args: exp.DayOfYear(this=exp.TsOrDsToDate(this=seq_get(args, 0))), 312 "FORMAT": exp.NumberToStr.from_arg_list, 313 "FROM_UNIXTIME": build_formatted_time(exp.UnixToTime, "mysql"), 314 "ISNULL": isnull_to_is_null, 315 "LENGTH": lambda args: exp.Length(this=seq_get(args, 0), binary=True), 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 "SCHEMA": exp.CurrentSchema.from_arg_list, 323 "DATABASE": exp.CurrentSchema.from_arg_list, 324 "STR_TO_DATE": _str_to_date, 325 "TIMESTAMPDIFF": build_date_delta(exp.TimestampDiff), 326 "TO_DAYS": lambda args: exp.paren( 327 exp.DateDiff( 328 this=exp.TsOrDsToDate(this=seq_get(args, 0)), 329 expression=exp.TsOrDsToDate(this=exp.Literal.string("0000-01-01")), 330 unit=exp.var("DAY"), 331 ) 332 + 1 333 ), 334 "WEEK": lambda args: exp.Week( 335 this=exp.TsOrDsToDate(this=seq_get(args, 0)), mode=seq_get(args, 1) 336 ), 337 "WEEKOFYEAR": lambda args: exp.WeekOfYear(this=exp.TsOrDsToDate(this=seq_get(args, 0))), 338 "YEAR": lambda args: exp.Year(this=exp.TsOrDsToDate(this=seq_get(args, 0))), 339 } 340 341 FUNCTION_PARSERS = { 342 **parser.Parser.FUNCTION_PARSERS, 343 "CHAR": lambda self: self.expression( 344 exp.Chr, 345 expressions=self._parse_csv(self._parse_assignment), 346 charset=self._match(TokenType.USING) and self._parse_var(), 347 ), 348 "GROUP_CONCAT": lambda self: self._parse_group_concat(), 349 # https://dev.mysql.com/doc/refman/5.7/en/miscellaneous-functions.html#function_values 350 "VALUES": lambda self: self.expression( 351 exp.Anonymous, this="VALUES", expressions=[self._parse_id_var()] 352 ), 353 "JSON_VALUE": lambda self: self._parse_json_value(), 354 } 355 356 STATEMENT_PARSERS = { 357 **parser.Parser.STATEMENT_PARSERS, 358 TokenType.SHOW: lambda self: self._parse_show(), 359 } 360 361 SHOW_PARSERS = { 362 "BINARY LOGS": _show_parser("BINARY LOGS"), 363 "MASTER LOGS": _show_parser("BINARY LOGS"), 364 "BINLOG EVENTS": _show_parser("BINLOG EVENTS"), 365 "CHARACTER SET": _show_parser("CHARACTER SET"), 366 "CHARSET": _show_parser("CHARACTER SET"), 367 "COLLATION": _show_parser("COLLATION"), 368 "FULL COLUMNS": _show_parser("COLUMNS", target="FROM", full=True), 369 "COLUMNS": _show_parser("COLUMNS", target="FROM"), 370 "CREATE DATABASE": _show_parser("CREATE DATABASE", target=True), 371 "CREATE EVENT": _show_parser("CREATE EVENT", target=True), 372 "CREATE FUNCTION": _show_parser("CREATE FUNCTION", target=True), 373 "CREATE PROCEDURE": _show_parser("CREATE PROCEDURE", target=True), 374 "CREATE TABLE": _show_parser("CREATE TABLE", target=True), 375 "CREATE TRIGGER": _show_parser("CREATE TRIGGER", target=True), 376 "CREATE VIEW": _show_parser("CREATE VIEW", target=True), 377 "DATABASES": _show_parser("DATABASES"), 378 "SCHEMAS": _show_parser("DATABASES"), 379 "ENGINE": _show_parser("ENGINE", target=True), 380 "STORAGE ENGINES": _show_parser("ENGINES"), 381 "ENGINES": _show_parser("ENGINES"), 382 "ERRORS": _show_parser("ERRORS"), 383 "EVENTS": _show_parser("EVENTS"), 384 "FUNCTION CODE": _show_parser("FUNCTION CODE", target=True), 385 "FUNCTION STATUS": _show_parser("FUNCTION STATUS"), 386 "GRANTS": _show_parser("GRANTS", target="FOR"), 387 "INDEX": _show_parser("INDEX", target="FROM"), 388 "MASTER STATUS": _show_parser("MASTER STATUS"), 389 "OPEN TABLES": _show_parser("OPEN TABLES"), 390 "PLUGINS": _show_parser("PLUGINS"), 391 "PROCEDURE CODE": _show_parser("PROCEDURE CODE", target=True), 392 "PROCEDURE STATUS": _show_parser("PROCEDURE STATUS"), 393 "PRIVILEGES": _show_parser("PRIVILEGES"), 394 "FULL PROCESSLIST": _show_parser("PROCESSLIST", full=True), 395 "PROCESSLIST": _show_parser("PROCESSLIST"), 396 "PROFILE": _show_parser("PROFILE"), 397 "PROFILES": _show_parser("PROFILES"), 398 "RELAYLOG EVENTS": _show_parser("RELAYLOG EVENTS"), 399 "REPLICAS": _show_parser("REPLICAS"), 400 "SLAVE HOSTS": _show_parser("REPLICAS"), 401 "REPLICA STATUS": _show_parser("REPLICA STATUS"), 402 "SLAVE STATUS": _show_parser("REPLICA STATUS"), 403 "GLOBAL STATUS": _show_parser("STATUS", global_=True), 404 "SESSION STATUS": _show_parser("STATUS"), 405 "STATUS": _show_parser("STATUS"), 406 "TABLE STATUS": _show_parser("TABLE STATUS"), 407 "FULL TABLES": _show_parser("TABLES", full=True), 408 "TABLES": _show_parser("TABLES"), 409 "TRIGGERS": _show_parser("TRIGGERS"), 410 "GLOBAL VARIABLES": _show_parser("VARIABLES", global_=True), 411 "SESSION VARIABLES": _show_parser("VARIABLES"), 412 "VARIABLES": _show_parser("VARIABLES"), 413 "WARNINGS": _show_parser("WARNINGS"), 414 } 415 416 PROPERTY_PARSERS = { 417 **parser.Parser.PROPERTY_PARSERS, 418 "LOCK": lambda self: self._parse_property_assignment(exp.LockProperty), 419 } 420 421 SET_PARSERS = { 422 **parser.Parser.SET_PARSERS, 423 "PERSIST": lambda self: self._parse_set_item_assignment("PERSIST"), 424 "PERSIST_ONLY": lambda self: self._parse_set_item_assignment("PERSIST_ONLY"), 425 "CHARACTER SET": lambda self: self._parse_set_item_charset("CHARACTER SET"), 426 "CHARSET": lambda self: self._parse_set_item_charset("CHARACTER SET"), 427 "NAMES": lambda self: self._parse_set_item_names(), 428 } 429 430 CONSTRAINT_PARSERS = { 431 **parser.Parser.CONSTRAINT_PARSERS, 432 "FULLTEXT": lambda self: self._parse_index_constraint(kind="FULLTEXT"), 433 "INDEX": lambda self: self._parse_index_constraint(), 434 "KEY": lambda self: self._parse_index_constraint(), 435 "SPATIAL": lambda self: self._parse_index_constraint(kind="SPATIAL"), 436 } 437 438 ALTER_PARSERS = { 439 **parser.Parser.ALTER_PARSERS, 440 "MODIFY": lambda self: self._parse_alter_table_alter(), 441 } 442 443 ALTER_ALTER_PARSERS = { 444 **parser.Parser.ALTER_ALTER_PARSERS, 445 "INDEX": lambda self: self._parse_alter_table_alter_index(), 446 } 447 448 SCHEMA_UNNAMED_CONSTRAINTS = { 449 *parser.Parser.SCHEMA_UNNAMED_CONSTRAINTS, 450 "FULLTEXT", 451 "INDEX", 452 "KEY", 453 "SPATIAL", 454 } 455 456 PROFILE_TYPES: parser.OPTIONS_TYPE = { 457 **dict.fromkeys(("ALL", "CPU", "IPC", "MEMORY", "SOURCE", "SWAPS"), tuple()), 458 "BLOCK": ("IO",), 459 "CONTEXT": ("SWITCHES",), 460 "PAGE": ("FAULTS",), 461 } 462 463 TYPE_TOKENS = { 464 *parser.Parser.TYPE_TOKENS, 465 TokenType.SET, 466 } 467 468 ENUM_TYPE_TOKENS = { 469 *parser.Parser.ENUM_TYPE_TOKENS, 470 TokenType.SET, 471 } 472 473 # SELECT [ ALL | DISTINCT | DISTINCTROW ] [ <OPERATION_MODIFIERS> ] 474 OPERATION_MODIFIERS = { 475 "HIGH_PRIORITY", 476 "STRAIGHT_JOIN", 477 "SQL_SMALL_RESULT", 478 "SQL_BIG_RESULT", 479 "SQL_BUFFER_RESULT", 480 "SQL_NO_CACHE", 481 "SQL_CALC_FOUND_ROWS", 482 } 483 484 LOG_DEFAULTS_TO_LN = True 485 STRING_ALIASES = True 486 VALUES_FOLLOWED_BY_PAREN = False 487 SUPPORTS_PARTITION_SELECTION = True 488 489 def _parse_primary_key_part(self) -> t.Optional[exp.Expression]: 490 this = self._parse_id_var() 491 if not self._match(TokenType.L_PAREN): 492 return this 493 494 expression = self._parse_number() 495 self._match_r_paren() 496 return self.expression(exp.ColumnPrefix, this=this, expression=expression) 497 498 def _parse_index_constraint( 499 self, kind: t.Optional[str] = None 500 ) -> exp.IndexColumnConstraint: 501 if kind: 502 self._match_texts(("INDEX", "KEY")) 503 504 this = self._parse_id_var(any_token=False) 505 index_type = self._match(TokenType.USING) and self._advance_any() and self._prev.text 506 expressions = self._parse_wrapped_csv(self._parse_ordered) 507 508 options = [] 509 while True: 510 if self._match_text_seq("KEY_BLOCK_SIZE"): 511 self._match(TokenType.EQ) 512 opt = exp.IndexConstraintOption(key_block_size=self._parse_number()) 513 elif self._match(TokenType.USING): 514 opt = exp.IndexConstraintOption(using=self._advance_any() and self._prev.text) 515 elif self._match_text_seq("WITH", "PARSER"): 516 opt = exp.IndexConstraintOption(parser=self._parse_var(any_token=True)) 517 elif self._match(TokenType.COMMENT): 518 opt = exp.IndexConstraintOption(comment=self._parse_string()) 519 elif self._match_text_seq("VISIBLE"): 520 opt = exp.IndexConstraintOption(visible=True) 521 elif self._match_text_seq("INVISIBLE"): 522 opt = exp.IndexConstraintOption(visible=False) 523 elif self._match_text_seq("ENGINE_ATTRIBUTE"): 524 self._match(TokenType.EQ) 525 opt = exp.IndexConstraintOption(engine_attr=self._parse_string()) 526 elif self._match_text_seq("SECONDARY_ENGINE_ATTRIBUTE"): 527 self._match(TokenType.EQ) 528 opt = exp.IndexConstraintOption(secondary_engine_attr=self._parse_string()) 529 else: 530 opt = None 531 532 if not opt: 533 break 534 535 options.append(opt) 536 537 return self.expression( 538 exp.IndexColumnConstraint, 539 this=this, 540 expressions=expressions, 541 kind=kind, 542 index_type=index_type, 543 options=options, 544 ) 545 546 def _parse_show_mysql( 547 self, 548 this: str, 549 target: bool | str = False, 550 full: t.Optional[bool] = None, 551 global_: t.Optional[bool] = None, 552 ) -> exp.Show: 553 if target: 554 if isinstance(target, str): 555 self._match_text_seq(target) 556 target_id = self._parse_id_var() 557 else: 558 target_id = None 559 560 log = self._parse_string() if self._match_text_seq("IN") else None 561 562 if this in ("BINLOG EVENTS", "RELAYLOG EVENTS"): 563 position = self._parse_number() if self._match_text_seq("FROM") else None 564 db = None 565 else: 566 position = None 567 db = None 568 569 if self._match(TokenType.FROM): 570 db = self._parse_id_var() 571 elif self._match(TokenType.DOT): 572 db = target_id 573 target_id = self._parse_id_var() 574 575 channel = self._parse_id_var() if self._match_text_seq("FOR", "CHANNEL") else None 576 577 like = self._parse_string() if self._match_text_seq("LIKE") else None 578 where = self._parse_where() 579 580 if this == "PROFILE": 581 types = self._parse_csv(lambda: self._parse_var_from_options(self.PROFILE_TYPES)) 582 query = self._parse_number() if self._match_text_seq("FOR", "QUERY") else None 583 offset = self._parse_number() if self._match_text_seq("OFFSET") else None 584 limit = self._parse_number() if self._match_text_seq("LIMIT") else None 585 else: 586 types, query = None, None 587 offset, limit = self._parse_oldstyle_limit() 588 589 mutex = True if self._match_text_seq("MUTEX") else None 590 mutex = False if self._match_text_seq("STATUS") else mutex 591 592 return self.expression( 593 exp.Show, 594 this=this, 595 target=target_id, 596 full=full, 597 log=log, 598 position=position, 599 db=db, 600 channel=channel, 601 like=like, 602 where=where, 603 types=types, 604 query=query, 605 offset=offset, 606 limit=limit, 607 mutex=mutex, 608 **{"global": global_}, # type: ignore 609 ) 610 611 def _parse_oldstyle_limit( 612 self, 613 ) -> t.Tuple[t.Optional[exp.Expression], t.Optional[exp.Expression]]: 614 limit = None 615 offset = None 616 if self._match_text_seq("LIMIT"): 617 parts = self._parse_csv(self._parse_number) 618 if len(parts) == 1: 619 limit = parts[0] 620 elif len(parts) == 2: 621 limit = parts[1] 622 offset = parts[0] 623 624 return offset, limit 625 626 def _parse_set_item_charset(self, kind: str) -> exp.Expression: 627 this = self._parse_string() or self._parse_unquoted_field() 628 return self.expression(exp.SetItem, this=this, kind=kind) 629 630 def _parse_set_item_names(self) -> exp.Expression: 631 charset = self._parse_string() or self._parse_unquoted_field() 632 if self._match_text_seq("COLLATE"): 633 collate = self._parse_string() or self._parse_unquoted_field() 634 else: 635 collate = None 636 637 return self.expression(exp.SetItem, this=charset, collate=collate, kind="NAMES") 638 639 def _parse_type( 640 self, parse_interval: bool = True, fallback_to_identifier: bool = False 641 ) -> t.Optional[exp.Expression]: 642 # mysql binary is special and can work anywhere, even in order by operations 643 # it operates like a no paren func 644 if self._match(TokenType.BINARY, advance=False): 645 data_type = self._parse_types(check_func=True, allow_identifiers=False) 646 647 if isinstance(data_type, exp.DataType): 648 return self.expression(exp.Cast, this=self._parse_column(), to=data_type) 649 650 return super()._parse_type( 651 parse_interval=parse_interval, fallback_to_identifier=fallback_to_identifier 652 ) 653 654 def _parse_group_concat(self) -> t.Optional[exp.Expression]: 655 def concat_exprs( 656 node: t.Optional[exp.Expression], exprs: t.List[exp.Expression] 657 ) -> exp.Expression: 658 if isinstance(node, exp.Distinct) and len(node.expressions) > 1: 659 concat_exprs = [ 660 self.expression(exp.Concat, expressions=node.expressions, safe=True) 661 ] 662 node.set("expressions", concat_exprs) 663 return node 664 if len(exprs) == 1: 665 return exprs[0] 666 return self.expression(exp.Concat, expressions=args, safe=True) 667 668 args = self._parse_csv(self._parse_lambda) 669 670 if args: 671 order = args[-1] if isinstance(args[-1], exp.Order) else None 672 673 if order: 674 # Order By is the last (or only) expression in the list and has consumed the 'expr' before it, 675 # remove 'expr' from exp.Order and add it back to args 676 args[-1] = order.this 677 order.set("this", concat_exprs(order.this, args)) 678 679 this = order or concat_exprs(args[0], args) 680 else: 681 this = None 682 683 separator = self._parse_field() if self._match(TokenType.SEPARATOR) else None 684 685 return self.expression(exp.GroupConcat, this=this, separator=separator) 686 687 def _parse_json_value(self) -> exp.JSONValue: 688 this = self._parse_bitwise() 689 self._match(TokenType.COMMA) 690 path = self._parse_bitwise() 691 692 returning = self._match(TokenType.RETURNING) and self._parse_type() 693 694 return self.expression( 695 exp.JSONValue, 696 this=this, 697 path=self.dialect.to_json_path(path), 698 returning=returning, 699 on_condition=self._parse_on_condition(), 700 ) 701 702 def _parse_alter_table_alter_index(self) -> exp.AlterIndex: 703 index = self._parse_field(any_token=True) 704 705 if self._match_text_seq("VISIBLE"): 706 visible = True 707 elif self._match_text_seq("INVISIBLE"): 708 visible = False 709 else: 710 visible = None 711 712 return self.expression(exp.AlterIndex, this=index, visible=visible) 713 714 class Generator(generator.Generator): 715 INTERVAL_ALLOWS_PLURAL_FORM = False 716 LOCKING_READS_SUPPORTED = True 717 NULL_ORDERING_SUPPORTED = None 718 JOIN_HINTS = False 719 TABLE_HINTS = True 720 DUPLICATE_KEY_UPDATE_WITH_SET = False 721 QUERY_HINT_SEP = " " 722 VALUES_AS_TABLE = False 723 NVL2_SUPPORTED = False 724 LAST_DAY_SUPPORTS_DATE_PART = False 725 JSON_TYPE_REQUIRED_FOR_EXTRACTION = True 726 JSON_PATH_BRACKETED_KEY_SUPPORTED = False 727 JSON_KEY_VALUE_PAIR_SEP = "," 728 SUPPORTS_TO_NUMBER = False 729 PARSE_JSON_NAME: t.Optional[str] = None 730 PAD_FILL_PATTERN_IS_REQUIRED = True 731 WRAP_DERIVED_VALUES = False 732 VARCHAR_REQUIRES_SIZE = True 733 SUPPORTS_MEDIAN = False 734 735 TRANSFORMS = { 736 **generator.Generator.TRANSFORMS, 737 exp.ArrayAgg: rename_func("GROUP_CONCAT"), 738 exp.CurrentDate: no_paren_current_date_sql, 739 exp.DateDiff: _remove_ts_or_ds_to_date( 740 lambda self, e: self.func("DATEDIFF", e.this, e.expression), ("this", "expression") 741 ), 742 exp.DateAdd: _remove_ts_or_ds_to_date(date_add_sql("ADD")), 743 exp.DateStrToDate: datestrtodate_sql, 744 exp.DateSub: _remove_ts_or_ds_to_date(date_add_sql("SUB")), 745 exp.DateTrunc: _date_trunc_sql, 746 exp.Day: _remove_ts_or_ds_to_date(), 747 exp.DayOfMonth: _remove_ts_or_ds_to_date(rename_func("DAYOFMONTH")), 748 exp.DayOfWeek: _remove_ts_or_ds_to_date(rename_func("DAYOFWEEK")), 749 exp.DayOfYear: _remove_ts_or_ds_to_date(rename_func("DAYOFYEAR")), 750 exp.GroupConcat: lambda self, 751 e: f"""GROUP_CONCAT({self.sql(e, "this")} SEPARATOR {self.sql(e, "separator") or "','"})""", 752 exp.ILike: no_ilike_sql, 753 exp.JSONExtractScalar: arrow_json_extract_sql, 754 exp.Length: length_or_char_length_sql, 755 exp.LogicalOr: rename_func("MAX"), 756 exp.LogicalAnd: rename_func("MIN"), 757 exp.Max: max_or_greatest, 758 exp.Min: min_or_least, 759 exp.Month: _remove_ts_or_ds_to_date(), 760 exp.NullSafeEQ: lambda self, e: self.binary(e, "<=>"), 761 exp.NullSafeNEQ: lambda self, e: f"NOT {self.binary(e, '<=>')}", 762 exp.NumberToStr: rename_func("FORMAT"), 763 exp.Pivot: no_pivot_sql, 764 exp.Select: transforms.preprocess( 765 [ 766 transforms.eliminate_distinct_on, 767 transforms.eliminate_semi_and_anti_joins, 768 transforms.eliminate_qualify, 769 transforms.eliminate_full_outer_join, 770 transforms.unnest_generate_date_array_using_recursive_cte, 771 ] 772 ), 773 exp.StrPosition: lambda self, e: strposition_sql( 774 self, e, func_name="LOCATE", supports_position=True 775 ), 776 exp.StrToDate: _str_to_date_sql, 777 exp.StrToTime: _str_to_date_sql, 778 exp.Stuff: rename_func("INSERT"), 779 exp.TableSample: no_tablesample_sql, 780 exp.TimeFromParts: rename_func("MAKETIME"), 781 exp.TimestampAdd: date_add_interval_sql("DATE", "ADD"), 782 exp.TimestampDiff: lambda self, e: self.func( 783 "TIMESTAMPDIFF", unit_to_var(e), e.expression, e.this 784 ), 785 exp.TimestampSub: date_add_interval_sql("DATE", "SUB"), 786 exp.TimeStrToUnix: rename_func("UNIX_TIMESTAMP"), 787 exp.TimeStrToTime: lambda self, e: timestrtotime_sql( 788 self, 789 e, 790 include_precision=not e.args.get("zone"), 791 ), 792 exp.TimeToStr: _remove_ts_or_ds_to_date( 793 lambda self, e: self.func("DATE_FORMAT", e.this, self.format_time(e)) 794 ), 795 exp.Trim: trim_sql, 796 exp.TryCast: no_trycast_sql, 797 exp.TsOrDsAdd: date_add_sql("ADD"), 798 exp.TsOrDsDiff: lambda self, e: self.func("DATEDIFF", e.this, e.expression), 799 exp.TsOrDsToDate: _ts_or_ds_to_date_sql, 800 exp.Unicode: lambda self, e: f"ORD(CONVERT({self.sql(e.this)} USING utf32))", 801 exp.UnixToTime: _unix_to_time_sql, 802 exp.Week: _remove_ts_or_ds_to_date(), 803 exp.WeekOfYear: _remove_ts_or_ds_to_date(rename_func("WEEKOFYEAR")), 804 exp.Year: _remove_ts_or_ds_to_date(), 805 } 806 807 UNSIGNED_TYPE_MAPPING = { 808 exp.DataType.Type.UBIGINT: "BIGINT", 809 exp.DataType.Type.UINT: "INT", 810 exp.DataType.Type.UMEDIUMINT: "MEDIUMINT", 811 exp.DataType.Type.USMALLINT: "SMALLINT", 812 exp.DataType.Type.UTINYINT: "TINYINT", 813 exp.DataType.Type.UDECIMAL: "DECIMAL", 814 exp.DataType.Type.UDOUBLE: "DOUBLE", 815 } 816 817 TIMESTAMP_TYPE_MAPPING = { 818 exp.DataType.Type.DATETIME2: "DATETIME", 819 exp.DataType.Type.SMALLDATETIME: "DATETIME", 820 exp.DataType.Type.TIMESTAMP: "DATETIME", 821 exp.DataType.Type.TIMESTAMPTZ: "TIMESTAMP", 822 exp.DataType.Type.TIMESTAMPLTZ: "TIMESTAMP", 823 } 824 825 TYPE_MAPPING = { 826 **generator.Generator.TYPE_MAPPING, 827 **UNSIGNED_TYPE_MAPPING, 828 **TIMESTAMP_TYPE_MAPPING, 829 } 830 831 TYPE_MAPPING.pop(exp.DataType.Type.MEDIUMTEXT) 832 TYPE_MAPPING.pop(exp.DataType.Type.LONGTEXT) 833 TYPE_MAPPING.pop(exp.DataType.Type.TINYTEXT) 834 TYPE_MAPPING.pop(exp.DataType.Type.BLOB) 835 TYPE_MAPPING.pop(exp.DataType.Type.MEDIUMBLOB) 836 TYPE_MAPPING.pop(exp.DataType.Type.LONGBLOB) 837 TYPE_MAPPING.pop(exp.DataType.Type.TINYBLOB) 838 839 PROPERTIES_LOCATION = { 840 **generator.Generator.PROPERTIES_LOCATION, 841 exp.TransientProperty: exp.Properties.Location.UNSUPPORTED, 842 exp.VolatileProperty: exp.Properties.Location.UNSUPPORTED, 843 } 844 845 LIMIT_FETCH = "LIMIT" 846 847 LIMIT_ONLY_LITERALS = True 848 849 CHAR_CAST_MAPPING = dict.fromkeys( 850 ( 851 exp.DataType.Type.LONGTEXT, 852 exp.DataType.Type.LONGBLOB, 853 exp.DataType.Type.MEDIUMBLOB, 854 exp.DataType.Type.MEDIUMTEXT, 855 exp.DataType.Type.TEXT, 856 exp.DataType.Type.TINYBLOB, 857 exp.DataType.Type.TINYTEXT, 858 exp.DataType.Type.VARCHAR, 859 ), 860 "CHAR", 861 ) 862 SIGNED_CAST_MAPPING = dict.fromkeys( 863 ( 864 exp.DataType.Type.BIGINT, 865 exp.DataType.Type.BOOLEAN, 866 exp.DataType.Type.INT, 867 exp.DataType.Type.SMALLINT, 868 exp.DataType.Type.TINYINT, 869 exp.DataType.Type.MEDIUMINT, 870 ), 871 "SIGNED", 872 ) 873 874 # MySQL doesn't support many datatypes in cast. 875 # https://dev.mysql.com/doc/refman/8.0/en/cast-functions.html#function_cast 876 CAST_MAPPING = { 877 **CHAR_CAST_MAPPING, 878 **SIGNED_CAST_MAPPING, 879 exp.DataType.Type.UBIGINT: "UNSIGNED", 880 } 881 882 TIMESTAMP_FUNC_TYPES = { 883 exp.DataType.Type.TIMESTAMPTZ, 884 exp.DataType.Type.TIMESTAMPLTZ, 885 } 886 887 # https://dev.mysql.com/doc/refman/8.0/en/keywords.html 888 RESERVED_KEYWORDS = { 889 "accessible", 890 "add", 891 "all", 892 "alter", 893 "analyze", 894 "and", 895 "as", 896 "asc", 897 "asensitive", 898 "before", 899 "between", 900 "bigint", 901 "binary", 902 "blob", 903 "both", 904 "by", 905 "call", 906 "cascade", 907 "case", 908 "change", 909 "char", 910 "character", 911 "check", 912 "collate", 913 "column", 914 "condition", 915 "constraint", 916 "continue", 917 "convert", 918 "create", 919 "cross", 920 "cube", 921 "cume_dist", 922 "current_date", 923 "current_time", 924 "current_timestamp", 925 "current_user", 926 "cursor", 927 "database", 928 "databases", 929 "day_hour", 930 "day_microsecond", 931 "day_minute", 932 "day_second", 933 "dec", 934 "decimal", 935 "declare", 936 "default", 937 "delayed", 938 "delete", 939 "dense_rank", 940 "desc", 941 "describe", 942 "deterministic", 943 "distinct", 944 "distinctrow", 945 "div", 946 "double", 947 "drop", 948 "dual", 949 "each", 950 "else", 951 "elseif", 952 "empty", 953 "enclosed", 954 "escaped", 955 "except", 956 "exists", 957 "exit", 958 "explain", 959 "false", 960 "fetch", 961 "first_value", 962 "float", 963 "float4", 964 "float8", 965 "for", 966 "force", 967 "foreign", 968 "from", 969 "fulltext", 970 "function", 971 "generated", 972 "get", 973 "grant", 974 "group", 975 "grouping", 976 "groups", 977 "having", 978 "high_priority", 979 "hour_microsecond", 980 "hour_minute", 981 "hour_second", 982 "if", 983 "ignore", 984 "in", 985 "index", 986 "infile", 987 "inner", 988 "inout", 989 "insensitive", 990 "insert", 991 "int", 992 "int1", 993 "int2", 994 "int3", 995 "int4", 996 "int8", 997 "integer", 998 "intersect", 999 "interval", 1000 "into", 1001 "io_after_gtids", 1002 "io_before_gtids", 1003 "is", 1004 "iterate", 1005 "join", 1006 "json_table", 1007 "key", 1008 "keys", 1009 "kill", 1010 "lag", 1011 "last_value", 1012 "lateral", 1013 "lead", 1014 "leading", 1015 "leave", 1016 "left", 1017 "like", 1018 "limit", 1019 "linear", 1020 "lines", 1021 "load", 1022 "localtime", 1023 "localtimestamp", 1024 "lock", 1025 "long", 1026 "longblob", 1027 "longtext", 1028 "loop", 1029 "low_priority", 1030 "master_bind", 1031 "master_ssl_verify_server_cert", 1032 "match", 1033 "maxvalue", 1034 "mediumblob", 1035 "mediumint", 1036 "mediumtext", 1037 "middleint", 1038 "minute_microsecond", 1039 "minute_second", 1040 "mod", 1041 "modifies", 1042 "natural", 1043 "not", 1044 "no_write_to_binlog", 1045 "nth_value", 1046 "ntile", 1047 "null", 1048 "numeric", 1049 "of", 1050 "on", 1051 "optimize", 1052 "optimizer_costs", 1053 "option", 1054 "optionally", 1055 "or", 1056 "order", 1057 "out", 1058 "outer", 1059 "outfile", 1060 "over", 1061 "partition", 1062 "percent_rank", 1063 "precision", 1064 "primary", 1065 "procedure", 1066 "purge", 1067 "range", 1068 "rank", 1069 "read", 1070 "reads", 1071 "read_write", 1072 "real", 1073 "recursive", 1074 "references", 1075 "regexp", 1076 "release", 1077 "rename", 1078 "repeat", 1079 "replace", 1080 "require", 1081 "resignal", 1082 "restrict", 1083 "return", 1084 "revoke", 1085 "right", 1086 "rlike", 1087 "row", 1088 "rows", 1089 "row_number", 1090 "schema", 1091 "schemas", 1092 "second_microsecond", 1093 "select", 1094 "sensitive", 1095 "separator", 1096 "set", 1097 "show", 1098 "signal", 1099 "smallint", 1100 "spatial", 1101 "specific", 1102 "sql", 1103 "sqlexception", 1104 "sqlstate", 1105 "sqlwarning", 1106 "sql_big_result", 1107 "sql_calc_found_rows", 1108 "sql_small_result", 1109 "ssl", 1110 "starting", 1111 "stored", 1112 "straight_join", 1113 "system", 1114 "table", 1115 "terminated", 1116 "then", 1117 "tinyblob", 1118 "tinyint", 1119 "tinytext", 1120 "to", 1121 "trailing", 1122 "trigger", 1123 "true", 1124 "undo", 1125 "union", 1126 "unique", 1127 "unlock", 1128 "unsigned", 1129 "update", 1130 "usage", 1131 "use", 1132 "using", 1133 "utc_date", 1134 "utc_time", 1135 "utc_timestamp", 1136 "values", 1137 "varbinary", 1138 "varchar", 1139 "varcharacter", 1140 "varying", 1141 "virtual", 1142 "when", 1143 "where", 1144 "while", 1145 "window", 1146 "with", 1147 "write", 1148 "xor", 1149 "year_month", 1150 "zerofill", 1151 } 1152 1153 def array_sql(self, expression: exp.Array) -> str: 1154 self.unsupported("Arrays are not supported by MySQL") 1155 return self.function_fallback_sql(expression) 1156 1157 def arraycontainsall_sql(self, expression: exp.ArrayContainsAll) -> str: 1158 self.unsupported("Array operations are not supported by MySQL") 1159 return self.function_fallback_sql(expression) 1160 1161 def dpipe_sql(self, expression: exp.DPipe) -> str: 1162 return self.func("CONCAT", *expression.flatten()) 1163 1164 def extract_sql(self, expression: exp.Extract) -> str: 1165 unit = expression.name 1166 if unit and unit.lower() == "epoch": 1167 return self.func("UNIX_TIMESTAMP", expression.expression) 1168 1169 return super().extract_sql(expression) 1170 1171 def datatype_sql(self, expression: exp.DataType) -> str: 1172 if ( 1173 self.VARCHAR_REQUIRES_SIZE 1174 and expression.is_type(exp.DataType.Type.VARCHAR) 1175 and not expression.expressions 1176 ): 1177 # `VARCHAR` must always have a size - if it doesn't, we always generate `TEXT` 1178 return "TEXT" 1179 1180 # https://dev.mysql.com/doc/refman/8.0/en/numeric-type-syntax.html 1181 result = super().datatype_sql(expression) 1182 if expression.this in self.UNSIGNED_TYPE_MAPPING: 1183 result = f"{result} UNSIGNED" 1184 1185 return result 1186 1187 def jsonarraycontains_sql(self, expression: exp.JSONArrayContains) -> str: 1188 return f"{self.sql(expression, 'this')} MEMBER OF({self.sql(expression, 'expression')})" 1189 1190 def cast_sql(self, expression: exp.Cast, safe_prefix: t.Optional[str] = None) -> str: 1191 if expression.to.this in self.TIMESTAMP_FUNC_TYPES: 1192 return self.func("TIMESTAMP", expression.this) 1193 1194 to = self.CAST_MAPPING.get(expression.to.this) 1195 1196 if to: 1197 expression.to.set("this", to) 1198 return super().cast_sql(expression) 1199 1200 def show_sql(self, expression: exp.Show) -> str: 1201 this = f" {expression.name}" 1202 full = " FULL" if expression.args.get("full") else "" 1203 global_ = " GLOBAL" if expression.args.get("global") else "" 1204 1205 target = self.sql(expression, "target") 1206 target = f" {target}" if target else "" 1207 if expression.name in ("COLUMNS", "INDEX"): 1208 target = f" FROM{target}" 1209 elif expression.name == "GRANTS": 1210 target = f" FOR{target}" 1211 1212 db = self._prefixed_sql("FROM", expression, "db") 1213 1214 like = self._prefixed_sql("LIKE", expression, "like") 1215 where = self.sql(expression, "where") 1216 1217 types = self.expressions(expression, key="types") 1218 types = f" {types}" if types else types 1219 query = self._prefixed_sql("FOR QUERY", expression, "query") 1220 1221 if expression.name == "PROFILE": 1222 offset = self._prefixed_sql("OFFSET", expression, "offset") 1223 limit = self._prefixed_sql("LIMIT", expression, "limit") 1224 else: 1225 offset = "" 1226 limit = self._oldstyle_limit_sql(expression) 1227 1228 log = self._prefixed_sql("IN", expression, "log") 1229 position = self._prefixed_sql("FROM", expression, "position") 1230 1231 channel = self._prefixed_sql("FOR CHANNEL", expression, "channel") 1232 1233 if expression.name == "ENGINE": 1234 mutex_or_status = " MUTEX" if expression.args.get("mutex") else " STATUS" 1235 else: 1236 mutex_or_status = "" 1237 1238 return f"SHOW{full}{global_}{this}{target}{types}{db}{query}{log}{position}{channel}{mutex_or_status}{like}{where}{offset}{limit}" 1239 1240 def altercolumn_sql(self, expression: exp.AlterColumn) -> str: 1241 dtype = self.sql(expression, "dtype") 1242 if not dtype: 1243 return super().altercolumn_sql(expression) 1244 1245 this = self.sql(expression, "this") 1246 return f"MODIFY COLUMN {this} {dtype}" 1247 1248 def _prefixed_sql(self, prefix: str, expression: exp.Expression, arg: str) -> str: 1249 sql = self.sql(expression, arg) 1250 return f" {prefix} {sql}" if sql else "" 1251 1252 def _oldstyle_limit_sql(self, expression: exp.Show) -> str: 1253 limit = self.sql(expression, "limit") 1254 offset = self.sql(expression, "offset") 1255 if limit: 1256 limit_offset = f"{offset}, {limit}" if offset else limit 1257 return f" LIMIT {limit_offset}" 1258 return "" 1259 1260 def chr_sql(self, expression: exp.Chr) -> str: 1261 this = self.expressions(sqls=[expression.this] + expression.expressions) 1262 charset = expression.args.get("charset") 1263 using = f" USING {self.sql(charset)}" if charset else "" 1264 return f"CHAR({this}{using})" 1265 1266 def timestamptrunc_sql(self, expression: exp.TimestampTrunc) -> str: 1267 unit = expression.args.get("unit") 1268 1269 # Pick an old-enough date to avoid negative timestamp diffs 1270 start_ts = "'0000-01-01 00:00:00'" 1271 1272 # Source: https://stackoverflow.com/a/32955740 1273 timestamp_diff = build_date_delta(exp.TimestampDiff)([unit, start_ts, expression.this]) 1274 interval = exp.Interval(this=timestamp_diff, unit=unit) 1275 dateadd = build_date_delta_with_interval(exp.DateAdd)([start_ts, interval]) 1276 1277 return self.sql(dateadd) 1278 1279 def converttimezone_sql(self, expression: exp.ConvertTimezone) -> str: 1280 from_tz = expression.args.get("source_tz") 1281 to_tz = expression.args.get("target_tz") 1282 dt = expression.args.get("timestamp") 1283 1284 return self.func("CONVERT_TZ", dt, from_tz, to_tz) 1285 1286 def attimezone_sql(self, expression: exp.AtTimeZone) -> str: 1287 self.unsupported("AT TIME ZONE is not supported by MySQL") 1288 return self.sql(expression.this) 1289 1290 def isascii_sql(self, expression: exp.IsAscii) -> str: 1291 return f"REGEXP_LIKE({self.sql(expression.this)}, '^[[:ascii:]]*$')" 1292 1293 @unsupported_args("this") 1294 def currentschema_sql(self, expression: exp.CurrentSchema) -> str: 1295 return self.func("SCHEMA")
TIME_SPECIFIERS =
{'I', 'T', 'k', 'p', 'S', 's', 'i', 'H', 'h', 'r', 'l', 'f'}
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
class
MySQL(sqlglot.dialects.dialect.Dialect):
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 "BLOB": TokenType.BLOB, 197 "EXPLAIN": TokenType.DESCRIBE, 198 "FORCE": TokenType.FORCE, 199 "IGNORE": TokenType.IGNORE, 200 "KEY": TokenType.KEY, 201 "LOCK TABLES": TokenType.COMMAND, 202 "LONGBLOB": TokenType.LONGBLOB, 203 "LONGTEXT": TokenType.LONGTEXT, 204 "MEDIUMBLOB": TokenType.MEDIUMBLOB, 205 "TINYBLOB": TokenType.TINYBLOB, 206 "TINYTEXT": TokenType.TINYTEXT, 207 "MEDIUMTEXT": TokenType.MEDIUMTEXT, 208 "MEDIUMINT": TokenType.MEDIUMINT, 209 "MEMBER OF": TokenType.MEMBER_OF, 210 "SEPARATOR": TokenType.SEPARATOR, 211 "SERIAL": TokenType.SERIAL, 212 "START": TokenType.BEGIN, 213 "SIGNED": TokenType.BIGINT, 214 "SIGNED INTEGER": TokenType.BIGINT, 215 "UNLOCK TABLES": TokenType.COMMAND, 216 "UNSIGNED": TokenType.UBIGINT, 217 "UNSIGNED INTEGER": TokenType.UBIGINT, 218 "YEAR": TokenType.YEAR, 219 "_ARMSCII8": TokenType.INTRODUCER, 220 "_ASCII": TokenType.INTRODUCER, 221 "_BIG5": TokenType.INTRODUCER, 222 "_BINARY": TokenType.INTRODUCER, 223 "_CP1250": TokenType.INTRODUCER, 224 "_CP1251": TokenType.INTRODUCER, 225 "_CP1256": TokenType.INTRODUCER, 226 "_CP1257": TokenType.INTRODUCER, 227 "_CP850": TokenType.INTRODUCER, 228 "_CP852": TokenType.INTRODUCER, 229 "_CP866": TokenType.INTRODUCER, 230 "_CP932": TokenType.INTRODUCER, 231 "_DEC8": TokenType.INTRODUCER, 232 "_EUCJPMS": TokenType.INTRODUCER, 233 "_EUCKR": TokenType.INTRODUCER, 234 "_GB18030": TokenType.INTRODUCER, 235 "_GB2312": TokenType.INTRODUCER, 236 "_GBK": TokenType.INTRODUCER, 237 "_GEOSTD8": TokenType.INTRODUCER, 238 "_GREEK": TokenType.INTRODUCER, 239 "_HEBREW": TokenType.INTRODUCER, 240 "_HP8": TokenType.INTRODUCER, 241 "_KEYBCS2": TokenType.INTRODUCER, 242 "_KOI8R": TokenType.INTRODUCER, 243 "_KOI8U": TokenType.INTRODUCER, 244 "_LATIN1": TokenType.INTRODUCER, 245 "_LATIN2": TokenType.INTRODUCER, 246 "_LATIN5": TokenType.INTRODUCER, 247 "_LATIN7": TokenType.INTRODUCER, 248 "_MACCE": TokenType.INTRODUCER, 249 "_MACROMAN": TokenType.INTRODUCER, 250 "_SJIS": TokenType.INTRODUCER, 251 "_SWE7": TokenType.INTRODUCER, 252 "_TIS620": TokenType.INTRODUCER, 253 "_UCS2": TokenType.INTRODUCER, 254 "_UJIS": TokenType.INTRODUCER, 255 # https://dev.mysql.com/doc/refman/8.0/en/string-literals.html 256 "_UTF8": TokenType.INTRODUCER, 257 "_UTF16": TokenType.INTRODUCER, 258 "_UTF16LE": TokenType.INTRODUCER, 259 "_UTF32": TokenType.INTRODUCER, 260 "_UTF8MB3": TokenType.INTRODUCER, 261 "_UTF8MB4": TokenType.INTRODUCER, 262 "@@": TokenType.SESSION_PARAMETER, 263 } 264 265 COMMANDS = {*tokens.Tokenizer.COMMANDS, TokenType.REPLACE} - {TokenType.SHOW} 266 267 class Parser(parser.Parser): 268 FUNC_TOKENS = { 269 *parser.Parser.FUNC_TOKENS, 270 TokenType.DATABASE, 271 TokenType.SCHEMA, 272 TokenType.VALUES, 273 } 274 275 CONJUNCTION = { 276 **parser.Parser.CONJUNCTION, 277 TokenType.DAMP: exp.And, 278 TokenType.XOR: exp.Xor, 279 } 280 281 DISJUNCTION = { 282 **parser.Parser.DISJUNCTION, 283 TokenType.DPIPE: exp.Or, 284 } 285 286 TABLE_ALIAS_TOKENS = ( 287 parser.Parser.TABLE_ALIAS_TOKENS - parser.Parser.TABLE_INDEX_HINT_TOKENS 288 ) 289 290 RANGE_PARSERS = { 291 **parser.Parser.RANGE_PARSERS, 292 TokenType.MEMBER_OF: lambda self, this: self.expression( 293 exp.JSONArrayContains, 294 this=this, 295 expression=self._parse_wrapped(self._parse_expression), 296 ), 297 } 298 299 FUNCTIONS = { 300 **parser.Parser.FUNCTIONS, 301 "CONVERT_TZ": lambda args: exp.ConvertTimezone( 302 source_tz=seq_get(args, 1), target_tz=seq_get(args, 2), timestamp=seq_get(args, 0) 303 ), 304 "CURDATE": exp.CurrentDate.from_arg_list, 305 "DATE": lambda args: exp.TsOrDsToDate(this=seq_get(args, 0)), 306 "DATE_ADD": build_date_delta_with_interval(exp.DateAdd), 307 "DATE_FORMAT": build_formatted_time(exp.TimeToStr, "mysql"), 308 "DATE_SUB": build_date_delta_with_interval(exp.DateSub), 309 "DAY": lambda args: exp.Day(this=exp.TsOrDsToDate(this=seq_get(args, 0))), 310 "DAYOFMONTH": lambda args: exp.DayOfMonth(this=exp.TsOrDsToDate(this=seq_get(args, 0))), 311 "DAYOFWEEK": lambda args: exp.DayOfWeek(this=exp.TsOrDsToDate(this=seq_get(args, 0))), 312 "DAYOFYEAR": lambda args: exp.DayOfYear(this=exp.TsOrDsToDate(this=seq_get(args, 0))), 313 "FORMAT": exp.NumberToStr.from_arg_list, 314 "FROM_UNIXTIME": build_formatted_time(exp.UnixToTime, "mysql"), 315 "ISNULL": isnull_to_is_null, 316 "LENGTH": lambda args: exp.Length(this=seq_get(args, 0), binary=True), 317 "MAKETIME": exp.TimeFromParts.from_arg_list, 318 "MONTH": lambda args: exp.Month(this=exp.TsOrDsToDate(this=seq_get(args, 0))), 319 "MONTHNAME": lambda args: exp.TimeToStr( 320 this=exp.TsOrDsToDate(this=seq_get(args, 0)), 321 format=exp.Literal.string("%B"), 322 ), 323 "SCHEMA": exp.CurrentSchema.from_arg_list, 324 "DATABASE": exp.CurrentSchema.from_arg_list, 325 "STR_TO_DATE": _str_to_date, 326 "TIMESTAMPDIFF": build_date_delta(exp.TimestampDiff), 327 "TO_DAYS": lambda args: exp.paren( 328 exp.DateDiff( 329 this=exp.TsOrDsToDate(this=seq_get(args, 0)), 330 expression=exp.TsOrDsToDate(this=exp.Literal.string("0000-01-01")), 331 unit=exp.var("DAY"), 332 ) 333 + 1 334 ), 335 "WEEK": lambda args: exp.Week( 336 this=exp.TsOrDsToDate(this=seq_get(args, 0)), mode=seq_get(args, 1) 337 ), 338 "WEEKOFYEAR": lambda args: exp.WeekOfYear(this=exp.TsOrDsToDate(this=seq_get(args, 0))), 339 "YEAR": lambda args: exp.Year(this=exp.TsOrDsToDate(this=seq_get(args, 0))), 340 } 341 342 FUNCTION_PARSERS = { 343 **parser.Parser.FUNCTION_PARSERS, 344 "CHAR": lambda self: self.expression( 345 exp.Chr, 346 expressions=self._parse_csv(self._parse_assignment), 347 charset=self._match(TokenType.USING) and self._parse_var(), 348 ), 349 "GROUP_CONCAT": lambda self: self._parse_group_concat(), 350 # https://dev.mysql.com/doc/refman/5.7/en/miscellaneous-functions.html#function_values 351 "VALUES": lambda self: self.expression( 352 exp.Anonymous, this="VALUES", expressions=[self._parse_id_var()] 353 ), 354 "JSON_VALUE": lambda self: self._parse_json_value(), 355 } 356 357 STATEMENT_PARSERS = { 358 **parser.Parser.STATEMENT_PARSERS, 359 TokenType.SHOW: lambda self: self._parse_show(), 360 } 361 362 SHOW_PARSERS = { 363 "BINARY LOGS": _show_parser("BINARY LOGS"), 364 "MASTER LOGS": _show_parser("BINARY LOGS"), 365 "BINLOG EVENTS": _show_parser("BINLOG EVENTS"), 366 "CHARACTER SET": _show_parser("CHARACTER SET"), 367 "CHARSET": _show_parser("CHARACTER SET"), 368 "COLLATION": _show_parser("COLLATION"), 369 "FULL COLUMNS": _show_parser("COLUMNS", target="FROM", full=True), 370 "COLUMNS": _show_parser("COLUMNS", target="FROM"), 371 "CREATE DATABASE": _show_parser("CREATE DATABASE", target=True), 372 "CREATE EVENT": _show_parser("CREATE EVENT", target=True), 373 "CREATE FUNCTION": _show_parser("CREATE FUNCTION", target=True), 374 "CREATE PROCEDURE": _show_parser("CREATE PROCEDURE", target=True), 375 "CREATE TABLE": _show_parser("CREATE TABLE", target=True), 376 "CREATE TRIGGER": _show_parser("CREATE TRIGGER", target=True), 377 "CREATE VIEW": _show_parser("CREATE VIEW", target=True), 378 "DATABASES": _show_parser("DATABASES"), 379 "SCHEMAS": _show_parser("DATABASES"), 380 "ENGINE": _show_parser("ENGINE", target=True), 381 "STORAGE ENGINES": _show_parser("ENGINES"), 382 "ENGINES": _show_parser("ENGINES"), 383 "ERRORS": _show_parser("ERRORS"), 384 "EVENTS": _show_parser("EVENTS"), 385 "FUNCTION CODE": _show_parser("FUNCTION CODE", target=True), 386 "FUNCTION STATUS": _show_parser("FUNCTION STATUS"), 387 "GRANTS": _show_parser("GRANTS", target="FOR"), 388 "INDEX": _show_parser("INDEX", target="FROM"), 389 "MASTER STATUS": _show_parser("MASTER STATUS"), 390 "OPEN TABLES": _show_parser("OPEN TABLES"), 391 "PLUGINS": _show_parser("PLUGINS"), 392 "PROCEDURE CODE": _show_parser("PROCEDURE CODE", target=True), 393 "PROCEDURE STATUS": _show_parser("PROCEDURE STATUS"), 394 "PRIVILEGES": _show_parser("PRIVILEGES"), 395 "FULL PROCESSLIST": _show_parser("PROCESSLIST", full=True), 396 "PROCESSLIST": _show_parser("PROCESSLIST"), 397 "PROFILE": _show_parser("PROFILE"), 398 "PROFILES": _show_parser("PROFILES"), 399 "RELAYLOG EVENTS": _show_parser("RELAYLOG EVENTS"), 400 "REPLICAS": _show_parser("REPLICAS"), 401 "SLAVE HOSTS": _show_parser("REPLICAS"), 402 "REPLICA STATUS": _show_parser("REPLICA STATUS"), 403 "SLAVE STATUS": _show_parser("REPLICA STATUS"), 404 "GLOBAL STATUS": _show_parser("STATUS", global_=True), 405 "SESSION STATUS": _show_parser("STATUS"), 406 "STATUS": _show_parser("STATUS"), 407 "TABLE STATUS": _show_parser("TABLE STATUS"), 408 "FULL TABLES": _show_parser("TABLES", full=True), 409 "TABLES": _show_parser("TABLES"), 410 "TRIGGERS": _show_parser("TRIGGERS"), 411 "GLOBAL VARIABLES": _show_parser("VARIABLES", global_=True), 412 "SESSION VARIABLES": _show_parser("VARIABLES"), 413 "VARIABLES": _show_parser("VARIABLES"), 414 "WARNINGS": _show_parser("WARNINGS"), 415 } 416 417 PROPERTY_PARSERS = { 418 **parser.Parser.PROPERTY_PARSERS, 419 "LOCK": lambda self: self._parse_property_assignment(exp.LockProperty), 420 } 421 422 SET_PARSERS = { 423 **parser.Parser.SET_PARSERS, 424 "PERSIST": lambda self: self._parse_set_item_assignment("PERSIST"), 425 "PERSIST_ONLY": lambda self: self._parse_set_item_assignment("PERSIST_ONLY"), 426 "CHARACTER SET": lambda self: self._parse_set_item_charset("CHARACTER SET"), 427 "CHARSET": lambda self: self._parse_set_item_charset("CHARACTER SET"), 428 "NAMES": lambda self: self._parse_set_item_names(), 429 } 430 431 CONSTRAINT_PARSERS = { 432 **parser.Parser.CONSTRAINT_PARSERS, 433 "FULLTEXT": lambda self: self._parse_index_constraint(kind="FULLTEXT"), 434 "INDEX": lambda self: self._parse_index_constraint(), 435 "KEY": lambda self: self._parse_index_constraint(), 436 "SPATIAL": lambda self: self._parse_index_constraint(kind="SPATIAL"), 437 } 438 439 ALTER_PARSERS = { 440 **parser.Parser.ALTER_PARSERS, 441 "MODIFY": lambda self: self._parse_alter_table_alter(), 442 } 443 444 ALTER_ALTER_PARSERS = { 445 **parser.Parser.ALTER_ALTER_PARSERS, 446 "INDEX": lambda self: self._parse_alter_table_alter_index(), 447 } 448 449 SCHEMA_UNNAMED_CONSTRAINTS = { 450 *parser.Parser.SCHEMA_UNNAMED_CONSTRAINTS, 451 "FULLTEXT", 452 "INDEX", 453 "KEY", 454 "SPATIAL", 455 } 456 457 PROFILE_TYPES: parser.OPTIONS_TYPE = { 458 **dict.fromkeys(("ALL", "CPU", "IPC", "MEMORY", "SOURCE", "SWAPS"), tuple()), 459 "BLOCK": ("IO",), 460 "CONTEXT": ("SWITCHES",), 461 "PAGE": ("FAULTS",), 462 } 463 464 TYPE_TOKENS = { 465 *parser.Parser.TYPE_TOKENS, 466 TokenType.SET, 467 } 468 469 ENUM_TYPE_TOKENS = { 470 *parser.Parser.ENUM_TYPE_TOKENS, 471 TokenType.SET, 472 } 473 474 # SELECT [ ALL | DISTINCT | DISTINCTROW ] [ <OPERATION_MODIFIERS> ] 475 OPERATION_MODIFIERS = { 476 "HIGH_PRIORITY", 477 "STRAIGHT_JOIN", 478 "SQL_SMALL_RESULT", 479 "SQL_BIG_RESULT", 480 "SQL_BUFFER_RESULT", 481 "SQL_NO_CACHE", 482 "SQL_CALC_FOUND_ROWS", 483 } 484 485 LOG_DEFAULTS_TO_LN = True 486 STRING_ALIASES = True 487 VALUES_FOLLOWED_BY_PAREN = False 488 SUPPORTS_PARTITION_SELECTION = True 489 490 def _parse_primary_key_part(self) -> t.Optional[exp.Expression]: 491 this = self._parse_id_var() 492 if not self._match(TokenType.L_PAREN): 493 return this 494 495 expression = self._parse_number() 496 self._match_r_paren() 497 return self.expression(exp.ColumnPrefix, this=this, expression=expression) 498 499 def _parse_index_constraint( 500 self, kind: t.Optional[str] = None 501 ) -> exp.IndexColumnConstraint: 502 if kind: 503 self._match_texts(("INDEX", "KEY")) 504 505 this = self._parse_id_var(any_token=False) 506 index_type = self._match(TokenType.USING) and self._advance_any() and self._prev.text 507 expressions = self._parse_wrapped_csv(self._parse_ordered) 508 509 options = [] 510 while True: 511 if self._match_text_seq("KEY_BLOCK_SIZE"): 512 self._match(TokenType.EQ) 513 opt = exp.IndexConstraintOption(key_block_size=self._parse_number()) 514 elif self._match(TokenType.USING): 515 opt = exp.IndexConstraintOption(using=self._advance_any() and self._prev.text) 516 elif self._match_text_seq("WITH", "PARSER"): 517 opt = exp.IndexConstraintOption(parser=self._parse_var(any_token=True)) 518 elif self._match(TokenType.COMMENT): 519 opt = exp.IndexConstraintOption(comment=self._parse_string()) 520 elif self._match_text_seq("VISIBLE"): 521 opt = exp.IndexConstraintOption(visible=True) 522 elif self._match_text_seq("INVISIBLE"): 523 opt = exp.IndexConstraintOption(visible=False) 524 elif self._match_text_seq("ENGINE_ATTRIBUTE"): 525 self._match(TokenType.EQ) 526 opt = exp.IndexConstraintOption(engine_attr=self._parse_string()) 527 elif self._match_text_seq("SECONDARY_ENGINE_ATTRIBUTE"): 528 self._match(TokenType.EQ) 529 opt = exp.IndexConstraintOption(secondary_engine_attr=self._parse_string()) 530 else: 531 opt = None 532 533 if not opt: 534 break 535 536 options.append(opt) 537 538 return self.expression( 539 exp.IndexColumnConstraint, 540 this=this, 541 expressions=expressions, 542 kind=kind, 543 index_type=index_type, 544 options=options, 545 ) 546 547 def _parse_show_mysql( 548 self, 549 this: str, 550 target: bool | str = False, 551 full: t.Optional[bool] = None, 552 global_: t.Optional[bool] = None, 553 ) -> exp.Show: 554 if target: 555 if isinstance(target, str): 556 self._match_text_seq(target) 557 target_id = self._parse_id_var() 558 else: 559 target_id = None 560 561 log = self._parse_string() if self._match_text_seq("IN") else None 562 563 if this in ("BINLOG EVENTS", "RELAYLOG EVENTS"): 564 position = self._parse_number() if self._match_text_seq("FROM") else None 565 db = None 566 else: 567 position = None 568 db = None 569 570 if self._match(TokenType.FROM): 571 db = self._parse_id_var() 572 elif self._match(TokenType.DOT): 573 db = target_id 574 target_id = self._parse_id_var() 575 576 channel = self._parse_id_var() if self._match_text_seq("FOR", "CHANNEL") else None 577 578 like = self._parse_string() if self._match_text_seq("LIKE") else None 579 where = self._parse_where() 580 581 if this == "PROFILE": 582 types = self._parse_csv(lambda: self._parse_var_from_options(self.PROFILE_TYPES)) 583 query = self._parse_number() if self._match_text_seq("FOR", "QUERY") else None 584 offset = self._parse_number() if self._match_text_seq("OFFSET") else None 585 limit = self._parse_number() if self._match_text_seq("LIMIT") else None 586 else: 587 types, query = None, None 588 offset, limit = self._parse_oldstyle_limit() 589 590 mutex = True if self._match_text_seq("MUTEX") else None 591 mutex = False if self._match_text_seq("STATUS") else mutex 592 593 return self.expression( 594 exp.Show, 595 this=this, 596 target=target_id, 597 full=full, 598 log=log, 599 position=position, 600 db=db, 601 channel=channel, 602 like=like, 603 where=where, 604 types=types, 605 query=query, 606 offset=offset, 607 limit=limit, 608 mutex=mutex, 609 **{"global": global_}, # type: ignore 610 ) 611 612 def _parse_oldstyle_limit( 613 self, 614 ) -> t.Tuple[t.Optional[exp.Expression], t.Optional[exp.Expression]]: 615 limit = None 616 offset = None 617 if self._match_text_seq("LIMIT"): 618 parts = self._parse_csv(self._parse_number) 619 if len(parts) == 1: 620 limit = parts[0] 621 elif len(parts) == 2: 622 limit = parts[1] 623 offset = parts[0] 624 625 return offset, limit 626 627 def _parse_set_item_charset(self, kind: str) -> exp.Expression: 628 this = self._parse_string() or self._parse_unquoted_field() 629 return self.expression(exp.SetItem, this=this, kind=kind) 630 631 def _parse_set_item_names(self) -> exp.Expression: 632 charset = self._parse_string() or self._parse_unquoted_field() 633 if self._match_text_seq("COLLATE"): 634 collate = self._parse_string() or self._parse_unquoted_field() 635 else: 636 collate = None 637 638 return self.expression(exp.SetItem, this=charset, collate=collate, kind="NAMES") 639 640 def _parse_type( 641 self, parse_interval: bool = True, fallback_to_identifier: bool = False 642 ) -> t.Optional[exp.Expression]: 643 # mysql binary is special and can work anywhere, even in order by operations 644 # it operates like a no paren func 645 if self._match(TokenType.BINARY, advance=False): 646 data_type = self._parse_types(check_func=True, allow_identifiers=False) 647 648 if isinstance(data_type, exp.DataType): 649 return self.expression(exp.Cast, this=self._parse_column(), to=data_type) 650 651 return super()._parse_type( 652 parse_interval=parse_interval, fallback_to_identifier=fallback_to_identifier 653 ) 654 655 def _parse_group_concat(self) -> t.Optional[exp.Expression]: 656 def concat_exprs( 657 node: t.Optional[exp.Expression], exprs: t.List[exp.Expression] 658 ) -> exp.Expression: 659 if isinstance(node, exp.Distinct) and len(node.expressions) > 1: 660 concat_exprs = [ 661 self.expression(exp.Concat, expressions=node.expressions, safe=True) 662 ] 663 node.set("expressions", concat_exprs) 664 return node 665 if len(exprs) == 1: 666 return exprs[0] 667 return self.expression(exp.Concat, expressions=args, safe=True) 668 669 args = self._parse_csv(self._parse_lambda) 670 671 if args: 672 order = args[-1] if isinstance(args[-1], exp.Order) else None 673 674 if order: 675 # Order By is the last (or only) expression in the list and has consumed the 'expr' before it, 676 # remove 'expr' from exp.Order and add it back to args 677 args[-1] = order.this 678 order.set("this", concat_exprs(order.this, args)) 679 680 this = order or concat_exprs(args[0], args) 681 else: 682 this = None 683 684 separator = self._parse_field() if self._match(TokenType.SEPARATOR) else None 685 686 return self.expression(exp.GroupConcat, this=this, separator=separator) 687 688 def _parse_json_value(self) -> exp.JSONValue: 689 this = self._parse_bitwise() 690 self._match(TokenType.COMMA) 691 path = self._parse_bitwise() 692 693 returning = self._match(TokenType.RETURNING) and self._parse_type() 694 695 return self.expression( 696 exp.JSONValue, 697 this=this, 698 path=self.dialect.to_json_path(path), 699 returning=returning, 700 on_condition=self._parse_on_condition(), 701 ) 702 703 def _parse_alter_table_alter_index(self) -> exp.AlterIndex: 704 index = self._parse_field(any_token=True) 705 706 if self._match_text_seq("VISIBLE"): 707 visible = True 708 elif self._match_text_seq("INVISIBLE"): 709 visible = False 710 else: 711 visible = None 712 713 return self.expression(exp.AlterIndex, this=index, visible=visible) 714 715 class Generator(generator.Generator): 716 INTERVAL_ALLOWS_PLURAL_FORM = False 717 LOCKING_READS_SUPPORTED = True 718 NULL_ORDERING_SUPPORTED = None 719 JOIN_HINTS = False 720 TABLE_HINTS = True 721 DUPLICATE_KEY_UPDATE_WITH_SET = False 722 QUERY_HINT_SEP = " " 723 VALUES_AS_TABLE = False 724 NVL2_SUPPORTED = False 725 LAST_DAY_SUPPORTS_DATE_PART = False 726 JSON_TYPE_REQUIRED_FOR_EXTRACTION = True 727 JSON_PATH_BRACKETED_KEY_SUPPORTED = False 728 JSON_KEY_VALUE_PAIR_SEP = "," 729 SUPPORTS_TO_NUMBER = False 730 PARSE_JSON_NAME: t.Optional[str] = None 731 PAD_FILL_PATTERN_IS_REQUIRED = True 732 WRAP_DERIVED_VALUES = False 733 VARCHAR_REQUIRES_SIZE = True 734 SUPPORTS_MEDIAN = False 735 736 TRANSFORMS = { 737 **generator.Generator.TRANSFORMS, 738 exp.ArrayAgg: rename_func("GROUP_CONCAT"), 739 exp.CurrentDate: no_paren_current_date_sql, 740 exp.DateDiff: _remove_ts_or_ds_to_date( 741 lambda self, e: self.func("DATEDIFF", e.this, e.expression), ("this", "expression") 742 ), 743 exp.DateAdd: _remove_ts_or_ds_to_date(date_add_sql("ADD")), 744 exp.DateStrToDate: datestrtodate_sql, 745 exp.DateSub: _remove_ts_or_ds_to_date(date_add_sql("SUB")), 746 exp.DateTrunc: _date_trunc_sql, 747 exp.Day: _remove_ts_or_ds_to_date(), 748 exp.DayOfMonth: _remove_ts_or_ds_to_date(rename_func("DAYOFMONTH")), 749 exp.DayOfWeek: _remove_ts_or_ds_to_date(rename_func("DAYOFWEEK")), 750 exp.DayOfYear: _remove_ts_or_ds_to_date(rename_func("DAYOFYEAR")), 751 exp.GroupConcat: lambda self, 752 e: f"""GROUP_CONCAT({self.sql(e, "this")} SEPARATOR {self.sql(e, "separator") or "','"})""", 753 exp.ILike: no_ilike_sql, 754 exp.JSONExtractScalar: arrow_json_extract_sql, 755 exp.Length: length_or_char_length_sql, 756 exp.LogicalOr: rename_func("MAX"), 757 exp.LogicalAnd: rename_func("MIN"), 758 exp.Max: max_or_greatest, 759 exp.Min: min_or_least, 760 exp.Month: _remove_ts_or_ds_to_date(), 761 exp.NullSafeEQ: lambda self, e: self.binary(e, "<=>"), 762 exp.NullSafeNEQ: lambda self, e: f"NOT {self.binary(e, '<=>')}", 763 exp.NumberToStr: rename_func("FORMAT"), 764 exp.Pivot: no_pivot_sql, 765 exp.Select: transforms.preprocess( 766 [ 767 transforms.eliminate_distinct_on, 768 transforms.eliminate_semi_and_anti_joins, 769 transforms.eliminate_qualify, 770 transforms.eliminate_full_outer_join, 771 transforms.unnest_generate_date_array_using_recursive_cte, 772 ] 773 ), 774 exp.StrPosition: lambda self, e: strposition_sql( 775 self, e, func_name="LOCATE", supports_position=True 776 ), 777 exp.StrToDate: _str_to_date_sql, 778 exp.StrToTime: _str_to_date_sql, 779 exp.Stuff: rename_func("INSERT"), 780 exp.TableSample: no_tablesample_sql, 781 exp.TimeFromParts: rename_func("MAKETIME"), 782 exp.TimestampAdd: date_add_interval_sql("DATE", "ADD"), 783 exp.TimestampDiff: lambda self, e: self.func( 784 "TIMESTAMPDIFF", unit_to_var(e), e.expression, e.this 785 ), 786 exp.TimestampSub: date_add_interval_sql("DATE", "SUB"), 787 exp.TimeStrToUnix: rename_func("UNIX_TIMESTAMP"), 788 exp.TimeStrToTime: lambda self, e: timestrtotime_sql( 789 self, 790 e, 791 include_precision=not e.args.get("zone"), 792 ), 793 exp.TimeToStr: _remove_ts_or_ds_to_date( 794 lambda self, e: self.func("DATE_FORMAT", e.this, self.format_time(e)) 795 ), 796 exp.Trim: trim_sql, 797 exp.TryCast: no_trycast_sql, 798 exp.TsOrDsAdd: date_add_sql("ADD"), 799 exp.TsOrDsDiff: lambda self, e: self.func("DATEDIFF", e.this, e.expression), 800 exp.TsOrDsToDate: _ts_or_ds_to_date_sql, 801 exp.Unicode: lambda self, e: f"ORD(CONVERT({self.sql(e.this)} USING utf32))", 802 exp.UnixToTime: _unix_to_time_sql, 803 exp.Week: _remove_ts_or_ds_to_date(), 804 exp.WeekOfYear: _remove_ts_or_ds_to_date(rename_func("WEEKOFYEAR")), 805 exp.Year: _remove_ts_or_ds_to_date(), 806 } 807 808 UNSIGNED_TYPE_MAPPING = { 809 exp.DataType.Type.UBIGINT: "BIGINT", 810 exp.DataType.Type.UINT: "INT", 811 exp.DataType.Type.UMEDIUMINT: "MEDIUMINT", 812 exp.DataType.Type.USMALLINT: "SMALLINT", 813 exp.DataType.Type.UTINYINT: "TINYINT", 814 exp.DataType.Type.UDECIMAL: "DECIMAL", 815 exp.DataType.Type.UDOUBLE: "DOUBLE", 816 } 817 818 TIMESTAMP_TYPE_MAPPING = { 819 exp.DataType.Type.DATETIME2: "DATETIME", 820 exp.DataType.Type.SMALLDATETIME: "DATETIME", 821 exp.DataType.Type.TIMESTAMP: "DATETIME", 822 exp.DataType.Type.TIMESTAMPTZ: "TIMESTAMP", 823 exp.DataType.Type.TIMESTAMPLTZ: "TIMESTAMP", 824 } 825 826 TYPE_MAPPING = { 827 **generator.Generator.TYPE_MAPPING, 828 **UNSIGNED_TYPE_MAPPING, 829 **TIMESTAMP_TYPE_MAPPING, 830 } 831 832 TYPE_MAPPING.pop(exp.DataType.Type.MEDIUMTEXT) 833 TYPE_MAPPING.pop(exp.DataType.Type.LONGTEXT) 834 TYPE_MAPPING.pop(exp.DataType.Type.TINYTEXT) 835 TYPE_MAPPING.pop(exp.DataType.Type.BLOB) 836 TYPE_MAPPING.pop(exp.DataType.Type.MEDIUMBLOB) 837 TYPE_MAPPING.pop(exp.DataType.Type.LONGBLOB) 838 TYPE_MAPPING.pop(exp.DataType.Type.TINYBLOB) 839 840 PROPERTIES_LOCATION = { 841 **generator.Generator.PROPERTIES_LOCATION, 842 exp.TransientProperty: exp.Properties.Location.UNSUPPORTED, 843 exp.VolatileProperty: exp.Properties.Location.UNSUPPORTED, 844 } 845 846 LIMIT_FETCH = "LIMIT" 847 848 LIMIT_ONLY_LITERALS = True 849 850 CHAR_CAST_MAPPING = dict.fromkeys( 851 ( 852 exp.DataType.Type.LONGTEXT, 853 exp.DataType.Type.LONGBLOB, 854 exp.DataType.Type.MEDIUMBLOB, 855 exp.DataType.Type.MEDIUMTEXT, 856 exp.DataType.Type.TEXT, 857 exp.DataType.Type.TINYBLOB, 858 exp.DataType.Type.TINYTEXT, 859 exp.DataType.Type.VARCHAR, 860 ), 861 "CHAR", 862 ) 863 SIGNED_CAST_MAPPING = dict.fromkeys( 864 ( 865 exp.DataType.Type.BIGINT, 866 exp.DataType.Type.BOOLEAN, 867 exp.DataType.Type.INT, 868 exp.DataType.Type.SMALLINT, 869 exp.DataType.Type.TINYINT, 870 exp.DataType.Type.MEDIUMINT, 871 ), 872 "SIGNED", 873 ) 874 875 # MySQL doesn't support many datatypes in cast. 876 # https://dev.mysql.com/doc/refman/8.0/en/cast-functions.html#function_cast 877 CAST_MAPPING = { 878 **CHAR_CAST_MAPPING, 879 **SIGNED_CAST_MAPPING, 880 exp.DataType.Type.UBIGINT: "UNSIGNED", 881 } 882 883 TIMESTAMP_FUNC_TYPES = { 884 exp.DataType.Type.TIMESTAMPTZ, 885 exp.DataType.Type.TIMESTAMPLTZ, 886 } 887 888 # https://dev.mysql.com/doc/refman/8.0/en/keywords.html 889 RESERVED_KEYWORDS = { 890 "accessible", 891 "add", 892 "all", 893 "alter", 894 "analyze", 895 "and", 896 "as", 897 "asc", 898 "asensitive", 899 "before", 900 "between", 901 "bigint", 902 "binary", 903 "blob", 904 "both", 905 "by", 906 "call", 907 "cascade", 908 "case", 909 "change", 910 "char", 911 "character", 912 "check", 913 "collate", 914 "column", 915 "condition", 916 "constraint", 917 "continue", 918 "convert", 919 "create", 920 "cross", 921 "cube", 922 "cume_dist", 923 "current_date", 924 "current_time", 925 "current_timestamp", 926 "current_user", 927 "cursor", 928 "database", 929 "databases", 930 "day_hour", 931 "day_microsecond", 932 "day_minute", 933 "day_second", 934 "dec", 935 "decimal", 936 "declare", 937 "default", 938 "delayed", 939 "delete", 940 "dense_rank", 941 "desc", 942 "describe", 943 "deterministic", 944 "distinct", 945 "distinctrow", 946 "div", 947 "double", 948 "drop", 949 "dual", 950 "each", 951 "else", 952 "elseif", 953 "empty", 954 "enclosed", 955 "escaped", 956 "except", 957 "exists", 958 "exit", 959 "explain", 960 "false", 961 "fetch", 962 "first_value", 963 "float", 964 "float4", 965 "float8", 966 "for", 967 "force", 968 "foreign", 969 "from", 970 "fulltext", 971 "function", 972 "generated", 973 "get", 974 "grant", 975 "group", 976 "grouping", 977 "groups", 978 "having", 979 "high_priority", 980 "hour_microsecond", 981 "hour_minute", 982 "hour_second", 983 "if", 984 "ignore", 985 "in", 986 "index", 987 "infile", 988 "inner", 989 "inout", 990 "insensitive", 991 "insert", 992 "int", 993 "int1", 994 "int2", 995 "int3", 996 "int4", 997 "int8", 998 "integer", 999 "intersect", 1000 "interval", 1001 "into", 1002 "io_after_gtids", 1003 "io_before_gtids", 1004 "is", 1005 "iterate", 1006 "join", 1007 "json_table", 1008 "key", 1009 "keys", 1010 "kill", 1011 "lag", 1012 "last_value", 1013 "lateral", 1014 "lead", 1015 "leading", 1016 "leave", 1017 "left", 1018 "like", 1019 "limit", 1020 "linear", 1021 "lines", 1022 "load", 1023 "localtime", 1024 "localtimestamp", 1025 "lock", 1026 "long", 1027 "longblob", 1028 "longtext", 1029 "loop", 1030 "low_priority", 1031 "master_bind", 1032 "master_ssl_verify_server_cert", 1033 "match", 1034 "maxvalue", 1035 "mediumblob", 1036 "mediumint", 1037 "mediumtext", 1038 "middleint", 1039 "minute_microsecond", 1040 "minute_second", 1041 "mod", 1042 "modifies", 1043 "natural", 1044 "not", 1045 "no_write_to_binlog", 1046 "nth_value", 1047 "ntile", 1048 "null", 1049 "numeric", 1050 "of", 1051 "on", 1052 "optimize", 1053 "optimizer_costs", 1054 "option", 1055 "optionally", 1056 "or", 1057 "order", 1058 "out", 1059 "outer", 1060 "outfile", 1061 "over", 1062 "partition", 1063 "percent_rank", 1064 "precision", 1065 "primary", 1066 "procedure", 1067 "purge", 1068 "range", 1069 "rank", 1070 "read", 1071 "reads", 1072 "read_write", 1073 "real", 1074 "recursive", 1075 "references", 1076 "regexp", 1077 "release", 1078 "rename", 1079 "repeat", 1080 "replace", 1081 "require", 1082 "resignal", 1083 "restrict", 1084 "return", 1085 "revoke", 1086 "right", 1087 "rlike", 1088 "row", 1089 "rows", 1090 "row_number", 1091 "schema", 1092 "schemas", 1093 "second_microsecond", 1094 "select", 1095 "sensitive", 1096 "separator", 1097 "set", 1098 "show", 1099 "signal", 1100 "smallint", 1101 "spatial", 1102 "specific", 1103 "sql", 1104 "sqlexception", 1105 "sqlstate", 1106 "sqlwarning", 1107 "sql_big_result", 1108 "sql_calc_found_rows", 1109 "sql_small_result", 1110 "ssl", 1111 "starting", 1112 "stored", 1113 "straight_join", 1114 "system", 1115 "table", 1116 "terminated", 1117 "then", 1118 "tinyblob", 1119 "tinyint", 1120 "tinytext", 1121 "to", 1122 "trailing", 1123 "trigger", 1124 "true", 1125 "undo", 1126 "union", 1127 "unique", 1128 "unlock", 1129 "unsigned", 1130 "update", 1131 "usage", 1132 "use", 1133 "using", 1134 "utc_date", 1135 "utc_time", 1136 "utc_timestamp", 1137 "values", 1138 "varbinary", 1139 "varchar", 1140 "varcharacter", 1141 "varying", 1142 "virtual", 1143 "when", 1144 "where", 1145 "while", 1146 "window", 1147 "with", 1148 "write", 1149 "xor", 1150 "year_month", 1151 "zerofill", 1152 } 1153 1154 def array_sql(self, expression: exp.Array) -> str: 1155 self.unsupported("Arrays are not supported by MySQL") 1156 return self.function_fallback_sql(expression) 1157 1158 def arraycontainsall_sql(self, expression: exp.ArrayContainsAll) -> str: 1159 self.unsupported("Array operations are not supported by MySQL") 1160 return self.function_fallback_sql(expression) 1161 1162 def dpipe_sql(self, expression: exp.DPipe) -> str: 1163 return self.func("CONCAT", *expression.flatten()) 1164 1165 def extract_sql(self, expression: exp.Extract) -> str: 1166 unit = expression.name 1167 if unit and unit.lower() == "epoch": 1168 return self.func("UNIX_TIMESTAMP", expression.expression) 1169 1170 return super().extract_sql(expression) 1171 1172 def datatype_sql(self, expression: exp.DataType) -> str: 1173 if ( 1174 self.VARCHAR_REQUIRES_SIZE 1175 and expression.is_type(exp.DataType.Type.VARCHAR) 1176 and not expression.expressions 1177 ): 1178 # `VARCHAR` must always have a size - if it doesn't, we always generate `TEXT` 1179 return "TEXT" 1180 1181 # https://dev.mysql.com/doc/refman/8.0/en/numeric-type-syntax.html 1182 result = super().datatype_sql(expression) 1183 if expression.this in self.UNSIGNED_TYPE_MAPPING: 1184 result = f"{result} UNSIGNED" 1185 1186 return result 1187 1188 def jsonarraycontains_sql(self, expression: exp.JSONArrayContains) -> str: 1189 return f"{self.sql(expression, 'this')} MEMBER OF({self.sql(expression, 'expression')})" 1190 1191 def cast_sql(self, expression: exp.Cast, safe_prefix: t.Optional[str] = None) -> str: 1192 if expression.to.this in self.TIMESTAMP_FUNC_TYPES: 1193 return self.func("TIMESTAMP", expression.this) 1194 1195 to = self.CAST_MAPPING.get(expression.to.this) 1196 1197 if to: 1198 expression.to.set("this", to) 1199 return super().cast_sql(expression) 1200 1201 def show_sql(self, expression: exp.Show) -> str: 1202 this = f" {expression.name}" 1203 full = " FULL" if expression.args.get("full") else "" 1204 global_ = " GLOBAL" if expression.args.get("global") else "" 1205 1206 target = self.sql(expression, "target") 1207 target = f" {target}" if target else "" 1208 if expression.name in ("COLUMNS", "INDEX"): 1209 target = f" FROM{target}" 1210 elif expression.name == "GRANTS": 1211 target = f" FOR{target}" 1212 1213 db = self._prefixed_sql("FROM", expression, "db") 1214 1215 like = self._prefixed_sql("LIKE", expression, "like") 1216 where = self.sql(expression, "where") 1217 1218 types = self.expressions(expression, key="types") 1219 types = f" {types}" if types else types 1220 query = self._prefixed_sql("FOR QUERY", expression, "query") 1221 1222 if expression.name == "PROFILE": 1223 offset = self._prefixed_sql("OFFSET", expression, "offset") 1224 limit = self._prefixed_sql("LIMIT", expression, "limit") 1225 else: 1226 offset = "" 1227 limit = self._oldstyle_limit_sql(expression) 1228 1229 log = self._prefixed_sql("IN", expression, "log") 1230 position = self._prefixed_sql("FROM", expression, "position") 1231 1232 channel = self._prefixed_sql("FOR CHANNEL", expression, "channel") 1233 1234 if expression.name == "ENGINE": 1235 mutex_or_status = " MUTEX" if expression.args.get("mutex") else " STATUS" 1236 else: 1237 mutex_or_status = "" 1238 1239 return f"SHOW{full}{global_}{this}{target}{types}{db}{query}{log}{position}{channel}{mutex_or_status}{like}{where}{offset}{limit}" 1240 1241 def altercolumn_sql(self, expression: exp.AlterColumn) -> str: 1242 dtype = self.sql(expression, "dtype") 1243 if not dtype: 1244 return super().altercolumn_sql(expression) 1245 1246 this = self.sql(expression, "this") 1247 return f"MODIFY COLUMN {this} {dtype}" 1248 1249 def _prefixed_sql(self, prefix: str, expression: exp.Expression, arg: str) -> str: 1250 sql = self.sql(expression, arg) 1251 return f" {prefix} {sql}" if sql else "" 1252 1253 def _oldstyle_limit_sql(self, expression: exp.Show) -> str: 1254 limit = self.sql(expression, "limit") 1255 offset = self.sql(expression, "offset") 1256 if limit: 1257 limit_offset = f"{offset}, {limit}" if offset else limit 1258 return f" LIMIT {limit_offset}" 1259 return "" 1260 1261 def chr_sql(self, expression: exp.Chr) -> str: 1262 this = self.expressions(sqls=[expression.this] + expression.expressions) 1263 charset = expression.args.get("charset") 1264 using = f" USING {self.sql(charset)}" if charset else "" 1265 return f"CHAR({this}{using})" 1266 1267 def timestamptrunc_sql(self, expression: exp.TimestampTrunc) -> str: 1268 unit = expression.args.get("unit") 1269 1270 # Pick an old-enough date to avoid negative timestamp diffs 1271 start_ts = "'0000-01-01 00:00:00'" 1272 1273 # Source: https://stackoverflow.com/a/32955740 1274 timestamp_diff = build_date_delta(exp.TimestampDiff)([unit, start_ts, expression.this]) 1275 interval = exp.Interval(this=timestamp_diff, unit=unit) 1276 dateadd = build_date_delta_with_interval(exp.DateAdd)([start_ts, interval]) 1277 1278 return self.sql(dateadd) 1279 1280 def converttimezone_sql(self, expression: exp.ConvertTimezone) -> str: 1281 from_tz = expression.args.get("source_tz") 1282 to_tz = expression.args.get("target_tz") 1283 dt = expression.args.get("timestamp") 1284 1285 return self.func("CONVERT_TZ", dt, from_tz, to_tz) 1286 1287 def attimezone_sql(self, expression: exp.AtTimeZone) -> str: 1288 self.unsupported("AT TIME ZONE is not supported by MySQL") 1289 return self.sql(expression.this) 1290 1291 def isascii_sql(self, expression: exp.IsAscii) -> str: 1292 return f"REGEXP_LIKE({self.sql(expression.this)}, '^[[:ascii:]]*$')" 1293 1294 @unsupported_args("this") 1295 def currentschema_sql(self, expression: exp.CurrentSchema) -> str: 1296 return self.func("SCHEMA")
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}}}
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 "BLOB": TokenType.BLOB, 197 "EXPLAIN": TokenType.DESCRIBE, 198 "FORCE": TokenType.FORCE, 199 "IGNORE": TokenType.IGNORE, 200 "KEY": TokenType.KEY, 201 "LOCK TABLES": TokenType.COMMAND, 202 "LONGBLOB": TokenType.LONGBLOB, 203 "LONGTEXT": TokenType.LONGTEXT, 204 "MEDIUMBLOB": TokenType.MEDIUMBLOB, 205 "TINYBLOB": TokenType.TINYBLOB, 206 "TINYTEXT": TokenType.TINYTEXT, 207 "MEDIUMTEXT": TokenType.MEDIUMTEXT, 208 "MEDIUMINT": TokenType.MEDIUMINT, 209 "MEMBER OF": TokenType.MEMBER_OF, 210 "SEPARATOR": TokenType.SEPARATOR, 211 "SERIAL": TokenType.SERIAL, 212 "START": TokenType.BEGIN, 213 "SIGNED": TokenType.BIGINT, 214 "SIGNED INTEGER": TokenType.BIGINT, 215 "UNLOCK TABLES": TokenType.COMMAND, 216 "UNSIGNED": TokenType.UBIGINT, 217 "UNSIGNED INTEGER": TokenType.UBIGINT, 218 "YEAR": TokenType.YEAR, 219 "_ARMSCII8": TokenType.INTRODUCER, 220 "_ASCII": TokenType.INTRODUCER, 221 "_BIG5": TokenType.INTRODUCER, 222 "_BINARY": TokenType.INTRODUCER, 223 "_CP1250": TokenType.INTRODUCER, 224 "_CP1251": TokenType.INTRODUCER, 225 "_CP1256": TokenType.INTRODUCER, 226 "_CP1257": TokenType.INTRODUCER, 227 "_CP850": TokenType.INTRODUCER, 228 "_CP852": TokenType.INTRODUCER, 229 "_CP866": TokenType.INTRODUCER, 230 "_CP932": TokenType.INTRODUCER, 231 "_DEC8": TokenType.INTRODUCER, 232 "_EUCJPMS": TokenType.INTRODUCER, 233 "_EUCKR": TokenType.INTRODUCER, 234 "_GB18030": TokenType.INTRODUCER, 235 "_GB2312": TokenType.INTRODUCER, 236 "_GBK": TokenType.INTRODUCER, 237 "_GEOSTD8": TokenType.INTRODUCER, 238 "_GREEK": TokenType.INTRODUCER, 239 "_HEBREW": TokenType.INTRODUCER, 240 "_HP8": TokenType.INTRODUCER, 241 "_KEYBCS2": TokenType.INTRODUCER, 242 "_KOI8R": TokenType.INTRODUCER, 243 "_KOI8U": TokenType.INTRODUCER, 244 "_LATIN1": TokenType.INTRODUCER, 245 "_LATIN2": TokenType.INTRODUCER, 246 "_LATIN5": TokenType.INTRODUCER, 247 "_LATIN7": TokenType.INTRODUCER, 248 "_MACCE": TokenType.INTRODUCER, 249 "_MACROMAN": TokenType.INTRODUCER, 250 "_SJIS": TokenType.INTRODUCER, 251 "_SWE7": TokenType.INTRODUCER, 252 "_TIS620": TokenType.INTRODUCER, 253 "_UCS2": TokenType.INTRODUCER, 254 "_UJIS": TokenType.INTRODUCER, 255 # https://dev.mysql.com/doc/refman/8.0/en/string-literals.html 256 "_UTF8": TokenType.INTRODUCER, 257 "_UTF16": TokenType.INTRODUCER, 258 "_UTF16LE": TokenType.INTRODUCER, 259 "_UTF32": TokenType.INTRODUCER, 260 "_UTF8MB3": TokenType.INTRODUCER, 261 "_UTF8MB4": TokenType.INTRODUCER, 262 "@@": TokenType.SESSION_PARAMETER, 263 } 264 265 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_SCHEMA': <TokenType.CURRENT_SCHEMA: 'CURRENT_SCHEMA'>, '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'>, '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'>, 'INT128': <TokenType.INT128: 'INT128'>, 'INT256': <TokenType.INT256: 'INT256'>, 'LONG': <TokenType.BIGINT: 'BIGINT'>, 'BIGINT': <TokenType.BIGINT: 'BIGINT'>, 'INT8': <TokenType.TINYINT: 'TINYINT'>, 'UINT': <TokenType.UINT: 'UINT'>, 'UINT128': <TokenType.UINT128: 'UINT128'>, 'UINT256': <TokenType.UINT256: 'UINT256'>, '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.BLOB: 'BLOB'>, '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.EXECUTE: 'EXECUTE'>, <TokenType.FETCH: 'FETCH'>, <TokenType.REPLACE: 'REPLACE'>, <TokenType.RENAME: 'RENAME'>, <TokenType.COMMAND: 'COMMAND'>}
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
267 class Parser(parser.Parser): 268 FUNC_TOKENS = { 269 *parser.Parser.FUNC_TOKENS, 270 TokenType.DATABASE, 271 TokenType.SCHEMA, 272 TokenType.VALUES, 273 } 274 275 CONJUNCTION = { 276 **parser.Parser.CONJUNCTION, 277 TokenType.DAMP: exp.And, 278 TokenType.XOR: exp.Xor, 279 } 280 281 DISJUNCTION = { 282 **parser.Parser.DISJUNCTION, 283 TokenType.DPIPE: exp.Or, 284 } 285 286 TABLE_ALIAS_TOKENS = ( 287 parser.Parser.TABLE_ALIAS_TOKENS - parser.Parser.TABLE_INDEX_HINT_TOKENS 288 ) 289 290 RANGE_PARSERS = { 291 **parser.Parser.RANGE_PARSERS, 292 TokenType.MEMBER_OF: lambda self, this: self.expression( 293 exp.JSONArrayContains, 294 this=this, 295 expression=self._parse_wrapped(self._parse_expression), 296 ), 297 } 298 299 FUNCTIONS = { 300 **parser.Parser.FUNCTIONS, 301 "CONVERT_TZ": lambda args: exp.ConvertTimezone( 302 source_tz=seq_get(args, 1), target_tz=seq_get(args, 2), timestamp=seq_get(args, 0) 303 ), 304 "CURDATE": exp.CurrentDate.from_arg_list, 305 "DATE": lambda args: exp.TsOrDsToDate(this=seq_get(args, 0)), 306 "DATE_ADD": build_date_delta_with_interval(exp.DateAdd), 307 "DATE_FORMAT": build_formatted_time(exp.TimeToStr, "mysql"), 308 "DATE_SUB": build_date_delta_with_interval(exp.DateSub), 309 "DAY": lambda args: exp.Day(this=exp.TsOrDsToDate(this=seq_get(args, 0))), 310 "DAYOFMONTH": lambda args: exp.DayOfMonth(this=exp.TsOrDsToDate(this=seq_get(args, 0))), 311 "DAYOFWEEK": lambda args: exp.DayOfWeek(this=exp.TsOrDsToDate(this=seq_get(args, 0))), 312 "DAYOFYEAR": lambda args: exp.DayOfYear(this=exp.TsOrDsToDate(this=seq_get(args, 0))), 313 "FORMAT": exp.NumberToStr.from_arg_list, 314 "FROM_UNIXTIME": build_formatted_time(exp.UnixToTime, "mysql"), 315 "ISNULL": isnull_to_is_null, 316 "LENGTH": lambda args: exp.Length(this=seq_get(args, 0), binary=True), 317 "MAKETIME": exp.TimeFromParts.from_arg_list, 318 "MONTH": lambda args: exp.Month(this=exp.TsOrDsToDate(this=seq_get(args, 0))), 319 "MONTHNAME": lambda args: exp.TimeToStr( 320 this=exp.TsOrDsToDate(this=seq_get(args, 0)), 321 format=exp.Literal.string("%B"), 322 ), 323 "SCHEMA": exp.CurrentSchema.from_arg_list, 324 "DATABASE": exp.CurrentSchema.from_arg_list, 325 "STR_TO_DATE": _str_to_date, 326 "TIMESTAMPDIFF": build_date_delta(exp.TimestampDiff), 327 "TO_DAYS": lambda args: exp.paren( 328 exp.DateDiff( 329 this=exp.TsOrDsToDate(this=seq_get(args, 0)), 330 expression=exp.TsOrDsToDate(this=exp.Literal.string("0000-01-01")), 331 unit=exp.var("DAY"), 332 ) 333 + 1 334 ), 335 "WEEK": lambda args: exp.Week( 336 this=exp.TsOrDsToDate(this=seq_get(args, 0)), mode=seq_get(args, 1) 337 ), 338 "WEEKOFYEAR": lambda args: exp.WeekOfYear(this=exp.TsOrDsToDate(this=seq_get(args, 0))), 339 "YEAR": lambda args: exp.Year(this=exp.TsOrDsToDate(this=seq_get(args, 0))), 340 } 341 342 FUNCTION_PARSERS = { 343 **parser.Parser.FUNCTION_PARSERS, 344 "CHAR": lambda self: self.expression( 345 exp.Chr, 346 expressions=self._parse_csv(self._parse_assignment), 347 charset=self._match(TokenType.USING) and self._parse_var(), 348 ), 349 "GROUP_CONCAT": lambda self: self._parse_group_concat(), 350 # https://dev.mysql.com/doc/refman/5.7/en/miscellaneous-functions.html#function_values 351 "VALUES": lambda self: self.expression( 352 exp.Anonymous, this="VALUES", expressions=[self._parse_id_var()] 353 ), 354 "JSON_VALUE": lambda self: self._parse_json_value(), 355 } 356 357 STATEMENT_PARSERS = { 358 **parser.Parser.STATEMENT_PARSERS, 359 TokenType.SHOW: lambda self: self._parse_show(), 360 } 361 362 SHOW_PARSERS = { 363 "BINARY LOGS": _show_parser("BINARY LOGS"), 364 "MASTER LOGS": _show_parser("BINARY LOGS"), 365 "BINLOG EVENTS": _show_parser("BINLOG EVENTS"), 366 "CHARACTER SET": _show_parser("CHARACTER SET"), 367 "CHARSET": _show_parser("CHARACTER SET"), 368 "COLLATION": _show_parser("COLLATION"), 369 "FULL COLUMNS": _show_parser("COLUMNS", target="FROM", full=True), 370 "COLUMNS": _show_parser("COLUMNS", target="FROM"), 371 "CREATE DATABASE": _show_parser("CREATE DATABASE", target=True), 372 "CREATE EVENT": _show_parser("CREATE EVENT", target=True), 373 "CREATE FUNCTION": _show_parser("CREATE FUNCTION", target=True), 374 "CREATE PROCEDURE": _show_parser("CREATE PROCEDURE", target=True), 375 "CREATE TABLE": _show_parser("CREATE TABLE", target=True), 376 "CREATE TRIGGER": _show_parser("CREATE TRIGGER", target=True), 377 "CREATE VIEW": _show_parser("CREATE VIEW", target=True), 378 "DATABASES": _show_parser("DATABASES"), 379 "SCHEMAS": _show_parser("DATABASES"), 380 "ENGINE": _show_parser("ENGINE", target=True), 381 "STORAGE ENGINES": _show_parser("ENGINES"), 382 "ENGINES": _show_parser("ENGINES"), 383 "ERRORS": _show_parser("ERRORS"), 384 "EVENTS": _show_parser("EVENTS"), 385 "FUNCTION CODE": _show_parser("FUNCTION CODE", target=True), 386 "FUNCTION STATUS": _show_parser("FUNCTION STATUS"), 387 "GRANTS": _show_parser("GRANTS", target="FOR"), 388 "INDEX": _show_parser("INDEX", target="FROM"), 389 "MASTER STATUS": _show_parser("MASTER STATUS"), 390 "OPEN TABLES": _show_parser("OPEN TABLES"), 391 "PLUGINS": _show_parser("PLUGINS"), 392 "PROCEDURE CODE": _show_parser("PROCEDURE CODE", target=True), 393 "PROCEDURE STATUS": _show_parser("PROCEDURE STATUS"), 394 "PRIVILEGES": _show_parser("PRIVILEGES"), 395 "FULL PROCESSLIST": _show_parser("PROCESSLIST", full=True), 396 "PROCESSLIST": _show_parser("PROCESSLIST"), 397 "PROFILE": _show_parser("PROFILE"), 398 "PROFILES": _show_parser("PROFILES"), 399 "RELAYLOG EVENTS": _show_parser("RELAYLOG EVENTS"), 400 "REPLICAS": _show_parser("REPLICAS"), 401 "SLAVE HOSTS": _show_parser("REPLICAS"), 402 "REPLICA STATUS": _show_parser("REPLICA STATUS"), 403 "SLAVE STATUS": _show_parser("REPLICA STATUS"), 404 "GLOBAL STATUS": _show_parser("STATUS", global_=True), 405 "SESSION STATUS": _show_parser("STATUS"), 406 "STATUS": _show_parser("STATUS"), 407 "TABLE STATUS": _show_parser("TABLE STATUS"), 408 "FULL TABLES": _show_parser("TABLES", full=True), 409 "TABLES": _show_parser("TABLES"), 410 "TRIGGERS": _show_parser("TRIGGERS"), 411 "GLOBAL VARIABLES": _show_parser("VARIABLES", global_=True), 412 "SESSION VARIABLES": _show_parser("VARIABLES"), 413 "VARIABLES": _show_parser("VARIABLES"), 414 "WARNINGS": _show_parser("WARNINGS"), 415 } 416 417 PROPERTY_PARSERS = { 418 **parser.Parser.PROPERTY_PARSERS, 419 "LOCK": lambda self: self._parse_property_assignment(exp.LockProperty), 420 } 421 422 SET_PARSERS = { 423 **parser.Parser.SET_PARSERS, 424 "PERSIST": lambda self: self._parse_set_item_assignment("PERSIST"), 425 "PERSIST_ONLY": lambda self: self._parse_set_item_assignment("PERSIST_ONLY"), 426 "CHARACTER SET": lambda self: self._parse_set_item_charset("CHARACTER SET"), 427 "CHARSET": lambda self: self._parse_set_item_charset("CHARACTER SET"), 428 "NAMES": lambda self: self._parse_set_item_names(), 429 } 430 431 CONSTRAINT_PARSERS = { 432 **parser.Parser.CONSTRAINT_PARSERS, 433 "FULLTEXT": lambda self: self._parse_index_constraint(kind="FULLTEXT"), 434 "INDEX": lambda self: self._parse_index_constraint(), 435 "KEY": lambda self: self._parse_index_constraint(), 436 "SPATIAL": lambda self: self._parse_index_constraint(kind="SPATIAL"), 437 } 438 439 ALTER_PARSERS = { 440 **parser.Parser.ALTER_PARSERS, 441 "MODIFY": lambda self: self._parse_alter_table_alter(), 442 } 443 444 ALTER_ALTER_PARSERS = { 445 **parser.Parser.ALTER_ALTER_PARSERS, 446 "INDEX": lambda self: self._parse_alter_table_alter_index(), 447 } 448 449 SCHEMA_UNNAMED_CONSTRAINTS = { 450 *parser.Parser.SCHEMA_UNNAMED_CONSTRAINTS, 451 "FULLTEXT", 452 "INDEX", 453 "KEY", 454 "SPATIAL", 455 } 456 457 PROFILE_TYPES: parser.OPTIONS_TYPE = { 458 **dict.fromkeys(("ALL", "CPU", "IPC", "MEMORY", "SOURCE", "SWAPS"), tuple()), 459 "BLOCK": ("IO",), 460 "CONTEXT": ("SWITCHES",), 461 "PAGE": ("FAULTS",), 462 } 463 464 TYPE_TOKENS = { 465 *parser.Parser.TYPE_TOKENS, 466 TokenType.SET, 467 } 468 469 ENUM_TYPE_TOKENS = { 470 *parser.Parser.ENUM_TYPE_TOKENS, 471 TokenType.SET, 472 } 473 474 # SELECT [ ALL | DISTINCT | DISTINCTROW ] [ <OPERATION_MODIFIERS> ] 475 OPERATION_MODIFIERS = { 476 "HIGH_PRIORITY", 477 "STRAIGHT_JOIN", 478 "SQL_SMALL_RESULT", 479 "SQL_BIG_RESULT", 480 "SQL_BUFFER_RESULT", 481 "SQL_NO_CACHE", 482 "SQL_CALC_FOUND_ROWS", 483 } 484 485 LOG_DEFAULTS_TO_LN = True 486 STRING_ALIASES = True 487 VALUES_FOLLOWED_BY_PAREN = False 488 SUPPORTS_PARTITION_SELECTION = True 489 490 def _parse_primary_key_part(self) -> t.Optional[exp.Expression]: 491 this = self._parse_id_var() 492 if not self._match(TokenType.L_PAREN): 493 return this 494 495 expression = self._parse_number() 496 self._match_r_paren() 497 return self.expression(exp.ColumnPrefix, this=this, expression=expression) 498 499 def _parse_index_constraint( 500 self, kind: t.Optional[str] = None 501 ) -> exp.IndexColumnConstraint: 502 if kind: 503 self._match_texts(("INDEX", "KEY")) 504 505 this = self._parse_id_var(any_token=False) 506 index_type = self._match(TokenType.USING) and self._advance_any() and self._prev.text 507 expressions = self._parse_wrapped_csv(self._parse_ordered) 508 509 options = [] 510 while True: 511 if self._match_text_seq("KEY_BLOCK_SIZE"): 512 self._match(TokenType.EQ) 513 opt = exp.IndexConstraintOption(key_block_size=self._parse_number()) 514 elif self._match(TokenType.USING): 515 opt = exp.IndexConstraintOption(using=self._advance_any() and self._prev.text) 516 elif self._match_text_seq("WITH", "PARSER"): 517 opt = exp.IndexConstraintOption(parser=self._parse_var(any_token=True)) 518 elif self._match(TokenType.COMMENT): 519 opt = exp.IndexConstraintOption(comment=self._parse_string()) 520 elif self._match_text_seq("VISIBLE"): 521 opt = exp.IndexConstraintOption(visible=True) 522 elif self._match_text_seq("INVISIBLE"): 523 opt = exp.IndexConstraintOption(visible=False) 524 elif self._match_text_seq("ENGINE_ATTRIBUTE"): 525 self._match(TokenType.EQ) 526 opt = exp.IndexConstraintOption(engine_attr=self._parse_string()) 527 elif self._match_text_seq("SECONDARY_ENGINE_ATTRIBUTE"): 528 self._match(TokenType.EQ) 529 opt = exp.IndexConstraintOption(secondary_engine_attr=self._parse_string()) 530 else: 531 opt = None 532 533 if not opt: 534 break 535 536 options.append(opt) 537 538 return self.expression( 539 exp.IndexColumnConstraint, 540 this=this, 541 expressions=expressions, 542 kind=kind, 543 index_type=index_type, 544 options=options, 545 ) 546 547 def _parse_show_mysql( 548 self, 549 this: str, 550 target: bool | str = False, 551 full: t.Optional[bool] = None, 552 global_: t.Optional[bool] = None, 553 ) -> exp.Show: 554 if target: 555 if isinstance(target, str): 556 self._match_text_seq(target) 557 target_id = self._parse_id_var() 558 else: 559 target_id = None 560 561 log = self._parse_string() if self._match_text_seq("IN") else None 562 563 if this in ("BINLOG EVENTS", "RELAYLOG EVENTS"): 564 position = self._parse_number() if self._match_text_seq("FROM") else None 565 db = None 566 else: 567 position = None 568 db = None 569 570 if self._match(TokenType.FROM): 571 db = self._parse_id_var() 572 elif self._match(TokenType.DOT): 573 db = target_id 574 target_id = self._parse_id_var() 575 576 channel = self._parse_id_var() if self._match_text_seq("FOR", "CHANNEL") else None 577 578 like = self._parse_string() if self._match_text_seq("LIKE") else None 579 where = self._parse_where() 580 581 if this == "PROFILE": 582 types = self._parse_csv(lambda: self._parse_var_from_options(self.PROFILE_TYPES)) 583 query = self._parse_number() if self._match_text_seq("FOR", "QUERY") else None 584 offset = self._parse_number() if self._match_text_seq("OFFSET") else None 585 limit = self._parse_number() if self._match_text_seq("LIMIT") else None 586 else: 587 types, query = None, None 588 offset, limit = self._parse_oldstyle_limit() 589 590 mutex = True if self._match_text_seq("MUTEX") else None 591 mutex = False if self._match_text_seq("STATUS") else mutex 592 593 return self.expression( 594 exp.Show, 595 this=this, 596 target=target_id, 597 full=full, 598 log=log, 599 position=position, 600 db=db, 601 channel=channel, 602 like=like, 603 where=where, 604 types=types, 605 query=query, 606 offset=offset, 607 limit=limit, 608 mutex=mutex, 609 **{"global": global_}, # type: ignore 610 ) 611 612 def _parse_oldstyle_limit( 613 self, 614 ) -> t.Tuple[t.Optional[exp.Expression], t.Optional[exp.Expression]]: 615 limit = None 616 offset = None 617 if self._match_text_seq("LIMIT"): 618 parts = self._parse_csv(self._parse_number) 619 if len(parts) == 1: 620 limit = parts[0] 621 elif len(parts) == 2: 622 limit = parts[1] 623 offset = parts[0] 624 625 return offset, limit 626 627 def _parse_set_item_charset(self, kind: str) -> exp.Expression: 628 this = self._parse_string() or self._parse_unquoted_field() 629 return self.expression(exp.SetItem, this=this, kind=kind) 630 631 def _parse_set_item_names(self) -> exp.Expression: 632 charset = self._parse_string() or self._parse_unquoted_field() 633 if self._match_text_seq("COLLATE"): 634 collate = self._parse_string() or self._parse_unquoted_field() 635 else: 636 collate = None 637 638 return self.expression(exp.SetItem, this=charset, collate=collate, kind="NAMES") 639 640 def _parse_type( 641 self, parse_interval: bool = True, fallback_to_identifier: bool = False 642 ) -> t.Optional[exp.Expression]: 643 # mysql binary is special and can work anywhere, even in order by operations 644 # it operates like a no paren func 645 if self._match(TokenType.BINARY, advance=False): 646 data_type = self._parse_types(check_func=True, allow_identifiers=False) 647 648 if isinstance(data_type, exp.DataType): 649 return self.expression(exp.Cast, this=self._parse_column(), to=data_type) 650 651 return super()._parse_type( 652 parse_interval=parse_interval, fallback_to_identifier=fallback_to_identifier 653 ) 654 655 def _parse_group_concat(self) -> t.Optional[exp.Expression]: 656 def concat_exprs( 657 node: t.Optional[exp.Expression], exprs: t.List[exp.Expression] 658 ) -> exp.Expression: 659 if isinstance(node, exp.Distinct) and len(node.expressions) > 1: 660 concat_exprs = [ 661 self.expression(exp.Concat, expressions=node.expressions, safe=True) 662 ] 663 node.set("expressions", concat_exprs) 664 return node 665 if len(exprs) == 1: 666 return exprs[0] 667 return self.expression(exp.Concat, expressions=args, safe=True) 668 669 args = self._parse_csv(self._parse_lambda) 670 671 if args: 672 order = args[-1] if isinstance(args[-1], exp.Order) else None 673 674 if order: 675 # Order By is the last (or only) expression in the list and has consumed the 'expr' before it, 676 # remove 'expr' from exp.Order and add it back to args 677 args[-1] = order.this 678 order.set("this", concat_exprs(order.this, args)) 679 680 this = order or concat_exprs(args[0], args) 681 else: 682 this = None 683 684 separator = self._parse_field() if self._match(TokenType.SEPARATOR) else None 685 686 return self.expression(exp.GroupConcat, this=this, separator=separator) 687 688 def _parse_json_value(self) -> exp.JSONValue: 689 this = self._parse_bitwise() 690 self._match(TokenType.COMMA) 691 path = self._parse_bitwise() 692 693 returning = self._match(TokenType.RETURNING) and self._parse_type() 694 695 return self.expression( 696 exp.JSONValue, 697 this=this, 698 path=self.dialect.to_json_path(path), 699 returning=returning, 700 on_condition=self._parse_on_condition(), 701 ) 702 703 def _parse_alter_table_alter_index(self) -> exp.AlterIndex: 704 index = self._parse_field(any_token=True) 705 706 if self._match_text_seq("VISIBLE"): 707 visible = True 708 elif self._match_text_seq("INVISIBLE"): 709 visible = False 710 else: 711 visible = None 712 713 return self.expression(exp.AlterIndex, this=index, visible=visible)
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.ROW: 'ROW'>, <TokenType.BOOLEAN: 'BOOLEAN'>, <TokenType.RING: 'RING'>, <TokenType.CURRENT_SCHEMA: 'CURRENT_SCHEMA'>, <TokenType.DECIMAL256: 'DECIMAL256'>, <TokenType.POLYGON: 'POLYGON'>, <TokenType.SMALLDATETIME: 'SMALLDATETIME'>, <TokenType.WINDOW: 'WINDOW'>, <TokenType.MULTILINESTRING: 'MULTILINESTRING'>, <TokenType.NAME: 'NAME'>, <TokenType.MONEY: 'MONEY'>, <TokenType.IPV4: 'IPV4'>, <TokenType.MAP: 'MAP'>, <TokenType.BLOB: 'BLOB'>, <TokenType.ILIKE: 'ILIKE'>, <TokenType.INT128: 'INT128'>, <TokenType.JSON: 'JSON'>, <TokenType.UDOUBLE: 'UDOUBLE'>, <TokenType.SMALLMONEY: 'SMALLMONEY'>, <TokenType.NULLABLE: 'NULLABLE'>, <TokenType.TIMESTAMP_MS: 'TIMESTAMP_MS'>, <TokenType.NEXT: 'NEXT'>, <TokenType.INSERT: 'INSERT'>, <TokenType.VAR: 'VAR'>, <TokenType.INT8MULTIRANGE: 'INT8MULTIRANGE'>, <TokenType.PRIMARY_KEY: 'PRIMARY_KEY'>, <TokenType.STRUCT: 'STRUCT'>, <TokenType.ENUM8: 'ENUM8'>, <TokenType.FILTER: 'FILTER'>, <TokenType.XOR: 'XOR'>, <TokenType.DATABASE: 'DATABASE'>, <TokenType.TIMESTAMP_S: 'TIMESTAMP_S'>, <TokenType.NESTED: 'NESTED'>, <TokenType.BINARY: 'BINARY'>, <TokenType.ANY: 'ANY'>, <TokenType.IPV6: 'IPV6'>, <TokenType.UNION: 'UNION'>, <TokenType.DECIMAL: 'DECIMAL'>, <TokenType.UINT256: 'UINT256'>, <TokenType.ENUM: 'ENUM'>, <TokenType.INT4RANGE: 'INT4RANGE'>, <TokenType.POINT: 'POINT'>, <TokenType.TIMESTAMP: 'TIMESTAMP'>, <TokenType.SCHEMA: 'SCHEMA'>, <TokenType.MULTIPOLYGON: 'MULTIPOLYGON'>, <TokenType.TINYINT: 'TINYINT'>, <TokenType.TSMULTIRANGE: 'TSMULTIRANGE'>, <TokenType.FLOAT: 'FLOAT'>, <TokenType.VARCHAR: 'VARCHAR'>, <TokenType.TINYBLOB: 'TINYBLOB'>, <TokenType.NUMRANGE: 'NUMRANGE'>, <TokenType.BIGDECIMAL: 'BIGDECIMAL'>, <TokenType.DATERANGE: 'DATERANGE'>, <TokenType.AGGREGATEFUNCTION: 'AGGREGATEFUNCTION'>, <TokenType.MEDIUMTEXT: 'MEDIUMTEXT'>, <TokenType.FIXEDSTRING: 'FIXEDSTRING'>, <TokenType.GEOGRAPHY: 'GEOGRAPHY'>, <TokenType.INDEX: 'INDEX'>, <TokenType.VECTOR: 'VECTOR'>, <TokenType.GEOMETRY: 'GEOMETRY'>, <TokenType.CURRENT_USER: 'CURRENT_USER'>, <TokenType.RANGE: 'RANGE'>, <TokenType.BIGSERIAL: 'BIGSERIAL'>, <TokenType.ALL: 'ALL'>, <TokenType.INT8RANGE: 'INT8RANGE'>, <TokenType.HSTORE: 'HSTORE'>, <TokenType.GLOB: 'GLOB'>, <TokenType.DECIMAL64: 'DECIMAL64'>, <TokenType.OBJECT: 'OBJECT'>, <TokenType.CURRENT_TIMESTAMP: 'CURRENT_TIMESTAMP'>, <TokenType.OFFSET: 'OFFSET'>, <TokenType.USMALLINT: 'USMALLINT'>, <TokenType.TIME: 'TIME'>, <TokenType.PSEUDO_TYPE: 'PSEUDO_TYPE'>, <TokenType.SIMPLEAGGREGATEFUNCTION: 'SIMPLEAGGREGATEFUNCTION'>, <TokenType.TIMETZ: 'TIMETZ'>, <TokenType.UINT: 'UINT'>, <TokenType.UNKNOWN: 'UNKNOWN'>, <TokenType.MEDIUMBLOB: 'MEDIUMBLOB'>, <TokenType.TEXT: 'TEXT'>, <TokenType.IMAGE: 'IMAGE'>, <TokenType.UTINYINT: 'UTINYINT'>, <TokenType.MEDIUMINT: 'MEDIUMINT'>, <TokenType.LIKE: 'LIKE'>, <TokenType.LINESTRING: 'LINESTRING'>, <TokenType.INT4MULTIRANGE: 'INT4MULTIRANGE'>, <TokenType.TRUNCATE: 'TRUNCATE'>, <TokenType.DATE: 'DATE'>, <TokenType.SUPER: 'SUPER'>, <TokenType.DOUBLE: 'DOUBLE'>, <TokenType.RLIKE: 'RLIKE'>, <TokenType.ROWVERSION: 'ROWVERSION'>, <TokenType.SOME: 'SOME'>, <TokenType.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, <TokenType.TDIGEST: 'TDIGEST'>, <TokenType.SERIAL: 'SERIAL'>, <TokenType.OBJECT_IDENTIFIER: 'OBJECT_IDENTIFIER'>, <TokenType.CHAR: 'CHAR'>, <TokenType.DATETIME2: 'DATETIME2'>, <TokenType.SMALLINT: 'SMALLINT'>, <TokenType.CURRENT_TIME: 'CURRENT_TIME'>, <TokenType.IDENTIFIER: 'IDENTIFIER'>, <TokenType.EXISTS: 'EXISTS'>, <TokenType.CURRENT_DATE: 'CURRENT_DATE'>, <TokenType.JSONB: 'JSONB'>, <TokenType.UMEDIUMINT: 'UMEDIUMINT'>, <TokenType.TSTZRANGE: 'TSTZRANGE'>, <TokenType.ENUM16: 'ENUM16'>, <TokenType.LEFT: 'LEFT'>, <TokenType.TSRANGE: 'TSRANGE'>, <TokenType.UBIGINT: 'UBIGINT'>, <TokenType.HLLSKETCH: 'HLLSKETCH'>, <TokenType.LOWCARDINALITY: 'LOWCARDINALITY'>, <TokenType.CURRENT_DATETIME: 'CURRENT_DATETIME'>, <TokenType.DATETIME64: 'DATETIME64'>, <TokenType.NCHAR: 'NCHAR'>, <TokenType.INT: 'INT'>, <TokenType.RIGHT: 'RIGHT'>, <TokenType.UNNEST: 'UNNEST'>, <TokenType.YEAR: 'YEAR'>, <TokenType.IPPREFIX: 'IPPREFIX'>, <TokenType.IPADDRESS: 'IPADDRESS'>, <TokenType.TIMESTAMPNTZ: 'TIMESTAMPNTZ'>, <TokenType.DATETIME: 'DATETIME'>, <TokenType.VALUES: 'VALUES'>, <TokenType.VARBINARY: 'VARBINARY'>, <TokenType.COLLATE: 'COLLATE'>, <TokenType.BPCHAR: 'BPCHAR'>, <TokenType.NVARCHAR: 'NVARCHAR'>, <TokenType.SMALLSERIAL: 'SMALLSERIAL'>, <TokenType.INET: 'INET'>, <TokenType.UDECIMAL: 'UDECIMAL'>, <TokenType.DECIMAL32: 'DECIMAL32'>, <TokenType.TSTZMULTIRANGE: 'TSTZMULTIRANGE'>, <TokenType.DECIMAL128: 'DECIMAL128'>, <TokenType.XML: 'XML'>, <TokenType.COMMAND: 'COMMAND'>, <TokenType.DYNAMIC: 'DYNAMIC'>, <TokenType.UUID: 'UUID'>, <TokenType.NUMMULTIRANGE: 'NUMMULTIRANGE'>, <TokenType.BIGINT: 'BIGINT'>, <TokenType.REPLACE: 'REPLACE'>, <TokenType.TIMESTAMP_NS: 'TIMESTAMP_NS'>, <TokenType.LONGTEXT: 'LONGTEXT'>, <TokenType.TABLE: 'TABLE'>, <TokenType.DATE32: 'DATE32'>, <TokenType.DATEMULTIRANGE: 'DATEMULTIRANGE'>, <TokenType.USERDEFINED: 'USERDEFINED'>, <TokenType.INTERVAL: 'INTERVAL'>, <TokenType.LIST: 'LIST'>, <TokenType.FIRST: 'FIRST'>, <TokenType.TIMESTAMPTZ: 'TIMESTAMPTZ'>, <TokenType.INT256: 'INT256'>, <TokenType.UINT128: 'UINT128'>, <TokenType.VARIANT: 'VARIANT'>, <TokenType.MERGE: 'MERGE'>, <TokenType.SEQUENCE: 'SEQUENCE'>, <TokenType.LONGBLOB: 'LONGBLOB'>, <TokenType.NULL: 'NULL'>, <TokenType.BIT: 'BIT'>, <TokenType.ARRAY: 'ARRAY'>, <TokenType.ISNULL: 'ISNULL'>, <TokenType.TINYTEXT: 'TINYTEXT'>, <TokenType.FORMAT: 'FORMAT'>}
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.SINK: 'SINK'>, <TokenType.ROW: 'ROW'>, <TokenType.BOOLEAN: 'BOOLEAN'>, <TokenType.RING: 'RING'>, <TokenType.CURRENT_SCHEMA: 'CURRENT_SCHEMA'>, <TokenType.AUTO_INCREMENT: 'AUTO_INCREMENT'>, <TokenType.END: 'END'>, <TokenType.DECIMAL256: 'DECIMAL256'>, <TokenType.POLYGON: 'POLYGON'>, <TokenType.SMALLDATETIME: 'SMALLDATETIME'>, <TokenType.VOLATILE: 'VOLATILE'>, <TokenType.MULTILINESTRING: 'MULTILINESTRING'>, <TokenType.NAME: 'NAME'>, <TokenType.MODEL: 'MODEL'>, <TokenType.PIVOT: 'PIVOT'>, <TokenType.ROLLUP: 'ROLLUP'>, <TokenType.MONEY: 'MONEY'>, <TokenType.SET: 'SET'>, <TokenType.IPV4: 'IPV4'>, <TokenType.FINAL: 'FINAL'>, <TokenType.MAP: 'MAP'>, <TokenType.BLOB: 'BLOB'>, <TokenType.INT128: 'INT128'>, <TokenType.JSON: 'JSON'>, <TokenType.UDOUBLE: 'UDOUBLE'>, <TokenType.SMALLMONEY: 'SMALLMONEY'>, <TokenType.NULLABLE: 'NULLABLE'>, <TokenType.TIMESTAMP_MS: 'TIMESTAMP_MS'>, <TokenType.VAR: 'VAR'>, <TokenType.NEXT: 'NEXT'>, <TokenType.STRUCT: 'STRUCT'>, <TokenType.ROWS: 'ROWS'>, <TokenType.ENUM8: 'ENUM8'>, <TokenType.FILTER: 'FILTER'>, <TokenType.STORAGE_INTEGRATION: 'STORAGE_INTEGRATION'>, <TokenType.DATABASE: 'DATABASE'>, <TokenType.COMMENT: 'COMMENT'>, <TokenType.TIMESTAMP_S: 'TIMESTAMP_S'>, <TokenType.NESTED: 'NESTED'>, <TokenType.BINARY: 'BINARY'>, <TokenType.ANY: 'ANY'>, <TokenType.IPV6: 'IPV6'>, <TokenType.DECIMAL: 'DECIMAL'>, <TokenType.CACHE: 'CACHE'>, <TokenType.UINT256: 'UINT256'>, <TokenType.ESCAPE: 'ESCAPE'>, <TokenType.ENUM: 'ENUM'>, <TokenType.ASC: 'ASC'>, <TokenType.INT4RANGE: 'INT4RANGE'>, <TokenType.DETACH: 'DETACH'>, <TokenType.POINT: 'POINT'>, <TokenType.SCHEMA: 'SCHEMA'>, <TokenType.TIMESTAMP: 'TIMESTAMP'>, <TokenType.MULTIPOLYGON: 'MULTIPOLYGON'>, <TokenType.TINYINT: 'TINYINT'>, <TokenType.COPY: 'COPY'>, <TokenType.TEMPORARY: 'TEMPORARY'>, <TokenType.TOP: 'TOP'>, <TokenType.UPDATE: 'UPDATE'>, <TokenType.TSMULTIRANGE: 'TSMULTIRANGE'>, <TokenType.FLOAT: 'FLOAT'>, <TokenType.SETTINGS: 'SETTINGS'>, <TokenType.VARCHAR: 'VARCHAR'>, <TokenType.TINYBLOB: 'TINYBLOB'>, <TokenType.NUMRANGE: 'NUMRANGE'>, <TokenType.DEFAULT: 'DEFAULT'>, <TokenType.BIGDECIMAL: 'BIGDECIMAL'>, <TokenType.DATERANGE: 'DATERANGE'>, <TokenType.ATTACH: 'ATTACH'>, <TokenType.AGGREGATEFUNCTION: 'AGGREGATEFUNCTION'>, <TokenType.MEDIUMTEXT: 'MEDIUMTEXT'>, <TokenType.FIXEDSTRING: 'FIXEDSTRING'>, <TokenType.PRAGMA: 'PRAGMA'>, <TokenType.GEOGRAPHY: 'GEOGRAPHY'>, <TokenType.DELETE: 'DELETE'>, <TokenType.INDEX: 'INDEX'>, <TokenType.CASE: 'CASE'>, <TokenType.LOAD: 'LOAD'>, <TokenType.VECTOR: 'VECTOR'>, <TokenType.RANGE: 'RANGE'>, <TokenType.GEOMETRY: 'GEOMETRY'>, <TokenType.BIGSERIAL: 'BIGSERIAL'>, <TokenType.RENAME: 'RENAME'>, <TokenType.CURRENT_USER: 'CURRENT_USER'>, <TokenType.LIMIT: 'LIMIT'>, <TokenType.ALL: 'ALL'>, <TokenType.INT8RANGE: 'INT8RANGE'>, <TokenType.WAREHOUSE: 'WAREHOUSE'>, <TokenType.HSTORE: 'HSTORE'>, <TokenType.DECIMAL64: 'DECIMAL64'>, <TokenType.OBJECT: 'OBJECT'>, <TokenType.OFFSET: 'OFFSET'>, <TokenType.CURRENT_TIMESTAMP: 'CURRENT_TIMESTAMP'>, <TokenType.USMALLINT: 'USMALLINT'>, <TokenType.TIME: 'TIME'>, <TokenType.PSEUDO_TYPE: 'PSEUDO_TYPE'>, <TokenType.SIMPLEAGGREGATEFUNCTION: 'SIMPLEAGGREGATEFUNCTION'>, <TokenType.TIMETZ: 'TIMETZ'>, <TokenType.OVERWRITE: 'OVERWRITE'>, <TokenType.UINT: 'UINT'>, <TokenType.UNKNOWN: 'UNKNOWN'>, <TokenType.MEDIUMBLOB: 'MEDIUMBLOB'>, <TokenType.TEXT: 'TEXT'>, <TokenType.IMAGE: 'IMAGE'>, <TokenType.OVERLAPS: 'OVERLAPS'>, <TokenType.REFERENCES: 'REFERENCES'>, <TokenType.COLUMN: 'COLUMN'>, <TokenType.UTINYINT: 'UTINYINT'>, <TokenType.MEDIUMINT: 'MEDIUMINT'>, <TokenType.LINESTRING: 'LINESTRING'>, <TokenType.INT4MULTIRANGE: 'INT4MULTIRANGE'>, <TokenType.OPERATOR: 'OPERATOR'>, <TokenType.TRUNCATE: 'TRUNCATE'>, <TokenType.RECURSIVE: 'RECURSIVE'>, <TokenType.DATE: 'DATE'>, <TokenType.SUPER: 'SUPER'>, <TokenType.DOUBLE: 'DOUBLE'>, <TokenType.FUNCTION: 'FUNCTION'>, <TokenType.DESC: 'DESC'>, <TokenType.SOME: 'SOME'>, <TokenType.ROWVERSION: 'ROWVERSION'>, <TokenType.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, <TokenType.TDIGEST: 'TDIGEST'>, <TokenType.SERIAL: 'SERIAL'>, <TokenType.OBJECT_IDENTIFIER: 'OBJECT_IDENTIFIER'>, <TokenType.IS: 'IS'>, <TokenType.PERCENT: 'PERCENT'>, <TokenType.CHAR: 'CHAR'>, <TokenType.DATETIME2: 'DATETIME2'>, <TokenType.SMALLINT: 'SMALLINT'>, <TokenType.CURRENT_TIME: 'CURRENT_TIME'>, <TokenType.IDENTIFIER: 'IDENTIFIER'>, <TokenType.EXISTS: 'EXISTS'>, <TokenType.CURRENT_DATE: 'CURRENT_DATE'>, <TokenType.JSONB: 'JSONB'>, <TokenType.UMEDIUMINT: 'UMEDIUMINT'>, <TokenType.TSTZRANGE: 'TSTZRANGE'>, <TokenType.ENUM16: 'ENUM16'>, <TokenType.COMMIT: 'COMMIT'>, <TokenType.STREAMLIT: 'STREAMLIT'>, <TokenType.TSRANGE: 'TSRANGE'>, <TokenType.KILL: 'KILL'>, <TokenType.UBIGINT: 'UBIGINT'>, <TokenType.FOREIGN_KEY: 'FOREIGN_KEY'>, <TokenType.HLLSKETCH: 'HLLSKETCH'>, <TokenType.LOWCARDINALITY: 'LOWCARDINALITY'>, <TokenType.CURRENT_DATETIME: 'CURRENT_DATETIME'>, <TokenType.DATETIME64: 'DATETIME64'>, <TokenType.DESCRIBE: 'DESCRIBE'>, <TokenType.NCHAR: 'NCHAR'>, <TokenType.EXPORT: 'EXPORT'>, <TokenType.INT: 'INT'>, <TokenType.CUBE: 'CUBE'>, <TokenType.ANTI: 'ANTI'>, <TokenType.UNNEST: 'UNNEST'>, <TokenType.YEAR: 'YEAR'>, <TokenType.PROCEDURE: 'PROCEDURE'>, <TokenType.IPPREFIX: 'IPPREFIX'>, <TokenType.IPADDRESS: 'IPADDRESS'>, <TokenType.UNPIVOT: 'UNPIVOT'>, <TokenType.TIMESTAMPNTZ: 'TIMESTAMPNTZ'>, <TokenType.DATETIME: 'DATETIME'>, <TokenType.FALSE: 'FALSE'>, <TokenType.VARBINARY: 'VARBINARY'>, <TokenType.REFRESH: 'REFRESH'>, <TokenType.COLLATE: 'COLLATE'>, <TokenType.BPCHAR: 'BPCHAR'>, <TokenType.NVARCHAR: 'NVARCHAR'>, <TokenType.SMALLSERIAL: 'SMALLSERIAL'>, <TokenType.INET: 'INET'>, <TokenType.DIV: 'DIV'>, <TokenType.PUT: 'PUT'>, <TokenType.UDECIMAL: 'UDECIMAL'>, <TokenType.SEMI: 'SEMI'>, <TokenType.UNIQUE: 'UNIQUE'>, <TokenType.DECIMAL32: 'DECIMAL32'>, <TokenType.TAG: 'TAG'>, <TokenType.TSTZMULTIRANGE: 'TSTZMULTIRANGE'>, <TokenType.DECIMAL128: 'DECIMAL128'>, <TokenType.XML: 'XML'>, <TokenType.NAMESPACE: 'NAMESPACE'>, <TokenType.COMMAND: 'COMMAND'>, <TokenType.DYNAMIC: 'DYNAMIC'>, <TokenType.UUID: 'UUID'>, <TokenType.KEEP: 'KEEP'>, <TokenType.PARTITION: 'PARTITION'>, <TokenType.NUMMULTIRANGE: 'NUMMULTIRANGE'>, <TokenType.BEGIN: 'BEGIN'>, <TokenType.BIGINT: 'BIGINT'>, <TokenType.VIEW: 'VIEW'>, <TokenType.SHOW: 'SHOW'>, <TokenType.REPLACE: 'REPLACE'>, <TokenType.SOURCE: 'SOURCE'>, <TokenType.TIMESTAMP_NS: 'TIMESTAMP_NS'>, <TokenType.LONGTEXT: 'LONGTEXT'>, <TokenType.TABLE: 'TABLE'>, <TokenType.DATE32: 'DATE32'>, <TokenType.ORDINALITY: 'ORDINALITY'>, <TokenType.DATEMULTIRANGE: 'DATEMULTIRANGE'>, <TokenType.INTERVAL: 'INTERVAL'>, <TokenType.USERDEFINED: 'USERDEFINED'>, <TokenType.EXECUTE: 'EXECUTE'>, <TokenType.LIST: 'LIST'>, <TokenType.FIRST: 'FIRST'>, <TokenType.INT256: 'INT256'>, <TokenType.TIMESTAMPTZ: 'TIMESTAMPTZ'>, <TokenType.TRUE: 'TRUE'>, <TokenType.CONSTRAINT: 'CONSTRAINT'>, <TokenType.ARRAY: 'ARRAY'>, <TokenType.UINT128: 'UINT128'>, <TokenType.VARIANT: 'VARIANT'>, <TokenType.MERGE: 'MERGE'>, <TokenType.SEQUENCE: 'SEQUENCE'>, <TokenType.DICTIONARY: 'DICTIONARY'>, <TokenType.LONGBLOB: 'LONGBLOB'>, <TokenType.NULL: 'NULL'>, <TokenType.BIT: 'BIT'>, <TokenType.INT8MULTIRANGE: 'INT8MULTIRANGE'>, <TokenType.ISNULL: 'ISNULL'>, <TokenType.TINYTEXT: 'TINYTEXT'>, <TokenType.FORMAT: 'FORMAT'>}
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'>>, 'AND': <bound method Func.from_arg_list of <class 'sqlglot.expressions.And'>>, '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_SCHEMA': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CurrentSchema'>>, '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>, 'DATE_BIN': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DateBin'>>, '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_B_OBJECT_AGG': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONBObjectAgg'>>, 'J_S_O_N_CAST': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONCast'>>, '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'>>, 'OR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Or'>>, 'OVERLAY': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Overlay'>>, 'PAD': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Pad'>>, 'PARAMETERIZED_AGG': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ParameterizedAgg'>>, 'PARSE_JSON': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ParseJSON'>>, 'JSON_PARSE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ParseJSON'>>, 'PERCENTILE_CONT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.PercentileCont'>>, 'PERCENTILE_DISC': <bound method Func.from_arg_list of <class 'sqlglot.expressions.PercentileDisc'>>, 'POSEXPLODE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Posexplode'>>, 'POSEXPLODE_OUTER': <bound method Func.from_arg_list of <class 'sqlglot.expressions.PosexplodeOuter'>>, 'POWER': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Pow'>>, 'POW': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Pow'>>, 'PREDICT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Predict'>>, 'QUANTILE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Quantile'>>, 'QUARTER': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Quarter'>>, 'RAND': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Rand'>>, 'RANDOM': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Rand'>>, 'RANDN': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Randn'>>, 'RANGE_N': <bound method Func.from_arg_list of <class 'sqlglot.expressions.RangeN'>>, 'READ_CSV': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ReadCSV'>>, 'REDUCE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Reduce'>>, 'REGEXP_EXTRACT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.RegexpExtract'>>, 'REGEXP_EXTRACT_ALL': <bound method Func.from_arg_list of <class 'sqlglot.expressions.RegexpExtractAll'>>, 'REGEXP_I_LIKE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.RegexpILike'>>, 'REGEXP_LIKE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.RegexpLike'>>, 'REGEXP_REPLACE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.RegexpReplace'>>, 'REGEXP_SPLIT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.RegexpSplit'>>, 'REPEAT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Repeat'>>, 'RIGHT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Right'>>, 'ROUND': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Round'>>, 'ROW_NUMBER': <bound method Func.from_arg_list of <class 'sqlglot.expressions.RowNumber'>>, 'SHA': <bound method Func.from_arg_list of <class 'sqlglot.expressions.SHA'>>, 'SHA1': <bound method Func.from_arg_list of <class 'sqlglot.expressions.SHA'>>, 'SHA2': <bound method Func.from_arg_list of <class 'sqlglot.expressions.SHA2'>>, 'SAFE_DIVIDE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.SafeDivide'>>, 'SIGN': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Sign'>>, 'SIGNUM': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Sign'>>, 'SORT_ARRAY': <bound method Func.from_arg_list of <class 'sqlglot.expressions.SortArray'>>, 'SPLIT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Split'>>, 'SPLIT_PART': <bound method Func.from_arg_list of <class 'sqlglot.expressions.SplitPart'>>, 'SQRT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Sqrt'>>, 'STANDARD_HASH': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StandardHash'>>, 'STAR_MAP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StarMap'>>, 'STARTS_WITH': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StartsWith'>>, 'STARTSWITH': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StartsWith'>>, 'STDDEV': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Stddev'>>, 'STDEV': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Stddev'>>, 'STDDEV_POP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StddevPop'>>, 'STDDEV_SAMP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StddevSamp'>>, 'STR_POSITION': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StrPosition'>>, 'STR_TO_DATE': <function _str_to_date>, 'STR_TO_MAP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StrToMap'>>, 'STR_TO_TIME': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StrToTime'>>, 'STR_TO_UNIX': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StrToUnix'>>, 'STRING': <bound method Func.from_arg_list of <class 'sqlglot.expressions.String'>>, 'STRING_TO_ARRAY': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StringToArray'>>, 'SPLIT_BY_STRING': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StringToArray'>>, 'STRUCT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Struct'>>, 'STRUCT_EXTRACT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StructExtract'>>, 'STUFF': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Stuff'>>, 'INSERT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Stuff'>>, 'SUBSTRING': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Substring'>>, 'SUBSTR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Substring'>>, 'SUM': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Sum'>>, 'TIME': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Time'>>, 'TIME_ADD': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimeAdd'>>, 'TIME_DIFF': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimeDiff'>>, 'TIME_FROM_PARTS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimeFromParts'>>, 'TIMEFROMPARTS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimeFromParts'>>, 'TIME_STR_TO_DATE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimeStrToDate'>>, 'TIME_STR_TO_TIME': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimeStrToTime'>>, 'TIME_STR_TO_UNIX': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimeStrToUnix'>>, 'TIME_SUB': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimeSub'>>, 'TIME_TO_STR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimeToStr'>>, 'TIME_TO_TIME_STR': <function Parser.<lambda>>, 'TIME_TO_UNIX': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimeToUnix'>>, 'TIME_TRUNC': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimeTrunc'>>, 'TIMESTAMP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Timestamp'>>, 'TIMESTAMP_ADD': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimestampAdd'>>, 'TIMESTAMPDIFF': <function build_date_delta.<locals>._builder>, 'TIMESTAMP_DIFF': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimestampDiff'>>, 'TIMESTAMP_FROM_PARTS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimestampFromParts'>>, 'TIMESTAMPFROMPARTS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimestampFromParts'>>, 'TIMESTAMP_SUB': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimestampSub'>>, 'TIMESTAMP_TRUNC': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimestampTrunc'>>, 'TO_ARRAY': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ToArray'>>, 'TO_BASE64': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ToBase64'>>, 'TO_CHAR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ToChar'>>, 'TO_DAYS': <function MySQL.Parser.<lambda>>, 'TO_DOUBLE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ToDouble'>>, 'TO_MAP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ToMap'>>, 'TO_NUMBER': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ToNumber'>>, 'TRANSFORM': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Transform'>>, 'TRIM': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Trim'>>, 'TRY': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Try'>>, 'TRY_CAST': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TryCast'>>, 'TS_OR_DI_TO_DI': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TsOrDiToDi'>>, 'TS_OR_DS_ADD': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TsOrDsAdd'>>, 'TS_OR_DS_DIFF': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TsOrDsDiff'>>, 'TS_OR_DS_TO_DATE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TsOrDsToDate'>>, 'TS_OR_DS_TO_DATE_STR': <function Parser.<lambda>>, 'TS_OR_DS_TO_DATETIME': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TsOrDsToDatetime'>>, 'TS_OR_DS_TO_TIME': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TsOrDsToTime'>>, 'TS_OR_DS_TO_TIMESTAMP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TsOrDsToTimestamp'>>, 'UNHEX': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Unhex'>>, 'UNICODE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Unicode'>>, 'UNIX_DATE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.UnixDate'>>, 'UNIX_SECONDS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.UnixSeconds'>>, 'UNIX_TO_STR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.UnixToStr'>>, 'UNIX_TO_TIME': <bound method Func.from_arg_list of <class 'sqlglot.expressions.UnixToTime'>>, 'UNIX_TO_TIME_STR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.UnixToTimeStr'>>, 'UNNEST': <function Parser.<lambda>>, 'UPPER': <function build_upper>, 'UCASE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Upper'>>, 'UUID': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Uuid'>>, 'GEN_RANDOM_UUID': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Uuid'>>, 'GENERATE_UUID': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Uuid'>>, 'UUID_STRING': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Uuid'>>, 'VAR_MAP': <function build_var_map>, 'VARIANCE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Variance'>>, 'VARIANCE_SAMP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Variance'>>, 'VAR_SAMP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Variance'>>, 'VARIANCE_POP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.VariancePop'>>, 'VAR_POP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.VariancePop'>>, 'WEEK': <function MySQL.Parser.<lambda>>, 'WEEK_OF_YEAR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.WeekOfYear'>>, 'WEEKOFYEAR': <function MySQL.Parser.<lambda>>, 'XMLELEMENT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.XMLElement'>>, 'X_M_L_TABLE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.XMLTable'>>, 'XOR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Xor'>>, 'YEAR': <function MySQL.Parser.<lambda>>, 'ARRAYAGG': <function Parser.<lambda>>, 'GLOB': <function Parser.<lambda>>, 'JSON_EXTRACT_PATH_TEXT': <function build_extract_json_with_path.<locals>._builder>, 'LIKE': <function build_like>, 'LOG2': <function Parser.<lambda>>, 'LOG10': <function Parser.<lambda>>, 'LPAD': <function Parser.<lambda>>, 'LEFTPAD': <function Parser.<lambda>>, 'LTRIM': <function Parser.<lambda>>, 'MOD': <function build_mod>, 'RIGHTPAD': <function Parser.<lambda>>, 'RPAD': <function Parser.<lambda>>, 'RTRIM': <function Parser.<lambda>>, 'SCOPE_RESOLUTION': <function Parser.<lambda>>, 'STRPOS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StrPosition'>>, 'CHARINDEX': <function Parser.<lambda>>, 'INSTR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StrPosition'>>, 'LOCATE': <function Parser.<lambda>>, 'TO_HEX': <function build_hex>, 'CONVERT_TZ': <function MySQL.Parser.<lambda>>, 'CURDATE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CurrentDate'>>, 'DATE_FORMAT': <function build_formatted_time.<locals>._builder>, 'FORMAT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.NumberToStr'>>, 'FROM_UNIXTIME': <function build_formatted_time.<locals>._builder>, 'ISNULL': <function isnull_to_is_null>, 'MAKETIME': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimeFromParts'>>, 'MONTHNAME': <function MySQL.Parser.<lambda>>, 'SCHEMA': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CurrentSchema'>>, 'DATABASE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CurrentSchema'>>}
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>>}
ALTER_ALTER_PARSERS =
{'DISTKEY': <function Parser.<lambda>>, 'DISTSTYLE': <function Parser.<lambda>>, 'SORTKEY': <function Parser.<lambda>>, 'COMPOUND': <function Parser.<lambda>>, 'INDEX': <function MySQL.Parser.<lambda>>}
SCHEMA_UNNAMED_CONSTRAINTS =
{'CHECK', 'WATERMARK', 'LIKE', 'SPATIAL', 'FOREIGN KEY', 'FULLTEXT', 'PRIMARY KEY', 'PERIOD', 'EXCLUDE', 'KEY', 'INDEX', 'UNIQUE'}
PROFILE_TYPES: Dict[str, Sequence[Union[Sequence[str], str]]] =
{'ALL': (), 'CPU': (), 'IPC': (), 'MEMORY': (), 'SOURCE': (), 'SWAPS': (), 'BLOCK': ('IO',), 'CONTEXT': ('SWITCHES',), 'PAGE': ('FAULTS',)}
TYPE_TOKENS =
{<TokenType.MEDIUMINT: 'MEDIUMINT'>, <TokenType.LINESTRING: 'LINESTRING'>, <TokenType.INT4MULTIRANGE: 'INT4MULTIRANGE'>, <TokenType.BOOLEAN: 'BOOLEAN'>, <TokenType.RING: 'RING'>, <TokenType.DATE: 'DATE'>, <TokenType.SUPER: 'SUPER'>, <TokenType.DOUBLE: 'DOUBLE'>, <TokenType.DECIMAL256: 'DECIMAL256'>, <TokenType.POLYGON: 'POLYGON'>, <TokenType.ROWVERSION: 'ROWVERSION'>, <TokenType.SMALLDATETIME: 'SMALLDATETIME'>, <TokenType.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, <TokenType.TDIGEST: 'TDIGEST'>, <TokenType.SERIAL: 'SERIAL'>, <TokenType.MULTILINESTRING: 'MULTILINESTRING'>, <TokenType.NAME: 'NAME'>, <TokenType.OBJECT_IDENTIFIER: 'OBJECT_IDENTIFIER'>, <TokenType.CHAR: 'CHAR'>, <TokenType.DATETIME2: 'DATETIME2'>, <TokenType.SMALLINT: 'SMALLINT'>, <TokenType.MONEY: 'MONEY'>, <TokenType.JSONB: 'JSONB'>, <TokenType.IPV4: 'IPV4'>, <TokenType.UMEDIUMINT: 'UMEDIUMINT'>, <TokenType.TSTZRANGE: 'TSTZRANGE'>, <TokenType.ENUM16: 'ENUM16'>, <TokenType.MAP: 'MAP'>, <TokenType.SET: 'SET'>, <TokenType.TSRANGE: 'TSRANGE'>, <TokenType.BLOB: 'BLOB'>, <TokenType.INT128: 'INT128'>, <TokenType.JSON: 'JSON'>, <TokenType.UDOUBLE: 'UDOUBLE'>, <TokenType.SMALLMONEY: 'SMALLMONEY'>, <TokenType.UBIGINT: 'UBIGINT'>, <TokenType.NULLABLE: 'NULLABLE'>, <TokenType.HLLSKETCH: 'HLLSKETCH'>, <TokenType.LOWCARDINALITY: 'LOWCARDINALITY'>, <TokenType.TIMESTAMP_MS: 'TIMESTAMP_MS'>, <TokenType.DATETIME64: 'DATETIME64'>, <TokenType.INT8MULTIRANGE: 'INT8MULTIRANGE'>, <TokenType.NCHAR: 'NCHAR'>, <TokenType.INT: 'INT'>, <TokenType.STRUCT: 'STRUCT'>, <TokenType.ENUM8: 'ENUM8'>, <TokenType.YEAR: 'YEAR'>, <TokenType.TIMESTAMP_S: 'TIMESTAMP_S'>, <TokenType.NESTED: 'NESTED'>, <TokenType.BINARY: 'BINARY'>, <TokenType.IPPREFIX: 'IPPREFIX'>, <TokenType.IPADDRESS: 'IPADDRESS'>, <TokenType.TIMESTAMPNTZ: 'TIMESTAMPNTZ'>, <TokenType.DATETIME: 'DATETIME'>, <TokenType.IPV6: 'IPV6'>, <TokenType.UNION: 'UNION'>, <TokenType.DECIMAL: 'DECIMAL'>, <TokenType.UINT256: 'UINT256'>, <TokenType.ENUM: 'ENUM'>, <TokenType.INT4RANGE: 'INT4RANGE'>, <TokenType.POINT: 'POINT'>, <TokenType.TIMESTAMP: 'TIMESTAMP'>, <TokenType.VARBINARY: 'VARBINARY'>, <TokenType.BPCHAR: 'BPCHAR'>, <TokenType.MULTIPOLYGON: 'MULTIPOLYGON'>, <TokenType.NVARCHAR: 'NVARCHAR'>, <TokenType.SMALLSERIAL: 'SMALLSERIAL'>, <TokenType.TINYINT: 'TINYINT'>, <TokenType.INET: 'INET'>, <TokenType.UDECIMAL: 'UDECIMAL'>, <TokenType.TSMULTIRANGE: 'TSMULTIRANGE'>, <TokenType.FLOAT: 'FLOAT'>, <TokenType.VARCHAR: 'VARCHAR'>, <TokenType.TINYBLOB: 'TINYBLOB'>, <TokenType.NUMRANGE: 'NUMRANGE'>, <TokenType.BIGDECIMAL: 'BIGDECIMAL'>, <TokenType.DATERANGE: 'DATERANGE'>, <TokenType.AGGREGATEFUNCTION: 'AGGREGATEFUNCTION'>, <TokenType.MEDIUMTEXT: 'MEDIUMTEXT'>, <TokenType.DECIMAL32: 'DECIMAL32'>, <TokenType.TSTZMULTIRANGE: 'TSTZMULTIRANGE'>, <TokenType.FIXEDSTRING: 'FIXEDSTRING'>, <TokenType.DECIMAL128: 'DECIMAL128'>, <TokenType.XML: 'XML'>, <TokenType.DYNAMIC: 'DYNAMIC'>, <TokenType.UUID: 'UUID'>, <TokenType.NUMMULTIRANGE: 'NUMMULTIRANGE'>, <TokenType.BIGINT: 'BIGINT'>, <TokenType.GEOGRAPHY: 'GEOGRAPHY'>, <TokenType.TIMESTAMP_NS: 'TIMESTAMP_NS'>, <TokenType.VECTOR: 'VECTOR'>, <TokenType.GEOMETRY: 'GEOMETRY'>, <TokenType.LONGTEXT: 'LONGTEXT'>, <TokenType.DATE32: 'DATE32'>, <TokenType.RANGE: 'RANGE'>, <TokenType.BIGSERIAL: 'BIGSERIAL'>, <TokenType.DATEMULTIRANGE: 'DATEMULTIRANGE'>, <TokenType.USERDEFINED: 'USERDEFINED'>, <TokenType.INTERVAL: 'INTERVAL'>, <TokenType.TINYTEXT: 'TINYTEXT'>, <TokenType.INT8RANGE: 'INT8RANGE'>, <TokenType.HSTORE: 'HSTORE'>, <TokenType.LIST: 'LIST'>, <TokenType.INT256: 'INT256'>, <TokenType.DECIMAL64: 'DECIMAL64'>, <TokenType.TIMESTAMPTZ: 'TIMESTAMPTZ'>, <TokenType.OBJECT: 'OBJECT'>, <TokenType.USMALLINT: 'USMALLINT'>, <TokenType.TIME: 'TIME'>, <TokenType.PSEUDO_TYPE: 'PSEUDO_TYPE'>, <TokenType.SIMPLEAGGREGATEFUNCTION: 'SIMPLEAGGREGATEFUNCTION'>, <TokenType.TIMETZ: 'TIMETZ'>, <TokenType.UINT128: 'UINT128'>, <TokenType.VARIANT: 'VARIANT'>, <TokenType.UINT: 'UINT'>, <TokenType.UNKNOWN: 'UNKNOWN'>, <TokenType.MEDIUMBLOB: 'MEDIUMBLOB'>, <TokenType.TEXT: 'TEXT'>, <TokenType.IMAGE: 'IMAGE'>, <TokenType.LONGBLOB: 'LONGBLOB'>, <TokenType.NULL: 'NULL'>, <TokenType.BIT: 'BIT'>, <TokenType.ARRAY: 'ARRAY'>, <TokenType.UTINYINT: 'UTINYINT'>}
ENUM_TYPE_TOKENS =
{<TokenType.DYNAMIC: 'DYNAMIC'>, <TokenType.SET: 'SET'>, <TokenType.ENUM: 'ENUM'>, <TokenType.ENUM16: 'ENUM16'>, <TokenType.ENUM8: 'ENUM8'>}
OPERATION_MODIFIERS =
{'SQL_SMALL_RESULT', 'SQL_CALC_FOUND_ROWS', 'SQL_NO_CACHE', 'STRAIGHT_JOIN', 'HIGH_PRIORITY', 'SQL_BIG_RESULT', 'SQL_BUFFER_RESULT'}
SHOW_TRIE: Dict =
{'BINARY': {'LOGS': {0: True}}, 'MASTER': {'LOGS': {0: True}, 'STATUS': {0: True}}, 'BINLOG': {'EVENTS': {0: True}}, 'CHARACTER': {'SET': {0: True}}, 'CHARSET': {0: True}, 'COLLATION': {0: True}, 'FULL': {'COLUMNS': {0: True}, 'PROCESSLIST': {0: True}, 'TABLES': {0: True}}, 'COLUMNS': {0: True}, 'CREATE': {'DATABASE': {0: True}, 'EVENT': {0: True}, 'FUNCTION': {0: True}, 'PROCEDURE': {0: True}, 'TABLE': {0: True}, 'TRIGGER': {0: True}, 'VIEW': {0: True}}, 'DATABASES': {0: True}, 'SCHEMAS': {0: True}, 'ENGINE': {0: True}, 'STORAGE': {'ENGINES': {0: True}}, 'ENGINES': {0: True}, 'ERRORS': {0: True}, 'EVENTS': {0: True}, 'FUNCTION': {'CODE': {0: True}, 'STATUS': {0: True}}, 'GRANTS': {0: True}, 'INDEX': {0: True}, 'OPEN': {'TABLES': {0: True}}, 'PLUGINS': {0: True}, 'PROCEDURE': {'CODE': {0: True}, 'STATUS': {0: True}}, 'PRIVILEGES': {0: True}, 'PROCESSLIST': {0: True}, 'PROFILE': {0: True}, 'PROFILES': {0: True}, 'RELAYLOG': {'EVENTS': {0: True}}, 'REPLICAS': {0: True}, 'SLAVE': {'HOSTS': {0: True}, 'STATUS': {0: True}}, 'REPLICA': {'STATUS': {0: True}}, 'GLOBAL': {'STATUS': {0: True}, 'VARIABLES': {0: True}}, 'SESSION': {'STATUS': {0: True}, 'VARIABLES': {0: True}}, 'STATUS': {0: True}, 'TABLE': {'STATUS': {0: True}}, 'TABLES': {0: True}, 'TRIGGERS': {0: True}, 'VARIABLES': {0: True}, 'WARNINGS': {0: True}}
SET_TRIE: Dict =
{'GLOBAL': {0: True}, 'LOCAL': {0: True}, 'SESSION': {0: True}, 'TRANSACTION': {0: True}, 'PERSIST': {0: True}, 'PERSIST_ONLY': {0: True}, 'CHARACTER': {'SET': {0: True}}, 'CHARSET': {0: True}, 'NAMES': {0: True}}
Inherited Members
- sqlglot.parser.Parser
- Parser
- NO_PAREN_FUNCTIONS
- STRUCT_TYPE_TOKENS
- NESTED_TYPE_TOKENS
- AGGREGATE_TYPE_TOKENS
- SIGNED_TO_UNSIGNED_TYPE_TOKEN
- SUBQUERY_PREDICATES
- RESERVED_TOKENS
- DB_CREATABLES
- CREATABLES
- ALTERABLES
- ID_VAR_TOKENS
- 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
- 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
- RECURSIVE_CTE_SEARCH_KIND
- MODIFIABLES
- 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
715 class Generator(generator.Generator): 716 INTERVAL_ALLOWS_PLURAL_FORM = False 717 LOCKING_READS_SUPPORTED = True 718 NULL_ORDERING_SUPPORTED = None 719 JOIN_HINTS = False 720 TABLE_HINTS = True 721 DUPLICATE_KEY_UPDATE_WITH_SET = False 722 QUERY_HINT_SEP = " " 723 VALUES_AS_TABLE = False 724 NVL2_SUPPORTED = False 725 LAST_DAY_SUPPORTS_DATE_PART = False 726 JSON_TYPE_REQUIRED_FOR_EXTRACTION = True 727 JSON_PATH_BRACKETED_KEY_SUPPORTED = False 728 JSON_KEY_VALUE_PAIR_SEP = "," 729 SUPPORTS_TO_NUMBER = False 730 PARSE_JSON_NAME: t.Optional[str] = None 731 PAD_FILL_PATTERN_IS_REQUIRED = True 732 WRAP_DERIVED_VALUES = False 733 VARCHAR_REQUIRES_SIZE = True 734 SUPPORTS_MEDIAN = False 735 736 TRANSFORMS = { 737 **generator.Generator.TRANSFORMS, 738 exp.ArrayAgg: rename_func("GROUP_CONCAT"), 739 exp.CurrentDate: no_paren_current_date_sql, 740 exp.DateDiff: _remove_ts_or_ds_to_date( 741 lambda self, e: self.func("DATEDIFF", e.this, e.expression), ("this", "expression") 742 ), 743 exp.DateAdd: _remove_ts_or_ds_to_date(date_add_sql("ADD")), 744 exp.DateStrToDate: datestrtodate_sql, 745 exp.DateSub: _remove_ts_or_ds_to_date(date_add_sql("SUB")), 746 exp.DateTrunc: _date_trunc_sql, 747 exp.Day: _remove_ts_or_ds_to_date(), 748 exp.DayOfMonth: _remove_ts_or_ds_to_date(rename_func("DAYOFMONTH")), 749 exp.DayOfWeek: _remove_ts_or_ds_to_date(rename_func("DAYOFWEEK")), 750 exp.DayOfYear: _remove_ts_or_ds_to_date(rename_func("DAYOFYEAR")), 751 exp.GroupConcat: lambda self, 752 e: f"""GROUP_CONCAT({self.sql(e, "this")} SEPARATOR {self.sql(e, "separator") or "','"})""", 753 exp.ILike: no_ilike_sql, 754 exp.JSONExtractScalar: arrow_json_extract_sql, 755 exp.Length: length_or_char_length_sql, 756 exp.LogicalOr: rename_func("MAX"), 757 exp.LogicalAnd: rename_func("MIN"), 758 exp.Max: max_or_greatest, 759 exp.Min: min_or_least, 760 exp.Month: _remove_ts_or_ds_to_date(), 761 exp.NullSafeEQ: lambda self, e: self.binary(e, "<=>"), 762 exp.NullSafeNEQ: lambda self, e: f"NOT {self.binary(e, '<=>')}", 763 exp.NumberToStr: rename_func("FORMAT"), 764 exp.Pivot: no_pivot_sql, 765 exp.Select: transforms.preprocess( 766 [ 767 transforms.eliminate_distinct_on, 768 transforms.eliminate_semi_and_anti_joins, 769 transforms.eliminate_qualify, 770 transforms.eliminate_full_outer_join, 771 transforms.unnest_generate_date_array_using_recursive_cte, 772 ] 773 ), 774 exp.StrPosition: lambda self, e: strposition_sql( 775 self, e, func_name="LOCATE", supports_position=True 776 ), 777 exp.StrToDate: _str_to_date_sql, 778 exp.StrToTime: _str_to_date_sql, 779 exp.Stuff: rename_func("INSERT"), 780 exp.TableSample: no_tablesample_sql, 781 exp.TimeFromParts: rename_func("MAKETIME"), 782 exp.TimestampAdd: date_add_interval_sql("DATE", "ADD"), 783 exp.TimestampDiff: lambda self, e: self.func( 784 "TIMESTAMPDIFF", unit_to_var(e), e.expression, e.this 785 ), 786 exp.TimestampSub: date_add_interval_sql("DATE", "SUB"), 787 exp.TimeStrToUnix: rename_func("UNIX_TIMESTAMP"), 788 exp.TimeStrToTime: lambda self, e: timestrtotime_sql( 789 self, 790 e, 791 include_precision=not e.args.get("zone"), 792 ), 793 exp.TimeToStr: _remove_ts_or_ds_to_date( 794 lambda self, e: self.func("DATE_FORMAT", e.this, self.format_time(e)) 795 ), 796 exp.Trim: trim_sql, 797 exp.TryCast: no_trycast_sql, 798 exp.TsOrDsAdd: date_add_sql("ADD"), 799 exp.TsOrDsDiff: lambda self, e: self.func("DATEDIFF", e.this, e.expression), 800 exp.TsOrDsToDate: _ts_or_ds_to_date_sql, 801 exp.Unicode: lambda self, e: f"ORD(CONVERT({self.sql(e.this)} USING utf32))", 802 exp.UnixToTime: _unix_to_time_sql, 803 exp.Week: _remove_ts_or_ds_to_date(), 804 exp.WeekOfYear: _remove_ts_or_ds_to_date(rename_func("WEEKOFYEAR")), 805 exp.Year: _remove_ts_or_ds_to_date(), 806 } 807 808 UNSIGNED_TYPE_MAPPING = { 809 exp.DataType.Type.UBIGINT: "BIGINT", 810 exp.DataType.Type.UINT: "INT", 811 exp.DataType.Type.UMEDIUMINT: "MEDIUMINT", 812 exp.DataType.Type.USMALLINT: "SMALLINT", 813 exp.DataType.Type.UTINYINT: "TINYINT", 814 exp.DataType.Type.UDECIMAL: "DECIMAL", 815 exp.DataType.Type.UDOUBLE: "DOUBLE", 816 } 817 818 TIMESTAMP_TYPE_MAPPING = { 819 exp.DataType.Type.DATETIME2: "DATETIME", 820 exp.DataType.Type.SMALLDATETIME: "DATETIME", 821 exp.DataType.Type.TIMESTAMP: "DATETIME", 822 exp.DataType.Type.TIMESTAMPTZ: "TIMESTAMP", 823 exp.DataType.Type.TIMESTAMPLTZ: "TIMESTAMP", 824 } 825 826 TYPE_MAPPING = { 827 **generator.Generator.TYPE_MAPPING, 828 **UNSIGNED_TYPE_MAPPING, 829 **TIMESTAMP_TYPE_MAPPING, 830 } 831 832 TYPE_MAPPING.pop(exp.DataType.Type.MEDIUMTEXT) 833 TYPE_MAPPING.pop(exp.DataType.Type.LONGTEXT) 834 TYPE_MAPPING.pop(exp.DataType.Type.TINYTEXT) 835 TYPE_MAPPING.pop(exp.DataType.Type.BLOB) 836 TYPE_MAPPING.pop(exp.DataType.Type.MEDIUMBLOB) 837 TYPE_MAPPING.pop(exp.DataType.Type.LONGBLOB) 838 TYPE_MAPPING.pop(exp.DataType.Type.TINYBLOB) 839 840 PROPERTIES_LOCATION = { 841 **generator.Generator.PROPERTIES_LOCATION, 842 exp.TransientProperty: exp.Properties.Location.UNSUPPORTED, 843 exp.VolatileProperty: exp.Properties.Location.UNSUPPORTED, 844 } 845 846 LIMIT_FETCH = "LIMIT" 847 848 LIMIT_ONLY_LITERALS = True 849 850 CHAR_CAST_MAPPING = dict.fromkeys( 851 ( 852 exp.DataType.Type.LONGTEXT, 853 exp.DataType.Type.LONGBLOB, 854 exp.DataType.Type.MEDIUMBLOB, 855 exp.DataType.Type.MEDIUMTEXT, 856 exp.DataType.Type.TEXT, 857 exp.DataType.Type.TINYBLOB, 858 exp.DataType.Type.TINYTEXT, 859 exp.DataType.Type.VARCHAR, 860 ), 861 "CHAR", 862 ) 863 SIGNED_CAST_MAPPING = dict.fromkeys( 864 ( 865 exp.DataType.Type.BIGINT, 866 exp.DataType.Type.BOOLEAN, 867 exp.DataType.Type.INT, 868 exp.DataType.Type.SMALLINT, 869 exp.DataType.Type.TINYINT, 870 exp.DataType.Type.MEDIUMINT, 871 ), 872 "SIGNED", 873 ) 874 875 # MySQL doesn't support many datatypes in cast. 876 # https://dev.mysql.com/doc/refman/8.0/en/cast-functions.html#function_cast 877 CAST_MAPPING = { 878 **CHAR_CAST_MAPPING, 879 **SIGNED_CAST_MAPPING, 880 exp.DataType.Type.UBIGINT: "UNSIGNED", 881 } 882 883 TIMESTAMP_FUNC_TYPES = { 884 exp.DataType.Type.TIMESTAMPTZ, 885 exp.DataType.Type.TIMESTAMPLTZ, 886 } 887 888 # https://dev.mysql.com/doc/refman/8.0/en/keywords.html 889 RESERVED_KEYWORDS = { 890 "accessible", 891 "add", 892 "all", 893 "alter", 894 "analyze", 895 "and", 896 "as", 897 "asc", 898 "asensitive", 899 "before", 900 "between", 901 "bigint", 902 "binary", 903 "blob", 904 "both", 905 "by", 906 "call", 907 "cascade", 908 "case", 909 "change", 910 "char", 911 "character", 912 "check", 913 "collate", 914 "column", 915 "condition", 916 "constraint", 917 "continue", 918 "convert", 919 "create", 920 "cross", 921 "cube", 922 "cume_dist", 923 "current_date", 924 "current_time", 925 "current_timestamp", 926 "current_user", 927 "cursor", 928 "database", 929 "databases", 930 "day_hour", 931 "day_microsecond", 932 "day_minute", 933 "day_second", 934 "dec", 935 "decimal", 936 "declare", 937 "default", 938 "delayed", 939 "delete", 940 "dense_rank", 941 "desc", 942 "describe", 943 "deterministic", 944 "distinct", 945 "distinctrow", 946 "div", 947 "double", 948 "drop", 949 "dual", 950 "each", 951 "else", 952 "elseif", 953 "empty", 954 "enclosed", 955 "escaped", 956 "except", 957 "exists", 958 "exit", 959 "explain", 960 "false", 961 "fetch", 962 "first_value", 963 "float", 964 "float4", 965 "float8", 966 "for", 967 "force", 968 "foreign", 969 "from", 970 "fulltext", 971 "function", 972 "generated", 973 "get", 974 "grant", 975 "group", 976 "grouping", 977 "groups", 978 "having", 979 "high_priority", 980 "hour_microsecond", 981 "hour_minute", 982 "hour_second", 983 "if", 984 "ignore", 985 "in", 986 "index", 987 "infile", 988 "inner", 989 "inout", 990 "insensitive", 991 "insert", 992 "int", 993 "int1", 994 "int2", 995 "int3", 996 "int4", 997 "int8", 998 "integer", 999 "intersect", 1000 "interval", 1001 "into", 1002 "io_after_gtids", 1003 "io_before_gtids", 1004 "is", 1005 "iterate", 1006 "join", 1007 "json_table", 1008 "key", 1009 "keys", 1010 "kill", 1011 "lag", 1012 "last_value", 1013 "lateral", 1014 "lead", 1015 "leading", 1016 "leave", 1017 "left", 1018 "like", 1019 "limit", 1020 "linear", 1021 "lines", 1022 "load", 1023 "localtime", 1024 "localtimestamp", 1025 "lock", 1026 "long", 1027 "longblob", 1028 "longtext", 1029 "loop", 1030 "low_priority", 1031 "master_bind", 1032 "master_ssl_verify_server_cert", 1033 "match", 1034 "maxvalue", 1035 "mediumblob", 1036 "mediumint", 1037 "mediumtext", 1038 "middleint", 1039 "minute_microsecond", 1040 "minute_second", 1041 "mod", 1042 "modifies", 1043 "natural", 1044 "not", 1045 "no_write_to_binlog", 1046 "nth_value", 1047 "ntile", 1048 "null", 1049 "numeric", 1050 "of", 1051 "on", 1052 "optimize", 1053 "optimizer_costs", 1054 "option", 1055 "optionally", 1056 "or", 1057 "order", 1058 "out", 1059 "outer", 1060 "outfile", 1061 "over", 1062 "partition", 1063 "percent_rank", 1064 "precision", 1065 "primary", 1066 "procedure", 1067 "purge", 1068 "range", 1069 "rank", 1070 "read", 1071 "reads", 1072 "read_write", 1073 "real", 1074 "recursive", 1075 "references", 1076 "regexp", 1077 "release", 1078 "rename", 1079 "repeat", 1080 "replace", 1081 "require", 1082 "resignal", 1083 "restrict", 1084 "return", 1085 "revoke", 1086 "right", 1087 "rlike", 1088 "row", 1089 "rows", 1090 "row_number", 1091 "schema", 1092 "schemas", 1093 "second_microsecond", 1094 "select", 1095 "sensitive", 1096 "separator", 1097 "set", 1098 "show", 1099 "signal", 1100 "smallint", 1101 "spatial", 1102 "specific", 1103 "sql", 1104 "sqlexception", 1105 "sqlstate", 1106 "sqlwarning", 1107 "sql_big_result", 1108 "sql_calc_found_rows", 1109 "sql_small_result", 1110 "ssl", 1111 "starting", 1112 "stored", 1113 "straight_join", 1114 "system", 1115 "table", 1116 "terminated", 1117 "then", 1118 "tinyblob", 1119 "tinyint", 1120 "tinytext", 1121 "to", 1122 "trailing", 1123 "trigger", 1124 "true", 1125 "undo", 1126 "union", 1127 "unique", 1128 "unlock", 1129 "unsigned", 1130 "update", 1131 "usage", 1132 "use", 1133 "using", 1134 "utc_date", 1135 "utc_time", 1136 "utc_timestamp", 1137 "values", 1138 "varbinary", 1139 "varchar", 1140 "varcharacter", 1141 "varying", 1142 "virtual", 1143 "when", 1144 "where", 1145 "while", 1146 "window", 1147 "with", 1148 "write", 1149 "xor", 1150 "year_month", 1151 "zerofill", 1152 } 1153 1154 def array_sql(self, expression: exp.Array) -> str: 1155 self.unsupported("Arrays are not supported by MySQL") 1156 return self.function_fallback_sql(expression) 1157 1158 def arraycontainsall_sql(self, expression: exp.ArrayContainsAll) -> str: 1159 self.unsupported("Array operations are not supported by MySQL") 1160 return self.function_fallback_sql(expression) 1161 1162 def dpipe_sql(self, expression: exp.DPipe) -> str: 1163 return self.func("CONCAT", *expression.flatten()) 1164 1165 def extract_sql(self, expression: exp.Extract) -> str: 1166 unit = expression.name 1167 if unit and unit.lower() == "epoch": 1168 return self.func("UNIX_TIMESTAMP", expression.expression) 1169 1170 return super().extract_sql(expression) 1171 1172 def datatype_sql(self, expression: exp.DataType) -> str: 1173 if ( 1174 self.VARCHAR_REQUIRES_SIZE 1175 and expression.is_type(exp.DataType.Type.VARCHAR) 1176 and not expression.expressions 1177 ): 1178 # `VARCHAR` must always have a size - if it doesn't, we always generate `TEXT` 1179 return "TEXT" 1180 1181 # https://dev.mysql.com/doc/refman/8.0/en/numeric-type-syntax.html 1182 result = super().datatype_sql(expression) 1183 if expression.this in self.UNSIGNED_TYPE_MAPPING: 1184 result = f"{result} UNSIGNED" 1185 1186 return result 1187 1188 def jsonarraycontains_sql(self, expression: exp.JSONArrayContains) -> str: 1189 return f"{self.sql(expression, 'this')} MEMBER OF({self.sql(expression, 'expression')})" 1190 1191 def cast_sql(self, expression: exp.Cast, safe_prefix: t.Optional[str] = None) -> str: 1192 if expression.to.this in self.TIMESTAMP_FUNC_TYPES: 1193 return self.func("TIMESTAMP", expression.this) 1194 1195 to = self.CAST_MAPPING.get(expression.to.this) 1196 1197 if to: 1198 expression.to.set("this", to) 1199 return super().cast_sql(expression) 1200 1201 def show_sql(self, expression: exp.Show) -> str: 1202 this = f" {expression.name}" 1203 full = " FULL" if expression.args.get("full") else "" 1204 global_ = " GLOBAL" if expression.args.get("global") else "" 1205 1206 target = self.sql(expression, "target") 1207 target = f" {target}" if target else "" 1208 if expression.name in ("COLUMNS", "INDEX"): 1209 target = f" FROM{target}" 1210 elif expression.name == "GRANTS": 1211 target = f" FOR{target}" 1212 1213 db = self._prefixed_sql("FROM", expression, "db") 1214 1215 like = self._prefixed_sql("LIKE", expression, "like") 1216 where = self.sql(expression, "where") 1217 1218 types = self.expressions(expression, key="types") 1219 types = f" {types}" if types else types 1220 query = self._prefixed_sql("FOR QUERY", expression, "query") 1221 1222 if expression.name == "PROFILE": 1223 offset = self._prefixed_sql("OFFSET", expression, "offset") 1224 limit = self._prefixed_sql("LIMIT", expression, "limit") 1225 else: 1226 offset = "" 1227 limit = self._oldstyle_limit_sql(expression) 1228 1229 log = self._prefixed_sql("IN", expression, "log") 1230 position = self._prefixed_sql("FROM", expression, "position") 1231 1232 channel = self._prefixed_sql("FOR CHANNEL", expression, "channel") 1233 1234 if expression.name == "ENGINE": 1235 mutex_or_status = " MUTEX" if expression.args.get("mutex") else " STATUS" 1236 else: 1237 mutex_or_status = "" 1238 1239 return f"SHOW{full}{global_}{this}{target}{types}{db}{query}{log}{position}{channel}{mutex_or_status}{like}{where}{offset}{limit}" 1240 1241 def altercolumn_sql(self, expression: exp.AlterColumn) -> str: 1242 dtype = self.sql(expression, "dtype") 1243 if not dtype: 1244 return super().altercolumn_sql(expression) 1245 1246 this = self.sql(expression, "this") 1247 return f"MODIFY COLUMN {this} {dtype}" 1248 1249 def _prefixed_sql(self, prefix: str, expression: exp.Expression, arg: str) -> str: 1250 sql = self.sql(expression, arg) 1251 return f" {prefix} {sql}" if sql else "" 1252 1253 def _oldstyle_limit_sql(self, expression: exp.Show) -> str: 1254 limit = self.sql(expression, "limit") 1255 offset = self.sql(expression, "offset") 1256 if limit: 1257 limit_offset = f"{offset}, {limit}" if offset else limit 1258 return f" LIMIT {limit_offset}" 1259 return "" 1260 1261 def chr_sql(self, expression: exp.Chr) -> str: 1262 this = self.expressions(sqls=[expression.this] + expression.expressions) 1263 charset = expression.args.get("charset") 1264 using = f" USING {self.sql(charset)}" if charset else "" 1265 return f"CHAR({this}{using})" 1266 1267 def timestamptrunc_sql(self, expression: exp.TimestampTrunc) -> str: 1268 unit = expression.args.get("unit") 1269 1270 # Pick an old-enough date to avoid negative timestamp diffs 1271 start_ts = "'0000-01-01 00:00:00'" 1272 1273 # Source: https://stackoverflow.com/a/32955740 1274 timestamp_diff = build_date_delta(exp.TimestampDiff)([unit, start_ts, expression.this]) 1275 interval = exp.Interval(this=timestamp_diff, unit=unit) 1276 dateadd = build_date_delta_with_interval(exp.DateAdd)([start_ts, interval]) 1277 1278 return self.sql(dateadd) 1279 1280 def converttimezone_sql(self, expression: exp.ConvertTimezone) -> str: 1281 from_tz = expression.args.get("source_tz") 1282 to_tz = expression.args.get("target_tz") 1283 dt = expression.args.get("timestamp") 1284 1285 return self.func("CONVERT_TZ", dt, from_tz, to_tz) 1286 1287 def attimezone_sql(self, expression: exp.AtTimeZone) -> str: 1288 self.unsupported("AT TIME ZONE is not supported by MySQL") 1289 return self.sql(expression.this) 1290 1291 def isascii_sql(self, expression: exp.IsAscii) -> str: 1292 return f"REGEXP_LIKE({self.sql(expression.this)}, '^[[:ascii:]]*$')" 1293 1294 @unsupported_args("this") 1295 def currentschema_sql(self, expression: exp.CurrentSchema) -> str: 1296 return self.func("SCHEMA")
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.Tags'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.TemporaryProperty'>: <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.UsingTemplateProperty'>: <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.ForceProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.ArrayAgg'>: <function rename_func.<locals>.<lambda>>, <class 'sqlglot.expressions.CurrentDate'>: <function no_paren_current_date_sql>, <class 'sqlglot.expressions.DateDiff'>: <function _remove_ts_or_ds_to_date.<locals>.func>, <class 'sqlglot.expressions.DateAdd'>: <function _remove_ts_or_ds_to_date.<locals>.func>, <class 'sqlglot.expressions.DateStrToDate'>: <function datestrtodate_sql>, <class 'sqlglot.expressions.DateSub'>: <function _remove_ts_or_ds_to_date.<locals>.func>, <class 'sqlglot.expressions.DateTrunc'>: <function _date_trunc_sql>, <class 'sqlglot.expressions.Day'>: <function _remove_ts_or_ds_to_date.<locals>.func>, <class 'sqlglot.expressions.DayOfMonth'>: <function _remove_ts_or_ds_to_date.<locals>.func>, <class 'sqlglot.expressions.DayOfWeek'>: <function _remove_ts_or_ds_to_date.<locals>.func>, <class 'sqlglot.expressions.DayOfYear'>: <function _remove_ts_or_ds_to_date.<locals>.func>, <class 'sqlglot.expressions.GroupConcat'>: <function MySQL.Generator.<lambda>>, <class 'sqlglot.expressions.ILike'>: <function no_ilike_sql>, <class 'sqlglot.expressions.JSONExtractScalar'>: <function arrow_json_extract_sql>, <class 'sqlglot.expressions.Length'>: <function length_or_char_length_sql>, <class 'sqlglot.expressions.LogicalOr'>: <function rename_func.<locals>.<lambda>>, <class 'sqlglot.expressions.LogicalAnd'>: <function rename_func.<locals>.<lambda>>, <class 'sqlglot.expressions.Max'>: <function max_or_greatest>, <class 'sqlglot.expressions.Min'>: <function min_or_least>, <class 'sqlglot.expressions.Month'>: <function _remove_ts_or_ds_to_date.<locals>.func>, <class 'sqlglot.expressions.NullSafeEQ'>: <function MySQL.Generator.<lambda>>, <class 'sqlglot.expressions.NullSafeNEQ'>: <function MySQL.Generator.<lambda>>, <class 'sqlglot.expressions.NumberToStr'>: <function rename_func.<locals>.<lambda>>, <class 'sqlglot.expressions.Pivot'>: <function no_pivot_sql>, <class 'sqlglot.expressions.Select'>: <function preprocess.<locals>._to_sql>, <class 'sqlglot.expressions.StrPosition'>: <function MySQL.Generator.<lambda>>, <class 'sqlglot.expressions.StrToDate'>: <function _str_to_date_sql>, <class 'sqlglot.expressions.StrToTime'>: <function _str_to_date_sql>, <class 'sqlglot.expressions.Stuff'>: <function rename_func.<locals>.<lambda>>, <class 'sqlglot.expressions.TableSample'>: <function no_tablesample_sql>, <class 'sqlglot.expressions.TimeFromParts'>: <function rename_func.<locals>.<lambda>>, <class 'sqlglot.expressions.TimestampAdd'>: <function date_add_interval_sql.<locals>.func>, <class 'sqlglot.expressions.TimestampDiff'>: <function MySQL.Generator.<lambda>>, <class 'sqlglot.expressions.TimestampSub'>: <function date_add_interval_sql.<locals>.func>, <class 'sqlglot.expressions.TimeStrToUnix'>: <function rename_func.<locals>.<lambda>>, <class 'sqlglot.expressions.TimeStrToTime'>: <function MySQL.Generator.<lambda>>, <class 'sqlglot.expressions.TimeToStr'>: <function _remove_ts_or_ds_to_date.<locals>.func>, <class 'sqlglot.expressions.Trim'>: <function trim_sql>, <class 'sqlglot.expressions.TryCast'>: <function no_trycast_sql>, <class 'sqlglot.expressions.TsOrDsAdd'>: <function date_add_sql.<locals>.func>, <class 'sqlglot.expressions.TsOrDsDiff'>: <function MySQL.Generator.<lambda>>, <class 'sqlglot.expressions.TsOrDsToDate'>: <function _ts_or_ds_to_date_sql>, <class 'sqlglot.expressions.Unicode'>: <function MySQL.Generator.<lambda>>, <class 'sqlglot.expressions.UnixToTime'>: <function _unix_to_time_sql>, <class 'sqlglot.expressions.Week'>: <function _remove_ts_or_ds_to_date.<locals>.func>, <class 'sqlglot.expressions.WeekOfYear'>: <function _remove_ts_or_ds_to_date.<locals>.func>, <class 'sqlglot.expressions.Year'>: <function _remove_ts_or_ds_to_date.<locals>.func>}
UNSIGNED_TYPE_MAPPING =
{<Type.UBIGINT: 'UBIGINT'>: 'BIGINT', <Type.UINT: 'UINT'>: 'INT', <Type.UMEDIUMINT: 'UMEDIUMINT'>: 'MEDIUMINT', <Type.USMALLINT: 'USMALLINT'>: 'SMALLINT', <Type.UTINYINT: 'UTINYINT'>: 'TINYINT', <Type.UDECIMAL: 'UDECIMAL'>: 'DECIMAL', <Type.UDOUBLE: 'UDOUBLE'>: 'DOUBLE'}
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.UDOUBLE: 'UDOUBLE'>: 'DOUBLE', <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.StorageHandlerProperty'>: <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.UsingTemplateProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <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'>, <class 'sqlglot.expressions.ForceProperty'>: <Location.POST_CREATE: 'POST_CREATE'>}
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 =
{'write', 'describe', 'ntile', 'master_bind', 'when', 'hour_minute', 'function', 'long', 'longblob', 'last_value', 'unlock', 'dec', 'resignal', 'percent_rank', 'asc', 'outfile', 'leading', 'dual', 'from', 'lock', 'explain', 'of', 'master_ssl_verify_server_cert', 'partition', 'spatial', 'utc_time', 'reads', 'as', 'hour_second', 'mod', 'int2', 'precision', 'optionally', 'empty', 'high_priority', 'check', 'primary', 'force', 'to', 'enclosed', 'revoke', 'read_write', 'cross', 'trigger', 'maxvalue', 'drop', 'char', 'distinctrow', 'repeat', 'desc', 'optimizer_costs', 'using', 'right', 'infile', 'grant', 'first_value', 'natural', 'asensitive', 'int', 'cursor', 'alter', 'binary', 'schema', 'continue', 'for', 'varcharacter', 'rename', 'call', 'low_priority', 'foreign', 'straight_join', 'all', 'inout', 'false', 'modifies', 'declare', 'float', 'is', 'character', 'lateral', 'before', 'collate', 'tinyint', 'longtext', 'signal', 'groups', 'virtual', 'convert', 'exit', 'mediumint', 'set', 'purge', 'constraint', 'require', 'both', 'double', 'sensitive', 'bigint', 'unsigned', 'utc_timestamp', 'localtime', 'range', 'column', 'delayed', 'row', 'lead', 'update', 'day_minute', 'analyze', 'mediumtext', 'like', 'day_second', 'sqlexception', 'kill', 'while', 'minute_second', 'out', 'int3', 'current_user', 'json_table', 'iterate', 'leave', 'rank', 'over', 'if', 'elseif', 'int1', 'specific', 'no_write_to_binlog', 'loop', 'default', 'case', 'except', 'middleint', 'accessible', 'numeric', 'minute_microsecond', 'inner', 'current_timestamp', 'hour_microsecond', 'current_time', 'between', 'stored', 'then', 'each', 'having', 'lag', 'system', 'separator', 'recursive', 'schemas', 'create', 'fulltext', 'generated', 'rows', 'terminated', 'get', 'values', 'optimize', 'load', 'linear', 'cube', 'into', 'table', 'dense_rank', 'exists', 'undo', 'use', 'sqlwarning', 'tinytext', 'day_microsecond', 'escaped', 'interval', 'index', 'varbinary', 'databases', 'usage', 'utc_date', 'grouping', 'condition', 'decimal', 'not', 'sqlstate', 'else', 'cume_dist', 'delete', 'change', 'return', 'distinct', 'integer', 'left', 'tinyblob', 'fetch', 'ignore', 'varying', 'row_number', 'rlike', 'io_before_gtids', 'lines', 'year_month', 'procedure', 'ssl', 'float4', 'starting', 'outer', 'int8', 'limit', 'real', 'order', 'sql_small_result', 'regexp', 'restrict', 'second_microsecond', 'day_hour', 'select', 'smallint', 'in', 'keys', 'references', 'insert', 'sql_big_result', 'and', 'current_date', 'intersect', 'zerofill', 'on', 'div', 'float8', 'option', 'with', 'database', 'where', 'read', 'int4', 'insensitive', 'nth_value', 'key', 'xor', 'io_after_gtids', 'by', 'localtimestamp', 'varchar', 'group', 'trailing', 'deterministic', 'null', 'join', 'window', 'match', 'union', 'unique', 'show', 'add', 'sql_calc_found_rows', 'true', 'sql', 'replace', 'mediumblob', 'cascade', 'blob', 'or', 'release'}
1172 def datatype_sql(self, expression: exp.DataType) -> str: 1173 if ( 1174 self.VARCHAR_REQUIRES_SIZE 1175 and expression.is_type(exp.DataType.Type.VARCHAR) 1176 and not expression.expressions 1177 ): 1178 # `VARCHAR` must always have a size - if it doesn't, we always generate `TEXT` 1179 return "TEXT" 1180 1181 # https://dev.mysql.com/doc/refman/8.0/en/numeric-type-syntax.html 1182 result = super().datatype_sql(expression) 1183 if expression.this in self.UNSIGNED_TYPE_MAPPING: 1184 result = f"{result} UNSIGNED" 1185 1186 return result
def
cast_sql( self, expression: sqlglot.expressions.Cast, safe_prefix: Optional[str] = None) -> str:
1191 def cast_sql(self, expression: exp.Cast, safe_prefix: t.Optional[str] = None) -> str: 1192 if expression.to.this in self.TIMESTAMP_FUNC_TYPES: 1193 return self.func("TIMESTAMP", expression.this) 1194 1195 to = self.CAST_MAPPING.get(expression.to.this) 1196 1197 if to: 1198 expression.to.set("this", to) 1199 return super().cast_sql(expression)
1201 def show_sql(self, expression: exp.Show) -> str: 1202 this = f" {expression.name}" 1203 full = " FULL" if expression.args.get("full") else "" 1204 global_ = " GLOBAL" if expression.args.get("global") else "" 1205 1206 target = self.sql(expression, "target") 1207 target = f" {target}" if target else "" 1208 if expression.name in ("COLUMNS", "INDEX"): 1209 target = f" FROM{target}" 1210 elif expression.name == "GRANTS": 1211 target = f" FOR{target}" 1212 1213 db = self._prefixed_sql("FROM", expression, "db") 1214 1215 like = self._prefixed_sql("LIKE", expression, "like") 1216 where = self.sql(expression, "where") 1217 1218 types = self.expressions(expression, key="types") 1219 types = f" {types}" if types else types 1220 query = self._prefixed_sql("FOR QUERY", expression, "query") 1221 1222 if expression.name == "PROFILE": 1223 offset = self._prefixed_sql("OFFSET", expression, "offset") 1224 limit = self._prefixed_sql("LIMIT", expression, "limit") 1225 else: 1226 offset = "" 1227 limit = self._oldstyle_limit_sql(expression) 1228 1229 log = self._prefixed_sql("IN", expression, "log") 1230 position = self._prefixed_sql("FROM", expression, "position") 1231 1232 channel = self._prefixed_sql("FOR CHANNEL", expression, "channel") 1233 1234 if expression.name == "ENGINE": 1235 mutex_or_status = " MUTEX" if expression.args.get("mutex") else " STATUS" 1236 else: 1237 mutex_or_status = "" 1238 1239 return f"SHOW{full}{global_}{this}{target}{types}{db}{query}{log}{position}{channel}{mutex_or_status}{like}{where}{offset}{limit}"
1267 def timestamptrunc_sql(self, expression: exp.TimestampTrunc) -> str: 1268 unit = expression.args.get("unit") 1269 1270 # Pick an old-enough date to avoid negative timestamp diffs 1271 start_ts = "'0000-01-01 00:00:00'" 1272 1273 # Source: https://stackoverflow.com/a/32955740 1274 timestamp_diff = build_date_delta(exp.TimestampDiff)([unit, start_ts, expression.this]) 1275 interval = exp.Interval(this=timestamp_diff, unit=unit) 1276 dateadd = build_date_delta_with_interval(exp.DateAdd)([start_ts, interval]) 1277 1278 return self.sql(dateadd)
@unsupported_args('this')
def
currentschema_sql(self, expression: sqlglot.expressions.CurrentSchema) -> str:
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
- ALTER_SET_TYPE
- 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
- limitoptions_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
- tablefromrows_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
- alterindex_sql
- alterdiststyle_sql
- altersortkey_sql
- alterrename_sql
- renamecolumn_sql
- alterset_sql
- alter_sql
- add_column_sql
- droppartition_sql
- addconstraint_sql
- distinct_sql
- ignorenulls_sql
- respectnulls_sql
- havingmax_sql
- intdiv_sql
- div_sql
- safedivide_sql
- overlaps_sql
- distance_sql
- dot_sql
- eq_sql
- propertyeq_sql
- escape_sql
- glob_sql
- gt_sql
- gte_sql
- ilike_sql
- ilikeany_sql
- is_sql
- like_sql
- likeany_sql
- similarto_sql
- lt_sql
- lte_sql
- mod_sql
- mul_sql
- neq_sql
- nullsafeeq_sql
- nullsafeneq_sql
- slice_sql
- sub_sql
- trycast_sql
- jsoncast_sql
- try_sql
- log_sql
- use_sql
- binary
- ceil_floor
- function_fallback_sql
- func
- format_args
- too_wide
- format_time
- expressions
- op_expressions
- naked_property
- tag_sql
- token_sql
- userdefinedfunction_sql
- joinhint_sql
- kwarg_sql
- when_sql
- whens_sql
- merge_sql
- tochar_sql
- tonumber_sql
- dictproperty_sql
- dictrange_sql
- dictsubproperty_sql
- duplicatekeyproperty_sql
- uniquekeyproperty_sql
- distributedbyproperty_sql
- oncluster_sql
- clusteredbyproperty_sql
- anyvalue_sql
- querytransform_sql
- indexconstraintoption_sql
- checkcolumnconstraint_sql
- indexcolumnconstraint_sql
- nvl2_sql
- comprehension_sql
- columnprefix_sql
- opclass_sql
- predict_sql
- forin_sql
- refresh_sql
- toarray_sql
- tsordstotime_sql
- tsordstotimestamp_sql
- tsordstodatetime_sql
- tsordstodate_sql
- unixdate_sql
- lastday_sql
- dateadd_sql
- arrayany_sql
- struct_sql
- partitionrange_sql
- truncatetable_sql
- convert_sql
- copyparameter_sql
- credentials_sql
- copy_sql
- semicolon_sql
- datadeletionproperty_sql
- maskingpolicycolumnconstraint_sql
- gapfill_sql
- scope_resolution
- scoperesolution_sql
- parsejson_sql
- rand_sql
- changes_sql
- pad_sql
- summarize_sql
- explodinggenerateseries_sql
- arrayconcat_sql
- json_sql
- jsonvalue_sql
- conditionalinsert_sql
- multitableinserts_sql
- oncondition_sql
- jsonextractquote_sql
- jsonexists_sql
- arrayagg_sql
- apply_sql
- grant_sql
- grantprivilege_sql
- grantprincipal_sql
- columns_sql
- overlay_sql
- todouble_sql
- string_sql
- median_sql
- overflowtruncatebehavior_sql
- unixseconds_sql
- arraysize_sql
- attach_sql
- detach_sql
- attachoption_sql
- featuresattime_sql
- watermarkcolumnconstraint_sql
- encodeproperty_sql
- includeproperty_sql
- xmlelement_sql
- partitionbyrangeproperty_sql
- partitionbyrangepropertydynamic_sql
- unpivotcolumns_sql
- analyzesample_sql
- analyzestatistics_sql
- analyzehistogram_sql
- analyzedelete_sql
- analyzelistchainedrows_sql
- analyzevalidate_sql
- analyze_sql
- xmltable_sql
- xmlnamespace_sql
- export_sql
- declare_sql
- declareitem_sql
- recursivewithsearch_sql
- parameterizedagg_sql
- anonymousaggfunc_sql
- combinedaggfunc_sql
- combinedparameterizedagg_sql
- put_sql