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