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 # https://dev.mysql.com/doc/refman/8.0/en/identifiers.html 149 IDENTIFIERS_CAN_START_WITH_DIGIT = True 150 151 # We default to treating all identifiers as case-sensitive, since it matches MySQL's 152 # behavior on Linux systems. For MacOS and Windows systems, one can override this 153 # setting by specifying `dialect="mysql, normalization_strategy = lowercase"`. 154 # 155 # See also https://dev.mysql.com/doc/refman/8.2/en/identifier-case-sensitivity.html 156 NORMALIZATION_STRATEGY = NormalizationStrategy.CASE_SENSITIVE 157 158 TIME_FORMAT = "'%Y-%m-%d %T'" 159 DPIPE_IS_STRING_CONCAT = False 160 SUPPORTS_USER_DEFINED_TYPES = False 161 SUPPORTS_SEMI_ANTI_JOIN = False 162 SAFE_DIVISION = True 163 164 # https://prestodb.io/docs/current/functions/datetime.html#mysql-date-functions 165 TIME_MAPPING = { 166 "%M": "%B", 167 "%c": "%-m", 168 "%e": "%-d", 169 "%h": "%I", 170 "%i": "%M", 171 "%s": "%S", 172 "%u": "%W", 173 "%k": "%-H", 174 "%l": "%-I", 175 "%T": "%H:%M:%S", 176 "%W": "%A", 177 } 178 179 class Tokenizer(tokens.Tokenizer): 180 QUOTES = ["'", '"'] 181 COMMENTS = ["--", "#", ("/*", "*/")] 182 IDENTIFIERS = ["`"] 183 STRING_ESCAPES = ["'", '"', "\\"] 184 BIT_STRINGS = [("b'", "'"), ("B'", "'"), ("0b", "")] 185 HEX_STRINGS = [("x'", "'"), ("X'", "'"), ("0x", "")] 186 187 KEYWORDS = { 188 **tokens.Tokenizer.KEYWORDS, 189 "CHARSET": TokenType.CHARACTER_SET, 190 # The DESCRIBE and EXPLAIN statements are synonyms. 191 # https://dev.mysql.com/doc/refman/8.4/en/explain.html 192 "EXPLAIN": TokenType.DESCRIBE, 193 "FORCE": TokenType.FORCE, 194 "IGNORE": TokenType.IGNORE, 195 "KEY": TokenType.KEY, 196 "LOCK TABLES": TokenType.COMMAND, 197 "LONGBLOB": TokenType.LONGBLOB, 198 "LONGTEXT": TokenType.LONGTEXT, 199 "MEDIUMBLOB": TokenType.MEDIUMBLOB, 200 "TINYBLOB": TokenType.TINYBLOB, 201 "TINYTEXT": TokenType.TINYTEXT, 202 "MEDIUMTEXT": TokenType.MEDIUMTEXT, 203 "MEDIUMINT": TokenType.MEDIUMINT, 204 "MEMBER OF": TokenType.MEMBER_OF, 205 "SEPARATOR": TokenType.SEPARATOR, 206 "START": TokenType.BEGIN, 207 "SIGNED": TokenType.BIGINT, 208 "SIGNED INTEGER": TokenType.BIGINT, 209 "UNLOCK TABLES": TokenType.COMMAND, 210 "UNSIGNED": TokenType.UBIGINT, 211 "UNSIGNED INTEGER": TokenType.UBIGINT, 212 "YEAR": TokenType.YEAR, 213 "_ARMSCII8": TokenType.INTRODUCER, 214 "_ASCII": TokenType.INTRODUCER, 215 "_BIG5": TokenType.INTRODUCER, 216 "_BINARY": TokenType.INTRODUCER, 217 "_CP1250": TokenType.INTRODUCER, 218 "_CP1251": TokenType.INTRODUCER, 219 "_CP1256": TokenType.INTRODUCER, 220 "_CP1257": TokenType.INTRODUCER, 221 "_CP850": TokenType.INTRODUCER, 222 "_CP852": TokenType.INTRODUCER, 223 "_CP866": TokenType.INTRODUCER, 224 "_CP932": TokenType.INTRODUCER, 225 "_DEC8": TokenType.INTRODUCER, 226 "_EUCJPMS": TokenType.INTRODUCER, 227 "_EUCKR": TokenType.INTRODUCER, 228 "_GB18030": TokenType.INTRODUCER, 229 "_GB2312": TokenType.INTRODUCER, 230 "_GBK": TokenType.INTRODUCER, 231 "_GEOSTD8": TokenType.INTRODUCER, 232 "_GREEK": TokenType.INTRODUCER, 233 "_HEBREW": TokenType.INTRODUCER, 234 "_HP8": TokenType.INTRODUCER, 235 "_KEYBCS2": TokenType.INTRODUCER, 236 "_KOI8R": TokenType.INTRODUCER, 237 "_KOI8U": TokenType.INTRODUCER, 238 "_LATIN1": TokenType.INTRODUCER, 239 "_LATIN2": TokenType.INTRODUCER, 240 "_LATIN5": TokenType.INTRODUCER, 241 "_LATIN7": TokenType.INTRODUCER, 242 "_MACCE": TokenType.INTRODUCER, 243 "_MACROMAN": TokenType.INTRODUCER, 244 "_SJIS": TokenType.INTRODUCER, 245 "_SWE7": TokenType.INTRODUCER, 246 "_TIS620": TokenType.INTRODUCER, 247 "_UCS2": TokenType.INTRODUCER, 248 "_UJIS": TokenType.INTRODUCER, 249 # https://dev.mysql.com/doc/refman/8.0/en/string-literals.html 250 "_UTF8": TokenType.INTRODUCER, 251 "_UTF16": TokenType.INTRODUCER, 252 "_UTF16LE": TokenType.INTRODUCER, 253 "_UTF32": TokenType.INTRODUCER, 254 "_UTF8MB3": TokenType.INTRODUCER, 255 "_UTF8MB4": TokenType.INTRODUCER, 256 "@@": TokenType.SESSION_PARAMETER, 257 } 258 259 COMMANDS = {*tokens.Tokenizer.COMMANDS, TokenType.REPLACE} - {TokenType.SHOW} 260 261 class Parser(parser.Parser): 262 FUNC_TOKENS = { 263 *parser.Parser.FUNC_TOKENS, 264 TokenType.DATABASE, 265 TokenType.SCHEMA, 266 TokenType.VALUES, 267 } 268 269 CONJUNCTION = { 270 **parser.Parser.CONJUNCTION, 271 TokenType.DAMP: exp.And, 272 TokenType.XOR: exp.Xor, 273 } 274 275 DISJUNCTION = { 276 **parser.Parser.DISJUNCTION, 277 TokenType.DPIPE: exp.Or, 278 } 279 280 TABLE_ALIAS_TOKENS = ( 281 parser.Parser.TABLE_ALIAS_TOKENS - parser.Parser.TABLE_INDEX_HINT_TOKENS 282 ) 283 284 RANGE_PARSERS = { 285 **parser.Parser.RANGE_PARSERS, 286 TokenType.MEMBER_OF: lambda self, this: self.expression( 287 exp.JSONArrayContains, 288 this=this, 289 expression=self._parse_wrapped(self._parse_expression), 290 ), 291 } 292 293 FUNCTIONS = { 294 **parser.Parser.FUNCTIONS, 295 "CONVERT_TZ": lambda args: exp.ConvertTimezone( 296 source_tz=seq_get(args, 1), target_tz=seq_get(args, 2), timestamp=seq_get(args, 0) 297 ), 298 "DATE": lambda args: exp.TsOrDsToDate(this=seq_get(args, 0)), 299 "DATE_ADD": build_date_delta_with_interval(exp.DateAdd), 300 "DATE_FORMAT": build_formatted_time(exp.TimeToStr, "mysql"), 301 "DATE_SUB": build_date_delta_with_interval(exp.DateSub), 302 "DAY": lambda args: exp.Day(this=exp.TsOrDsToDate(this=seq_get(args, 0))), 303 "DAYOFMONTH": lambda args: exp.DayOfMonth(this=exp.TsOrDsToDate(this=seq_get(args, 0))), 304 "DAYOFWEEK": lambda args: exp.DayOfWeek(this=exp.TsOrDsToDate(this=seq_get(args, 0))), 305 "DAYOFYEAR": lambda args: exp.DayOfYear(this=exp.TsOrDsToDate(this=seq_get(args, 0))), 306 "FROM_UNIXTIME": build_formatted_time(exp.UnixToTime, "mysql"), 307 "ISNULL": isnull_to_is_null, 308 "LOCATE": locate_to_strposition, 309 "MAKETIME": exp.TimeFromParts.from_arg_list, 310 "MONTH": lambda args: exp.Month(this=exp.TsOrDsToDate(this=seq_get(args, 0))), 311 "MONTHNAME": lambda args: exp.TimeToStr( 312 this=exp.TsOrDsToDate(this=seq_get(args, 0)), 313 format=exp.Literal.string("%B"), 314 ), 315 "STR_TO_DATE": _str_to_date, 316 "TIMESTAMPDIFF": build_date_delta(exp.TimestampDiff), 317 "TO_DAYS": lambda args: exp.paren( 318 exp.DateDiff( 319 this=exp.TsOrDsToDate(this=seq_get(args, 0)), 320 expression=exp.TsOrDsToDate(this=exp.Literal.string("0000-01-01")), 321 unit=exp.var("DAY"), 322 ) 323 + 1 324 ), 325 "WEEK": lambda args: exp.Week( 326 this=exp.TsOrDsToDate(this=seq_get(args, 0)), mode=seq_get(args, 1) 327 ), 328 "WEEKOFYEAR": lambda args: exp.WeekOfYear(this=exp.TsOrDsToDate(this=seq_get(args, 0))), 329 "YEAR": lambda args: exp.Year(this=exp.TsOrDsToDate(this=seq_get(args, 0))), 330 } 331 332 FUNCTION_PARSERS = { 333 **parser.Parser.FUNCTION_PARSERS, 334 "CHAR": lambda self: self.expression( 335 exp.Chr, 336 expressions=self._parse_csv(self._parse_assignment), 337 charset=self._match(TokenType.USING) and self._parse_var(), 338 ), 339 "GROUP_CONCAT": lambda self: self._parse_group_concat(), 340 # https://dev.mysql.com/doc/refman/5.7/en/miscellaneous-functions.html#function_values 341 "VALUES": lambda self: self.expression( 342 exp.Anonymous, this="VALUES", expressions=[self._parse_id_var()] 343 ), 344 "JSON_VALUE": lambda self: self._parse_json_value(), 345 } 346 347 STATEMENT_PARSERS = { 348 **parser.Parser.STATEMENT_PARSERS, 349 TokenType.SHOW: lambda self: self._parse_show(), 350 } 351 352 SHOW_PARSERS = { 353 "BINARY LOGS": _show_parser("BINARY LOGS"), 354 "MASTER LOGS": _show_parser("BINARY LOGS"), 355 "BINLOG EVENTS": _show_parser("BINLOG EVENTS"), 356 "CHARACTER SET": _show_parser("CHARACTER SET"), 357 "CHARSET": _show_parser("CHARACTER SET"), 358 "COLLATION": _show_parser("COLLATION"), 359 "FULL COLUMNS": _show_parser("COLUMNS", target="FROM", full=True), 360 "COLUMNS": _show_parser("COLUMNS", target="FROM"), 361 "CREATE DATABASE": _show_parser("CREATE DATABASE", target=True), 362 "CREATE EVENT": _show_parser("CREATE EVENT", target=True), 363 "CREATE FUNCTION": _show_parser("CREATE FUNCTION", target=True), 364 "CREATE PROCEDURE": _show_parser("CREATE PROCEDURE", target=True), 365 "CREATE TABLE": _show_parser("CREATE TABLE", target=True), 366 "CREATE TRIGGER": _show_parser("CREATE TRIGGER", target=True), 367 "CREATE VIEW": _show_parser("CREATE VIEW", target=True), 368 "DATABASES": _show_parser("DATABASES"), 369 "SCHEMAS": _show_parser("DATABASES"), 370 "ENGINE": _show_parser("ENGINE", target=True), 371 "STORAGE ENGINES": _show_parser("ENGINES"), 372 "ENGINES": _show_parser("ENGINES"), 373 "ERRORS": _show_parser("ERRORS"), 374 "EVENTS": _show_parser("EVENTS"), 375 "FUNCTION CODE": _show_parser("FUNCTION CODE", target=True), 376 "FUNCTION STATUS": _show_parser("FUNCTION STATUS"), 377 "GRANTS": _show_parser("GRANTS", target="FOR"), 378 "INDEX": _show_parser("INDEX", target="FROM"), 379 "MASTER STATUS": _show_parser("MASTER STATUS"), 380 "OPEN TABLES": _show_parser("OPEN TABLES"), 381 "PLUGINS": _show_parser("PLUGINS"), 382 "PROCEDURE CODE": _show_parser("PROCEDURE CODE", target=True), 383 "PROCEDURE STATUS": _show_parser("PROCEDURE STATUS"), 384 "PRIVILEGES": _show_parser("PRIVILEGES"), 385 "FULL PROCESSLIST": _show_parser("PROCESSLIST", full=True), 386 "PROCESSLIST": _show_parser("PROCESSLIST"), 387 "PROFILE": _show_parser("PROFILE"), 388 "PROFILES": _show_parser("PROFILES"), 389 "RELAYLOG EVENTS": _show_parser("RELAYLOG EVENTS"), 390 "REPLICAS": _show_parser("REPLICAS"), 391 "SLAVE HOSTS": _show_parser("REPLICAS"), 392 "REPLICA STATUS": _show_parser("REPLICA STATUS"), 393 "SLAVE STATUS": _show_parser("REPLICA STATUS"), 394 "GLOBAL STATUS": _show_parser("STATUS", global_=True), 395 "SESSION STATUS": _show_parser("STATUS"), 396 "STATUS": _show_parser("STATUS"), 397 "TABLE STATUS": _show_parser("TABLE STATUS"), 398 "FULL TABLES": _show_parser("TABLES", full=True), 399 "TABLES": _show_parser("TABLES"), 400 "TRIGGERS": _show_parser("TRIGGERS"), 401 "GLOBAL VARIABLES": _show_parser("VARIABLES", global_=True), 402 "SESSION VARIABLES": _show_parser("VARIABLES"), 403 "VARIABLES": _show_parser("VARIABLES"), 404 "WARNINGS": _show_parser("WARNINGS"), 405 } 406 407 PROPERTY_PARSERS = { 408 **parser.Parser.PROPERTY_PARSERS, 409 "LOCK": lambda self: self._parse_property_assignment(exp.LockProperty), 410 } 411 412 SET_PARSERS = { 413 **parser.Parser.SET_PARSERS, 414 "PERSIST": lambda self: self._parse_set_item_assignment("PERSIST"), 415 "PERSIST_ONLY": lambda self: self._parse_set_item_assignment("PERSIST_ONLY"), 416 "CHARACTER SET": lambda self: self._parse_set_item_charset("CHARACTER SET"), 417 "CHARSET": lambda self: self._parse_set_item_charset("CHARACTER SET"), 418 "NAMES": lambda self: self._parse_set_item_names(), 419 } 420 421 CONSTRAINT_PARSERS = { 422 **parser.Parser.CONSTRAINT_PARSERS, 423 "FULLTEXT": lambda self: self._parse_index_constraint(kind="FULLTEXT"), 424 "INDEX": lambda self: self._parse_index_constraint(), 425 "KEY": lambda self: self._parse_index_constraint(), 426 "SPATIAL": lambda self: self._parse_index_constraint(kind="SPATIAL"), 427 } 428 429 ALTER_PARSERS = { 430 **parser.Parser.ALTER_PARSERS, 431 "MODIFY": lambda self: self._parse_alter_table_alter(), 432 } 433 434 SCHEMA_UNNAMED_CONSTRAINTS = { 435 *parser.Parser.SCHEMA_UNNAMED_CONSTRAINTS, 436 "FULLTEXT", 437 "INDEX", 438 "KEY", 439 "SPATIAL", 440 } 441 442 PROFILE_TYPES: parser.OPTIONS_TYPE = { 443 **dict.fromkeys(("ALL", "CPU", "IPC", "MEMORY", "SOURCE", "SWAPS"), tuple()), 444 "BLOCK": ("IO",), 445 "CONTEXT": ("SWITCHES",), 446 "PAGE": ("FAULTS",), 447 } 448 449 TYPE_TOKENS = { 450 *parser.Parser.TYPE_TOKENS, 451 TokenType.SET, 452 } 453 454 ENUM_TYPE_TOKENS = { 455 *parser.Parser.ENUM_TYPE_TOKENS, 456 TokenType.SET, 457 } 458 459 # SELECT [ ALL | DISTINCT | DISTINCTROW ] [ <OPERATION_MODIFIERS> ] 460 OPERATION_MODIFIERS = { 461 "HIGH_PRIORITY", 462 "STRAIGHT_JOIN", 463 "SQL_SMALL_RESULT", 464 "SQL_BIG_RESULT", 465 "SQL_BUFFER_RESULT", 466 "SQL_NO_CACHE", 467 "SQL_CALC_FOUND_ROWS", 468 } 469 470 LOG_DEFAULTS_TO_LN = True 471 STRING_ALIASES = True 472 VALUES_FOLLOWED_BY_PAREN = False 473 SUPPORTS_PARTITION_SELECTION = True 474 475 def _parse_primary_key_part(self) -> t.Optional[exp.Expression]: 476 this = self._parse_id_var() 477 if not self._match(TokenType.L_PAREN): 478 return this 479 480 expression = self._parse_number() 481 self._match_r_paren() 482 return self.expression(exp.ColumnPrefix, this=this, expression=expression) 483 484 def _parse_index_constraint( 485 self, kind: t.Optional[str] = None 486 ) -> exp.IndexColumnConstraint: 487 if kind: 488 self._match_texts(("INDEX", "KEY")) 489 490 this = self._parse_id_var(any_token=False) 491 index_type = self._match(TokenType.USING) and self._advance_any() and self._prev.text 492 expressions = self._parse_wrapped_csv(self._parse_ordered) 493 494 options = [] 495 while True: 496 if self._match_text_seq("KEY_BLOCK_SIZE"): 497 self._match(TokenType.EQ) 498 opt = exp.IndexConstraintOption(key_block_size=self._parse_number()) 499 elif self._match(TokenType.USING): 500 opt = exp.IndexConstraintOption(using=self._advance_any() and self._prev.text) 501 elif self._match_text_seq("WITH", "PARSER"): 502 opt = exp.IndexConstraintOption(parser=self._parse_var(any_token=True)) 503 elif self._match(TokenType.COMMENT): 504 opt = exp.IndexConstraintOption(comment=self._parse_string()) 505 elif self._match_text_seq("VISIBLE"): 506 opt = exp.IndexConstraintOption(visible=True) 507 elif self._match_text_seq("INVISIBLE"): 508 opt = exp.IndexConstraintOption(visible=False) 509 elif self._match_text_seq("ENGINE_ATTRIBUTE"): 510 self._match(TokenType.EQ) 511 opt = exp.IndexConstraintOption(engine_attr=self._parse_string()) 512 elif self._match_text_seq("SECONDARY_ENGINE_ATTRIBUTE"): 513 self._match(TokenType.EQ) 514 opt = exp.IndexConstraintOption(secondary_engine_attr=self._parse_string()) 515 else: 516 opt = None 517 518 if not opt: 519 break 520 521 options.append(opt) 522 523 return self.expression( 524 exp.IndexColumnConstraint, 525 this=this, 526 expressions=expressions, 527 kind=kind, 528 index_type=index_type, 529 options=options, 530 ) 531 532 def _parse_show_mysql( 533 self, 534 this: str, 535 target: bool | str = False, 536 full: t.Optional[bool] = None, 537 global_: t.Optional[bool] = None, 538 ) -> exp.Show: 539 if target: 540 if isinstance(target, str): 541 self._match_text_seq(target) 542 target_id = self._parse_id_var() 543 else: 544 target_id = None 545 546 log = self._parse_string() if self._match_text_seq("IN") else None 547 548 if this in ("BINLOG EVENTS", "RELAYLOG EVENTS"): 549 position = self._parse_number() if self._match_text_seq("FROM") else None 550 db = None 551 else: 552 position = None 553 db = None 554 555 if self._match(TokenType.FROM): 556 db = self._parse_id_var() 557 elif self._match(TokenType.DOT): 558 db = target_id 559 target_id = self._parse_id_var() 560 561 channel = self._parse_id_var() if self._match_text_seq("FOR", "CHANNEL") else None 562 563 like = self._parse_string() if self._match_text_seq("LIKE") else None 564 where = self._parse_where() 565 566 if this == "PROFILE": 567 types = self._parse_csv(lambda: self._parse_var_from_options(self.PROFILE_TYPES)) 568 query = self._parse_number() if self._match_text_seq("FOR", "QUERY") else None 569 offset = self._parse_number() if self._match_text_seq("OFFSET") else None 570 limit = self._parse_number() if self._match_text_seq("LIMIT") else None 571 else: 572 types, query = None, None 573 offset, limit = self._parse_oldstyle_limit() 574 575 mutex = True if self._match_text_seq("MUTEX") else None 576 mutex = False if self._match_text_seq("STATUS") else mutex 577 578 return self.expression( 579 exp.Show, 580 this=this, 581 target=target_id, 582 full=full, 583 log=log, 584 position=position, 585 db=db, 586 channel=channel, 587 like=like, 588 where=where, 589 types=types, 590 query=query, 591 offset=offset, 592 limit=limit, 593 mutex=mutex, 594 **{"global": global_}, # type: ignore 595 ) 596 597 def _parse_oldstyle_limit( 598 self, 599 ) -> t.Tuple[t.Optional[exp.Expression], t.Optional[exp.Expression]]: 600 limit = None 601 offset = None 602 if self._match_text_seq("LIMIT"): 603 parts = self._parse_csv(self._parse_number) 604 if len(parts) == 1: 605 limit = parts[0] 606 elif len(parts) == 2: 607 limit = parts[1] 608 offset = parts[0] 609 610 return offset, limit 611 612 def _parse_set_item_charset(self, kind: str) -> exp.Expression: 613 this = self._parse_string() or self._parse_unquoted_field() 614 return self.expression(exp.SetItem, this=this, kind=kind) 615 616 def _parse_set_item_names(self) -> exp.Expression: 617 charset = self._parse_string() or self._parse_unquoted_field() 618 if self._match_text_seq("COLLATE"): 619 collate = self._parse_string() or self._parse_unquoted_field() 620 else: 621 collate = None 622 623 return self.expression(exp.SetItem, this=charset, collate=collate, kind="NAMES") 624 625 def _parse_type( 626 self, parse_interval: bool = True, fallback_to_identifier: bool = False 627 ) -> t.Optional[exp.Expression]: 628 # mysql binary is special and can work anywhere, even in order by operations 629 # it operates like a no paren func 630 if self._match(TokenType.BINARY, advance=False): 631 data_type = self._parse_types(check_func=True, allow_identifiers=False) 632 633 if isinstance(data_type, exp.DataType): 634 return self.expression(exp.Cast, this=self._parse_column(), to=data_type) 635 636 return super()._parse_type( 637 parse_interval=parse_interval, fallback_to_identifier=fallback_to_identifier 638 ) 639 640 def _parse_group_concat(self) -> t.Optional[exp.Expression]: 641 def concat_exprs( 642 node: t.Optional[exp.Expression], exprs: t.List[exp.Expression] 643 ) -> exp.Expression: 644 if isinstance(node, exp.Distinct) and len(node.expressions) > 1: 645 concat_exprs = [ 646 self.expression(exp.Concat, expressions=node.expressions, safe=True) 647 ] 648 node.set("expressions", concat_exprs) 649 return node 650 if len(exprs) == 1: 651 return exprs[0] 652 return self.expression(exp.Concat, expressions=args, safe=True) 653 654 args = self._parse_csv(self._parse_lambda) 655 656 if args: 657 order = args[-1] if isinstance(args[-1], exp.Order) else None 658 659 if order: 660 # Order By is the last (or only) expression in the list and has consumed the 'expr' before it, 661 # remove 'expr' from exp.Order and add it back to args 662 args[-1] = order.this 663 order.set("this", concat_exprs(order.this, args)) 664 665 this = order or concat_exprs(args[0], args) 666 else: 667 this = None 668 669 separator = self._parse_field() if self._match(TokenType.SEPARATOR) else None 670 671 return self.expression(exp.GroupConcat, this=this, separator=separator) 672 673 def _parse_json_value(self) -> exp.JSONValue: 674 this = self._parse_bitwise() 675 self._match(TokenType.COMMA) 676 path = self._parse_bitwise() 677 678 returning = self._match(TokenType.RETURNING) and self._parse_type() 679 680 return self.expression( 681 exp.JSONValue, 682 this=this, 683 path=self.dialect.to_json_path(path), 684 returning=returning, 685 on_condition=self._parse_on_condition(), 686 ) 687 688 class Generator(generator.Generator): 689 INTERVAL_ALLOWS_PLURAL_FORM = False 690 LOCKING_READS_SUPPORTED = True 691 NULL_ORDERING_SUPPORTED = None 692 JOIN_HINTS = False 693 TABLE_HINTS = True 694 DUPLICATE_KEY_UPDATE_WITH_SET = False 695 QUERY_HINT_SEP = " " 696 VALUES_AS_TABLE = False 697 NVL2_SUPPORTED = False 698 LAST_DAY_SUPPORTS_DATE_PART = False 699 JSON_TYPE_REQUIRED_FOR_EXTRACTION = True 700 JSON_PATH_BRACKETED_KEY_SUPPORTED = False 701 JSON_KEY_VALUE_PAIR_SEP = "," 702 SUPPORTS_TO_NUMBER = False 703 PARSE_JSON_NAME: t.Optional[str] = None 704 PAD_FILL_PATTERN_IS_REQUIRED = True 705 WRAP_DERIVED_VALUES = False 706 VARCHAR_REQUIRES_SIZE = True 707 SUPPORTS_MEDIAN = False 708 709 TRANSFORMS = { 710 **generator.Generator.TRANSFORMS, 711 exp.ArrayAgg: rename_func("GROUP_CONCAT"), 712 exp.CurrentDate: no_paren_current_date_sql, 713 exp.DateDiff: _remove_ts_or_ds_to_date( 714 lambda self, e: self.func("DATEDIFF", e.this, e.expression), ("this", "expression") 715 ), 716 exp.DateAdd: _remove_ts_or_ds_to_date(date_add_sql("ADD")), 717 exp.DateStrToDate: datestrtodate_sql, 718 exp.DateSub: _remove_ts_or_ds_to_date(date_add_sql("SUB")), 719 exp.DateTrunc: _date_trunc_sql, 720 exp.Day: _remove_ts_or_ds_to_date(), 721 exp.DayOfMonth: _remove_ts_or_ds_to_date(rename_func("DAYOFMONTH")), 722 exp.DayOfWeek: _remove_ts_or_ds_to_date(rename_func("DAYOFWEEK")), 723 exp.DayOfYear: _remove_ts_or_ds_to_date(rename_func("DAYOFYEAR")), 724 exp.GroupConcat: lambda self, 725 e: f"""GROUP_CONCAT({self.sql(e, "this")} SEPARATOR {self.sql(e, "separator") or "','"})""", 726 exp.ILike: no_ilike_sql, 727 exp.JSONExtractScalar: arrow_json_extract_sql, 728 exp.Max: max_or_greatest, 729 exp.Min: min_or_least, 730 exp.Month: _remove_ts_or_ds_to_date(), 731 exp.NullSafeEQ: lambda self, e: self.binary(e, "<=>"), 732 exp.NullSafeNEQ: lambda self, e: f"NOT {self.binary(e, '<=>')}", 733 exp.Pivot: no_pivot_sql, 734 exp.Select: transforms.preprocess( 735 [ 736 transforms.eliminate_distinct_on, 737 transforms.eliminate_semi_and_anti_joins, 738 transforms.eliminate_qualify, 739 transforms.eliminate_full_outer_join, 740 transforms.unnest_generate_date_array_using_recursive_cte, 741 ] 742 ), 743 exp.StrPosition: strposition_to_locate_sql, 744 exp.StrToDate: _str_to_date_sql, 745 exp.StrToTime: _str_to_date_sql, 746 exp.Stuff: rename_func("INSERT"), 747 exp.TableSample: no_tablesample_sql, 748 exp.TimeFromParts: rename_func("MAKETIME"), 749 exp.TimestampAdd: date_add_interval_sql("DATE", "ADD"), 750 exp.TimestampDiff: lambda self, e: self.func( 751 "TIMESTAMPDIFF", unit_to_var(e), e.expression, e.this 752 ), 753 exp.TimestampSub: date_add_interval_sql("DATE", "SUB"), 754 exp.TimeStrToUnix: rename_func("UNIX_TIMESTAMP"), 755 exp.TimeStrToTime: lambda self, e: timestrtotime_sql( 756 self, 757 e, 758 include_precision=not e.args.get("zone"), 759 ), 760 exp.TimeToStr: _remove_ts_or_ds_to_date( 761 lambda self, e: self.func("DATE_FORMAT", e.this, self.format_time(e)) 762 ), 763 exp.Trim: trim_sql, 764 exp.TryCast: no_trycast_sql, 765 exp.TsOrDsAdd: date_add_sql("ADD"), 766 exp.TsOrDsDiff: lambda self, e: self.func("DATEDIFF", e.this, e.expression), 767 exp.TsOrDsToDate: _ts_or_ds_to_date_sql, 768 exp.UnixToTime: _unix_to_time_sql, 769 exp.Week: _remove_ts_or_ds_to_date(), 770 exp.WeekOfYear: _remove_ts_or_ds_to_date(rename_func("WEEKOFYEAR")), 771 exp.Year: _remove_ts_or_ds_to_date(), 772 } 773 774 UNSIGNED_TYPE_MAPPING = { 775 exp.DataType.Type.UBIGINT: "BIGINT", 776 exp.DataType.Type.UINT: "INT", 777 exp.DataType.Type.UMEDIUMINT: "MEDIUMINT", 778 exp.DataType.Type.USMALLINT: "SMALLINT", 779 exp.DataType.Type.UTINYINT: "TINYINT", 780 exp.DataType.Type.UDECIMAL: "DECIMAL", 781 } 782 783 TIMESTAMP_TYPE_MAPPING = { 784 exp.DataType.Type.TIMESTAMP: "DATETIME", 785 exp.DataType.Type.TIMESTAMPTZ: "TIMESTAMP", 786 exp.DataType.Type.TIMESTAMPLTZ: "TIMESTAMP", 787 } 788 789 TYPE_MAPPING = { 790 **generator.Generator.TYPE_MAPPING, 791 **UNSIGNED_TYPE_MAPPING, 792 **TIMESTAMP_TYPE_MAPPING, 793 } 794 795 TYPE_MAPPING.pop(exp.DataType.Type.MEDIUMTEXT) 796 TYPE_MAPPING.pop(exp.DataType.Type.LONGTEXT) 797 TYPE_MAPPING.pop(exp.DataType.Type.TINYTEXT) 798 TYPE_MAPPING.pop(exp.DataType.Type.MEDIUMBLOB) 799 TYPE_MAPPING.pop(exp.DataType.Type.LONGBLOB) 800 TYPE_MAPPING.pop(exp.DataType.Type.TINYBLOB) 801 802 PROPERTIES_LOCATION = { 803 **generator.Generator.PROPERTIES_LOCATION, 804 exp.TransientProperty: exp.Properties.Location.UNSUPPORTED, 805 exp.VolatileProperty: exp.Properties.Location.UNSUPPORTED, 806 } 807 808 LIMIT_FETCH = "LIMIT" 809 810 LIMIT_ONLY_LITERALS = True 811 812 CHAR_CAST_MAPPING = dict.fromkeys( 813 ( 814 exp.DataType.Type.LONGTEXT, 815 exp.DataType.Type.LONGBLOB, 816 exp.DataType.Type.MEDIUMBLOB, 817 exp.DataType.Type.MEDIUMTEXT, 818 exp.DataType.Type.TEXT, 819 exp.DataType.Type.TINYBLOB, 820 exp.DataType.Type.TINYTEXT, 821 exp.DataType.Type.VARCHAR, 822 ), 823 "CHAR", 824 ) 825 SIGNED_CAST_MAPPING = dict.fromkeys( 826 ( 827 exp.DataType.Type.BIGINT, 828 exp.DataType.Type.BOOLEAN, 829 exp.DataType.Type.INT, 830 exp.DataType.Type.SMALLINT, 831 exp.DataType.Type.TINYINT, 832 exp.DataType.Type.MEDIUMINT, 833 ), 834 "SIGNED", 835 ) 836 837 # MySQL doesn't support many datatypes in cast. 838 # https://dev.mysql.com/doc/refman/8.0/en/cast-functions.html#function_cast 839 CAST_MAPPING = { 840 **CHAR_CAST_MAPPING, 841 **SIGNED_CAST_MAPPING, 842 exp.DataType.Type.UBIGINT: "UNSIGNED", 843 } 844 845 TIMESTAMP_FUNC_TYPES = { 846 exp.DataType.Type.TIMESTAMPTZ, 847 exp.DataType.Type.TIMESTAMPLTZ, 848 } 849 850 # https://dev.mysql.com/doc/refman/8.0/en/keywords.html 851 RESERVED_KEYWORDS = { 852 "accessible", 853 "add", 854 "all", 855 "alter", 856 "analyze", 857 "and", 858 "as", 859 "asc", 860 "asensitive", 861 "before", 862 "between", 863 "bigint", 864 "binary", 865 "blob", 866 "both", 867 "by", 868 "call", 869 "cascade", 870 "case", 871 "change", 872 "char", 873 "character", 874 "check", 875 "collate", 876 "column", 877 "condition", 878 "constraint", 879 "continue", 880 "convert", 881 "create", 882 "cross", 883 "cube", 884 "cume_dist", 885 "current_date", 886 "current_time", 887 "current_timestamp", 888 "current_user", 889 "cursor", 890 "database", 891 "databases", 892 "day_hour", 893 "day_microsecond", 894 "day_minute", 895 "day_second", 896 "dec", 897 "decimal", 898 "declare", 899 "default", 900 "delayed", 901 "delete", 902 "dense_rank", 903 "desc", 904 "describe", 905 "deterministic", 906 "distinct", 907 "distinctrow", 908 "div", 909 "double", 910 "drop", 911 "dual", 912 "each", 913 "else", 914 "elseif", 915 "empty", 916 "enclosed", 917 "escaped", 918 "except", 919 "exists", 920 "exit", 921 "explain", 922 "false", 923 "fetch", 924 "first_value", 925 "float", 926 "float4", 927 "float8", 928 "for", 929 "force", 930 "foreign", 931 "from", 932 "fulltext", 933 "function", 934 "generated", 935 "get", 936 "grant", 937 "group", 938 "grouping", 939 "groups", 940 "having", 941 "high_priority", 942 "hour_microsecond", 943 "hour_minute", 944 "hour_second", 945 "if", 946 "ignore", 947 "in", 948 "index", 949 "infile", 950 "inner", 951 "inout", 952 "insensitive", 953 "insert", 954 "int", 955 "int1", 956 "int2", 957 "int3", 958 "int4", 959 "int8", 960 "integer", 961 "intersect", 962 "interval", 963 "into", 964 "io_after_gtids", 965 "io_before_gtids", 966 "is", 967 "iterate", 968 "join", 969 "json_table", 970 "key", 971 "keys", 972 "kill", 973 "lag", 974 "last_value", 975 "lateral", 976 "lead", 977 "leading", 978 "leave", 979 "left", 980 "like", 981 "limit", 982 "linear", 983 "lines", 984 "load", 985 "localtime", 986 "localtimestamp", 987 "lock", 988 "long", 989 "longblob", 990 "longtext", 991 "loop", 992 "low_priority", 993 "master_bind", 994 "master_ssl_verify_server_cert", 995 "match", 996 "maxvalue", 997 "mediumblob", 998 "mediumint", 999 "mediumtext", 1000 "middleint", 1001 "minute_microsecond", 1002 "minute_second", 1003 "mod", 1004 "modifies", 1005 "natural", 1006 "not", 1007 "no_write_to_binlog", 1008 "nth_value", 1009 "ntile", 1010 "null", 1011 "numeric", 1012 "of", 1013 "on", 1014 "optimize", 1015 "optimizer_costs", 1016 "option", 1017 "optionally", 1018 "or", 1019 "order", 1020 "out", 1021 "outer", 1022 "outfile", 1023 "over", 1024 "partition", 1025 "percent_rank", 1026 "precision", 1027 "primary", 1028 "procedure", 1029 "purge", 1030 "range", 1031 "rank", 1032 "read", 1033 "reads", 1034 "read_write", 1035 "real", 1036 "recursive", 1037 "references", 1038 "regexp", 1039 "release", 1040 "rename", 1041 "repeat", 1042 "replace", 1043 "require", 1044 "resignal", 1045 "restrict", 1046 "return", 1047 "revoke", 1048 "right", 1049 "rlike", 1050 "row", 1051 "rows", 1052 "row_number", 1053 "schema", 1054 "schemas", 1055 "second_microsecond", 1056 "select", 1057 "sensitive", 1058 "separator", 1059 "set", 1060 "show", 1061 "signal", 1062 "smallint", 1063 "spatial", 1064 "specific", 1065 "sql", 1066 "sqlexception", 1067 "sqlstate", 1068 "sqlwarning", 1069 "sql_big_result", 1070 "sql_calc_found_rows", 1071 "sql_small_result", 1072 "ssl", 1073 "starting", 1074 "stored", 1075 "straight_join", 1076 "system", 1077 "table", 1078 "terminated", 1079 "then", 1080 "tinyblob", 1081 "tinyint", 1082 "tinytext", 1083 "to", 1084 "trailing", 1085 "trigger", 1086 "true", 1087 "undo", 1088 "union", 1089 "unique", 1090 "unlock", 1091 "unsigned", 1092 "update", 1093 "usage", 1094 "use", 1095 "using", 1096 "utc_date", 1097 "utc_time", 1098 "utc_timestamp", 1099 "values", 1100 "varbinary", 1101 "varchar", 1102 "varcharacter", 1103 "varying", 1104 "virtual", 1105 "when", 1106 "where", 1107 "while", 1108 "window", 1109 "with", 1110 "write", 1111 "xor", 1112 "year_month", 1113 "zerofill", 1114 } 1115 1116 def array_sql(self, expression: exp.Array) -> str: 1117 self.unsupported("Arrays are not supported by MySQL") 1118 return self.function_fallback_sql(expression) 1119 1120 def arraycontainsall_sql(self, expression: exp.ArrayContainsAll) -> str: 1121 self.unsupported("Array operations are not supported by MySQL") 1122 return self.function_fallback_sql(expression) 1123 1124 def dpipe_sql(self, expression: exp.DPipe) -> str: 1125 return self.func("CONCAT", *expression.flatten()) 1126 1127 def extract_sql(self, expression: exp.Extract) -> str: 1128 unit = expression.name 1129 if unit and unit.lower() == "epoch": 1130 return self.func("UNIX_TIMESTAMP", expression.expression) 1131 1132 return super().extract_sql(expression) 1133 1134 def datatype_sql(self, expression: exp.DataType) -> str: 1135 if ( 1136 self.VARCHAR_REQUIRES_SIZE 1137 and expression.is_type(exp.DataType.Type.VARCHAR) 1138 and not expression.expressions 1139 ): 1140 # `VARCHAR` must always have a size - if it doesn't, we always generate `TEXT` 1141 return "TEXT" 1142 1143 # https://dev.mysql.com/doc/refman/8.0/en/numeric-type-syntax.html 1144 result = super().datatype_sql(expression) 1145 if expression.this in self.UNSIGNED_TYPE_MAPPING: 1146 result = f"{result} UNSIGNED" 1147 1148 return result 1149 1150 def jsonarraycontains_sql(self, expression: exp.JSONArrayContains) -> str: 1151 return f"{self.sql(expression, 'this')} MEMBER OF({self.sql(expression, 'expression')})" 1152 1153 def cast_sql(self, expression: exp.Cast, safe_prefix: t.Optional[str] = None) -> str: 1154 if expression.to.this in self.TIMESTAMP_FUNC_TYPES: 1155 return self.func("TIMESTAMP", expression.this) 1156 1157 to = self.CAST_MAPPING.get(expression.to.this) 1158 1159 if to: 1160 expression.to.set("this", to) 1161 return super().cast_sql(expression) 1162 1163 def show_sql(self, expression: exp.Show) -> str: 1164 this = f" {expression.name}" 1165 full = " FULL" if expression.args.get("full") else "" 1166 global_ = " GLOBAL" if expression.args.get("global") else "" 1167 1168 target = self.sql(expression, "target") 1169 target = f" {target}" if target else "" 1170 if expression.name in ("COLUMNS", "INDEX"): 1171 target = f" FROM{target}" 1172 elif expression.name == "GRANTS": 1173 target = f" FOR{target}" 1174 1175 db = self._prefixed_sql("FROM", expression, "db") 1176 1177 like = self._prefixed_sql("LIKE", expression, "like") 1178 where = self.sql(expression, "where") 1179 1180 types = self.expressions(expression, key="types") 1181 types = f" {types}" if types else types 1182 query = self._prefixed_sql("FOR QUERY", expression, "query") 1183 1184 if expression.name == "PROFILE": 1185 offset = self._prefixed_sql("OFFSET", expression, "offset") 1186 limit = self._prefixed_sql("LIMIT", expression, "limit") 1187 else: 1188 offset = "" 1189 limit = self._oldstyle_limit_sql(expression) 1190 1191 log = self._prefixed_sql("IN", expression, "log") 1192 position = self._prefixed_sql("FROM", expression, "position") 1193 1194 channel = self._prefixed_sql("FOR CHANNEL", expression, "channel") 1195 1196 if expression.name == "ENGINE": 1197 mutex_or_status = " MUTEX" if expression.args.get("mutex") else " STATUS" 1198 else: 1199 mutex_or_status = "" 1200 1201 return f"SHOW{full}{global_}{this}{target}{types}{db}{query}{log}{position}{channel}{mutex_or_status}{like}{where}{offset}{limit}" 1202 1203 def altercolumn_sql(self, expression: exp.AlterColumn) -> str: 1204 dtype = self.sql(expression, "dtype") 1205 if not dtype: 1206 return super().altercolumn_sql(expression) 1207 1208 this = self.sql(expression, "this") 1209 return f"MODIFY COLUMN {this} {dtype}" 1210 1211 def _prefixed_sql(self, prefix: str, expression: exp.Expression, arg: str) -> str: 1212 sql = self.sql(expression, arg) 1213 return f" {prefix} {sql}" if sql else "" 1214 1215 def _oldstyle_limit_sql(self, expression: exp.Show) -> str: 1216 limit = self.sql(expression, "limit") 1217 offset = self.sql(expression, "offset") 1218 if limit: 1219 limit_offset = f"{offset}, {limit}" if offset else limit 1220 return f" LIMIT {limit_offset}" 1221 return "" 1222 1223 def chr_sql(self, expression: exp.Chr) -> str: 1224 this = self.expressions(sqls=[expression.this] + expression.expressions) 1225 charset = expression.args.get("charset") 1226 using = f" USING {self.sql(charset)}" if charset else "" 1227 return f"CHAR({this}{using})" 1228 1229 def timestamptrunc_sql(self, expression: exp.TimestampTrunc) -> str: 1230 unit = expression.args.get("unit") 1231 1232 # Pick an old-enough date to avoid negative timestamp diffs 1233 start_ts = "'0000-01-01 00:00:00'" 1234 1235 # Source: https://stackoverflow.com/a/32955740 1236 timestamp_diff = build_date_delta(exp.TimestampDiff)([unit, start_ts, expression.this]) 1237 interval = exp.Interval(this=timestamp_diff, unit=unit) 1238 dateadd = build_date_delta_with_interval(exp.DateAdd)([start_ts, interval]) 1239 1240 return self.sql(dateadd) 1241 1242 def converttimezone_sql(self, expression: exp.ConvertTimezone) -> str: 1243 from_tz = expression.args.get("source_tz") 1244 to_tz = expression.args.get("target_tz") 1245 dt = expression.args.get("timestamp") 1246 1247 return self.func("CONVERT_TZ", dt, from_tz, to_tz) 1248 1249 def attimezone_sql(self, expression: exp.AtTimeZone) -> str: 1250 self.unsupported("AT TIME ZONE is not supported by MySQL") 1251 return self.sql(expression.this)
TIME_SPECIFIERS =
{'T', 'p', 'H', 'k', 'S', 's', 'l', 'f', 'h', 'I', 'r', '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 # https://dev.mysql.com/doc/refman/8.0/en/identifiers.html 150 IDENTIFIERS_CAN_START_WITH_DIGIT = True 151 152 # We default to treating all identifiers as case-sensitive, since it matches MySQL's 153 # behavior on Linux systems. For MacOS and Windows systems, one can override this 154 # setting by specifying `dialect="mysql, normalization_strategy = lowercase"`. 155 # 156 # See also https://dev.mysql.com/doc/refman/8.2/en/identifier-case-sensitivity.html 157 NORMALIZATION_STRATEGY = NormalizationStrategy.CASE_SENSITIVE 158 159 TIME_FORMAT = "'%Y-%m-%d %T'" 160 DPIPE_IS_STRING_CONCAT = False 161 SUPPORTS_USER_DEFINED_TYPES = False 162 SUPPORTS_SEMI_ANTI_JOIN = False 163 SAFE_DIVISION = True 164 165 # https://prestodb.io/docs/current/functions/datetime.html#mysql-date-functions 166 TIME_MAPPING = { 167 "%M": "%B", 168 "%c": "%-m", 169 "%e": "%-d", 170 "%h": "%I", 171 "%i": "%M", 172 "%s": "%S", 173 "%u": "%W", 174 "%k": "%-H", 175 "%l": "%-I", 176 "%T": "%H:%M:%S", 177 "%W": "%A", 178 } 179 180 class Tokenizer(tokens.Tokenizer): 181 QUOTES = ["'", '"'] 182 COMMENTS = ["--", "#", ("/*", "*/")] 183 IDENTIFIERS = ["`"] 184 STRING_ESCAPES = ["'", '"', "\\"] 185 BIT_STRINGS = [("b'", "'"), ("B'", "'"), ("0b", "")] 186 HEX_STRINGS = [("x'", "'"), ("X'", "'"), ("0x", "")] 187 188 KEYWORDS = { 189 **tokens.Tokenizer.KEYWORDS, 190 "CHARSET": TokenType.CHARACTER_SET, 191 # The DESCRIBE and EXPLAIN statements are synonyms. 192 # https://dev.mysql.com/doc/refman/8.4/en/explain.html 193 "EXPLAIN": TokenType.DESCRIBE, 194 "FORCE": TokenType.FORCE, 195 "IGNORE": TokenType.IGNORE, 196 "KEY": TokenType.KEY, 197 "LOCK TABLES": TokenType.COMMAND, 198 "LONGBLOB": TokenType.LONGBLOB, 199 "LONGTEXT": TokenType.LONGTEXT, 200 "MEDIUMBLOB": TokenType.MEDIUMBLOB, 201 "TINYBLOB": TokenType.TINYBLOB, 202 "TINYTEXT": TokenType.TINYTEXT, 203 "MEDIUMTEXT": TokenType.MEDIUMTEXT, 204 "MEDIUMINT": TokenType.MEDIUMINT, 205 "MEMBER OF": TokenType.MEMBER_OF, 206 "SEPARATOR": TokenType.SEPARATOR, 207 "START": TokenType.BEGIN, 208 "SIGNED": TokenType.BIGINT, 209 "SIGNED INTEGER": TokenType.BIGINT, 210 "UNLOCK TABLES": TokenType.COMMAND, 211 "UNSIGNED": TokenType.UBIGINT, 212 "UNSIGNED INTEGER": TokenType.UBIGINT, 213 "YEAR": TokenType.YEAR, 214 "_ARMSCII8": TokenType.INTRODUCER, 215 "_ASCII": TokenType.INTRODUCER, 216 "_BIG5": TokenType.INTRODUCER, 217 "_BINARY": TokenType.INTRODUCER, 218 "_CP1250": TokenType.INTRODUCER, 219 "_CP1251": TokenType.INTRODUCER, 220 "_CP1256": TokenType.INTRODUCER, 221 "_CP1257": TokenType.INTRODUCER, 222 "_CP850": TokenType.INTRODUCER, 223 "_CP852": TokenType.INTRODUCER, 224 "_CP866": TokenType.INTRODUCER, 225 "_CP932": TokenType.INTRODUCER, 226 "_DEC8": TokenType.INTRODUCER, 227 "_EUCJPMS": TokenType.INTRODUCER, 228 "_EUCKR": TokenType.INTRODUCER, 229 "_GB18030": TokenType.INTRODUCER, 230 "_GB2312": TokenType.INTRODUCER, 231 "_GBK": TokenType.INTRODUCER, 232 "_GEOSTD8": TokenType.INTRODUCER, 233 "_GREEK": TokenType.INTRODUCER, 234 "_HEBREW": TokenType.INTRODUCER, 235 "_HP8": TokenType.INTRODUCER, 236 "_KEYBCS2": TokenType.INTRODUCER, 237 "_KOI8R": TokenType.INTRODUCER, 238 "_KOI8U": TokenType.INTRODUCER, 239 "_LATIN1": TokenType.INTRODUCER, 240 "_LATIN2": TokenType.INTRODUCER, 241 "_LATIN5": TokenType.INTRODUCER, 242 "_LATIN7": TokenType.INTRODUCER, 243 "_MACCE": TokenType.INTRODUCER, 244 "_MACROMAN": TokenType.INTRODUCER, 245 "_SJIS": TokenType.INTRODUCER, 246 "_SWE7": TokenType.INTRODUCER, 247 "_TIS620": TokenType.INTRODUCER, 248 "_UCS2": TokenType.INTRODUCER, 249 "_UJIS": TokenType.INTRODUCER, 250 # https://dev.mysql.com/doc/refman/8.0/en/string-literals.html 251 "_UTF8": TokenType.INTRODUCER, 252 "_UTF16": TokenType.INTRODUCER, 253 "_UTF16LE": TokenType.INTRODUCER, 254 "_UTF32": TokenType.INTRODUCER, 255 "_UTF8MB3": TokenType.INTRODUCER, 256 "_UTF8MB4": TokenType.INTRODUCER, 257 "@@": TokenType.SESSION_PARAMETER, 258 } 259 260 COMMANDS = {*tokens.Tokenizer.COMMANDS, TokenType.REPLACE} - {TokenType.SHOW} 261 262 class Parser(parser.Parser): 263 FUNC_TOKENS = { 264 *parser.Parser.FUNC_TOKENS, 265 TokenType.DATABASE, 266 TokenType.SCHEMA, 267 TokenType.VALUES, 268 } 269 270 CONJUNCTION = { 271 **parser.Parser.CONJUNCTION, 272 TokenType.DAMP: exp.And, 273 TokenType.XOR: exp.Xor, 274 } 275 276 DISJUNCTION = { 277 **parser.Parser.DISJUNCTION, 278 TokenType.DPIPE: exp.Or, 279 } 280 281 TABLE_ALIAS_TOKENS = ( 282 parser.Parser.TABLE_ALIAS_TOKENS - parser.Parser.TABLE_INDEX_HINT_TOKENS 283 ) 284 285 RANGE_PARSERS = { 286 **parser.Parser.RANGE_PARSERS, 287 TokenType.MEMBER_OF: lambda self, this: self.expression( 288 exp.JSONArrayContains, 289 this=this, 290 expression=self._parse_wrapped(self._parse_expression), 291 ), 292 } 293 294 FUNCTIONS = { 295 **parser.Parser.FUNCTIONS, 296 "CONVERT_TZ": lambda args: exp.ConvertTimezone( 297 source_tz=seq_get(args, 1), target_tz=seq_get(args, 2), timestamp=seq_get(args, 0) 298 ), 299 "DATE": lambda args: exp.TsOrDsToDate(this=seq_get(args, 0)), 300 "DATE_ADD": build_date_delta_with_interval(exp.DateAdd), 301 "DATE_FORMAT": build_formatted_time(exp.TimeToStr, "mysql"), 302 "DATE_SUB": build_date_delta_with_interval(exp.DateSub), 303 "DAY": lambda args: exp.Day(this=exp.TsOrDsToDate(this=seq_get(args, 0))), 304 "DAYOFMONTH": lambda args: exp.DayOfMonth(this=exp.TsOrDsToDate(this=seq_get(args, 0))), 305 "DAYOFWEEK": lambda args: exp.DayOfWeek(this=exp.TsOrDsToDate(this=seq_get(args, 0))), 306 "DAYOFYEAR": lambda args: exp.DayOfYear(this=exp.TsOrDsToDate(this=seq_get(args, 0))), 307 "FROM_UNIXTIME": build_formatted_time(exp.UnixToTime, "mysql"), 308 "ISNULL": isnull_to_is_null, 309 "LOCATE": locate_to_strposition, 310 "MAKETIME": exp.TimeFromParts.from_arg_list, 311 "MONTH": lambda args: exp.Month(this=exp.TsOrDsToDate(this=seq_get(args, 0))), 312 "MONTHNAME": lambda args: exp.TimeToStr( 313 this=exp.TsOrDsToDate(this=seq_get(args, 0)), 314 format=exp.Literal.string("%B"), 315 ), 316 "STR_TO_DATE": _str_to_date, 317 "TIMESTAMPDIFF": build_date_delta(exp.TimestampDiff), 318 "TO_DAYS": lambda args: exp.paren( 319 exp.DateDiff( 320 this=exp.TsOrDsToDate(this=seq_get(args, 0)), 321 expression=exp.TsOrDsToDate(this=exp.Literal.string("0000-01-01")), 322 unit=exp.var("DAY"), 323 ) 324 + 1 325 ), 326 "WEEK": lambda args: exp.Week( 327 this=exp.TsOrDsToDate(this=seq_get(args, 0)), mode=seq_get(args, 1) 328 ), 329 "WEEKOFYEAR": lambda args: exp.WeekOfYear(this=exp.TsOrDsToDate(this=seq_get(args, 0))), 330 "YEAR": lambda args: exp.Year(this=exp.TsOrDsToDate(this=seq_get(args, 0))), 331 } 332 333 FUNCTION_PARSERS = { 334 **parser.Parser.FUNCTION_PARSERS, 335 "CHAR": lambda self: self.expression( 336 exp.Chr, 337 expressions=self._parse_csv(self._parse_assignment), 338 charset=self._match(TokenType.USING) and self._parse_var(), 339 ), 340 "GROUP_CONCAT": lambda self: self._parse_group_concat(), 341 # https://dev.mysql.com/doc/refman/5.7/en/miscellaneous-functions.html#function_values 342 "VALUES": lambda self: self.expression( 343 exp.Anonymous, this="VALUES", expressions=[self._parse_id_var()] 344 ), 345 "JSON_VALUE": lambda self: self._parse_json_value(), 346 } 347 348 STATEMENT_PARSERS = { 349 **parser.Parser.STATEMENT_PARSERS, 350 TokenType.SHOW: lambda self: self._parse_show(), 351 } 352 353 SHOW_PARSERS = { 354 "BINARY LOGS": _show_parser("BINARY LOGS"), 355 "MASTER LOGS": _show_parser("BINARY LOGS"), 356 "BINLOG EVENTS": _show_parser("BINLOG EVENTS"), 357 "CHARACTER SET": _show_parser("CHARACTER SET"), 358 "CHARSET": _show_parser("CHARACTER SET"), 359 "COLLATION": _show_parser("COLLATION"), 360 "FULL COLUMNS": _show_parser("COLUMNS", target="FROM", full=True), 361 "COLUMNS": _show_parser("COLUMNS", target="FROM"), 362 "CREATE DATABASE": _show_parser("CREATE DATABASE", target=True), 363 "CREATE EVENT": _show_parser("CREATE EVENT", target=True), 364 "CREATE FUNCTION": _show_parser("CREATE FUNCTION", target=True), 365 "CREATE PROCEDURE": _show_parser("CREATE PROCEDURE", target=True), 366 "CREATE TABLE": _show_parser("CREATE TABLE", target=True), 367 "CREATE TRIGGER": _show_parser("CREATE TRIGGER", target=True), 368 "CREATE VIEW": _show_parser("CREATE VIEW", target=True), 369 "DATABASES": _show_parser("DATABASES"), 370 "SCHEMAS": _show_parser("DATABASES"), 371 "ENGINE": _show_parser("ENGINE", target=True), 372 "STORAGE ENGINES": _show_parser("ENGINES"), 373 "ENGINES": _show_parser("ENGINES"), 374 "ERRORS": _show_parser("ERRORS"), 375 "EVENTS": _show_parser("EVENTS"), 376 "FUNCTION CODE": _show_parser("FUNCTION CODE", target=True), 377 "FUNCTION STATUS": _show_parser("FUNCTION STATUS"), 378 "GRANTS": _show_parser("GRANTS", target="FOR"), 379 "INDEX": _show_parser("INDEX", target="FROM"), 380 "MASTER STATUS": _show_parser("MASTER STATUS"), 381 "OPEN TABLES": _show_parser("OPEN TABLES"), 382 "PLUGINS": _show_parser("PLUGINS"), 383 "PROCEDURE CODE": _show_parser("PROCEDURE CODE", target=True), 384 "PROCEDURE STATUS": _show_parser("PROCEDURE STATUS"), 385 "PRIVILEGES": _show_parser("PRIVILEGES"), 386 "FULL PROCESSLIST": _show_parser("PROCESSLIST", full=True), 387 "PROCESSLIST": _show_parser("PROCESSLIST"), 388 "PROFILE": _show_parser("PROFILE"), 389 "PROFILES": _show_parser("PROFILES"), 390 "RELAYLOG EVENTS": _show_parser("RELAYLOG EVENTS"), 391 "REPLICAS": _show_parser("REPLICAS"), 392 "SLAVE HOSTS": _show_parser("REPLICAS"), 393 "REPLICA STATUS": _show_parser("REPLICA STATUS"), 394 "SLAVE STATUS": _show_parser("REPLICA STATUS"), 395 "GLOBAL STATUS": _show_parser("STATUS", global_=True), 396 "SESSION STATUS": _show_parser("STATUS"), 397 "STATUS": _show_parser("STATUS"), 398 "TABLE STATUS": _show_parser("TABLE STATUS"), 399 "FULL TABLES": _show_parser("TABLES", full=True), 400 "TABLES": _show_parser("TABLES"), 401 "TRIGGERS": _show_parser("TRIGGERS"), 402 "GLOBAL VARIABLES": _show_parser("VARIABLES", global_=True), 403 "SESSION VARIABLES": _show_parser("VARIABLES"), 404 "VARIABLES": _show_parser("VARIABLES"), 405 "WARNINGS": _show_parser("WARNINGS"), 406 } 407 408 PROPERTY_PARSERS = { 409 **parser.Parser.PROPERTY_PARSERS, 410 "LOCK": lambda self: self._parse_property_assignment(exp.LockProperty), 411 } 412 413 SET_PARSERS = { 414 **parser.Parser.SET_PARSERS, 415 "PERSIST": lambda self: self._parse_set_item_assignment("PERSIST"), 416 "PERSIST_ONLY": lambda self: self._parse_set_item_assignment("PERSIST_ONLY"), 417 "CHARACTER SET": lambda self: self._parse_set_item_charset("CHARACTER SET"), 418 "CHARSET": lambda self: self._parse_set_item_charset("CHARACTER SET"), 419 "NAMES": lambda self: self._parse_set_item_names(), 420 } 421 422 CONSTRAINT_PARSERS = { 423 **parser.Parser.CONSTRAINT_PARSERS, 424 "FULLTEXT": lambda self: self._parse_index_constraint(kind="FULLTEXT"), 425 "INDEX": lambda self: self._parse_index_constraint(), 426 "KEY": lambda self: self._parse_index_constraint(), 427 "SPATIAL": lambda self: self._parse_index_constraint(kind="SPATIAL"), 428 } 429 430 ALTER_PARSERS = { 431 **parser.Parser.ALTER_PARSERS, 432 "MODIFY": lambda self: self._parse_alter_table_alter(), 433 } 434 435 SCHEMA_UNNAMED_CONSTRAINTS = { 436 *parser.Parser.SCHEMA_UNNAMED_CONSTRAINTS, 437 "FULLTEXT", 438 "INDEX", 439 "KEY", 440 "SPATIAL", 441 } 442 443 PROFILE_TYPES: parser.OPTIONS_TYPE = { 444 **dict.fromkeys(("ALL", "CPU", "IPC", "MEMORY", "SOURCE", "SWAPS"), tuple()), 445 "BLOCK": ("IO",), 446 "CONTEXT": ("SWITCHES",), 447 "PAGE": ("FAULTS",), 448 } 449 450 TYPE_TOKENS = { 451 *parser.Parser.TYPE_TOKENS, 452 TokenType.SET, 453 } 454 455 ENUM_TYPE_TOKENS = { 456 *parser.Parser.ENUM_TYPE_TOKENS, 457 TokenType.SET, 458 } 459 460 # SELECT [ ALL | DISTINCT | DISTINCTROW ] [ <OPERATION_MODIFIERS> ] 461 OPERATION_MODIFIERS = { 462 "HIGH_PRIORITY", 463 "STRAIGHT_JOIN", 464 "SQL_SMALL_RESULT", 465 "SQL_BIG_RESULT", 466 "SQL_BUFFER_RESULT", 467 "SQL_NO_CACHE", 468 "SQL_CALC_FOUND_ROWS", 469 } 470 471 LOG_DEFAULTS_TO_LN = True 472 STRING_ALIASES = True 473 VALUES_FOLLOWED_BY_PAREN = False 474 SUPPORTS_PARTITION_SELECTION = True 475 476 def _parse_primary_key_part(self) -> t.Optional[exp.Expression]: 477 this = self._parse_id_var() 478 if not self._match(TokenType.L_PAREN): 479 return this 480 481 expression = self._parse_number() 482 self._match_r_paren() 483 return self.expression(exp.ColumnPrefix, this=this, expression=expression) 484 485 def _parse_index_constraint( 486 self, kind: t.Optional[str] = None 487 ) -> exp.IndexColumnConstraint: 488 if kind: 489 self._match_texts(("INDEX", "KEY")) 490 491 this = self._parse_id_var(any_token=False) 492 index_type = self._match(TokenType.USING) and self._advance_any() and self._prev.text 493 expressions = self._parse_wrapped_csv(self._parse_ordered) 494 495 options = [] 496 while True: 497 if self._match_text_seq("KEY_BLOCK_SIZE"): 498 self._match(TokenType.EQ) 499 opt = exp.IndexConstraintOption(key_block_size=self._parse_number()) 500 elif self._match(TokenType.USING): 501 opt = exp.IndexConstraintOption(using=self._advance_any() and self._prev.text) 502 elif self._match_text_seq("WITH", "PARSER"): 503 opt = exp.IndexConstraintOption(parser=self._parse_var(any_token=True)) 504 elif self._match(TokenType.COMMENT): 505 opt = exp.IndexConstraintOption(comment=self._parse_string()) 506 elif self._match_text_seq("VISIBLE"): 507 opt = exp.IndexConstraintOption(visible=True) 508 elif self._match_text_seq("INVISIBLE"): 509 opt = exp.IndexConstraintOption(visible=False) 510 elif self._match_text_seq("ENGINE_ATTRIBUTE"): 511 self._match(TokenType.EQ) 512 opt = exp.IndexConstraintOption(engine_attr=self._parse_string()) 513 elif self._match_text_seq("SECONDARY_ENGINE_ATTRIBUTE"): 514 self._match(TokenType.EQ) 515 opt = exp.IndexConstraintOption(secondary_engine_attr=self._parse_string()) 516 else: 517 opt = None 518 519 if not opt: 520 break 521 522 options.append(opt) 523 524 return self.expression( 525 exp.IndexColumnConstraint, 526 this=this, 527 expressions=expressions, 528 kind=kind, 529 index_type=index_type, 530 options=options, 531 ) 532 533 def _parse_show_mysql( 534 self, 535 this: str, 536 target: bool | str = False, 537 full: t.Optional[bool] = None, 538 global_: t.Optional[bool] = None, 539 ) -> exp.Show: 540 if target: 541 if isinstance(target, str): 542 self._match_text_seq(target) 543 target_id = self._parse_id_var() 544 else: 545 target_id = None 546 547 log = self._parse_string() if self._match_text_seq("IN") else None 548 549 if this in ("BINLOG EVENTS", "RELAYLOG EVENTS"): 550 position = self._parse_number() if self._match_text_seq("FROM") else None 551 db = None 552 else: 553 position = None 554 db = None 555 556 if self._match(TokenType.FROM): 557 db = self._parse_id_var() 558 elif self._match(TokenType.DOT): 559 db = target_id 560 target_id = self._parse_id_var() 561 562 channel = self._parse_id_var() if self._match_text_seq("FOR", "CHANNEL") else None 563 564 like = self._parse_string() if self._match_text_seq("LIKE") else None 565 where = self._parse_where() 566 567 if this == "PROFILE": 568 types = self._parse_csv(lambda: self._parse_var_from_options(self.PROFILE_TYPES)) 569 query = self._parse_number() if self._match_text_seq("FOR", "QUERY") else None 570 offset = self._parse_number() if self._match_text_seq("OFFSET") else None 571 limit = self._parse_number() if self._match_text_seq("LIMIT") else None 572 else: 573 types, query = None, None 574 offset, limit = self._parse_oldstyle_limit() 575 576 mutex = True if self._match_text_seq("MUTEX") else None 577 mutex = False if self._match_text_seq("STATUS") else mutex 578 579 return self.expression( 580 exp.Show, 581 this=this, 582 target=target_id, 583 full=full, 584 log=log, 585 position=position, 586 db=db, 587 channel=channel, 588 like=like, 589 where=where, 590 types=types, 591 query=query, 592 offset=offset, 593 limit=limit, 594 mutex=mutex, 595 **{"global": global_}, # type: ignore 596 ) 597 598 def _parse_oldstyle_limit( 599 self, 600 ) -> t.Tuple[t.Optional[exp.Expression], t.Optional[exp.Expression]]: 601 limit = None 602 offset = None 603 if self._match_text_seq("LIMIT"): 604 parts = self._parse_csv(self._parse_number) 605 if len(parts) == 1: 606 limit = parts[0] 607 elif len(parts) == 2: 608 limit = parts[1] 609 offset = parts[0] 610 611 return offset, limit 612 613 def _parse_set_item_charset(self, kind: str) -> exp.Expression: 614 this = self._parse_string() or self._parse_unquoted_field() 615 return self.expression(exp.SetItem, this=this, kind=kind) 616 617 def _parse_set_item_names(self) -> exp.Expression: 618 charset = self._parse_string() or self._parse_unquoted_field() 619 if self._match_text_seq("COLLATE"): 620 collate = self._parse_string() or self._parse_unquoted_field() 621 else: 622 collate = None 623 624 return self.expression(exp.SetItem, this=charset, collate=collate, kind="NAMES") 625 626 def _parse_type( 627 self, parse_interval: bool = True, fallback_to_identifier: bool = False 628 ) -> t.Optional[exp.Expression]: 629 # mysql binary is special and can work anywhere, even in order by operations 630 # it operates like a no paren func 631 if self._match(TokenType.BINARY, advance=False): 632 data_type = self._parse_types(check_func=True, allow_identifiers=False) 633 634 if isinstance(data_type, exp.DataType): 635 return self.expression(exp.Cast, this=self._parse_column(), to=data_type) 636 637 return super()._parse_type( 638 parse_interval=parse_interval, fallback_to_identifier=fallback_to_identifier 639 ) 640 641 def _parse_group_concat(self) -> t.Optional[exp.Expression]: 642 def concat_exprs( 643 node: t.Optional[exp.Expression], exprs: t.List[exp.Expression] 644 ) -> exp.Expression: 645 if isinstance(node, exp.Distinct) and len(node.expressions) > 1: 646 concat_exprs = [ 647 self.expression(exp.Concat, expressions=node.expressions, safe=True) 648 ] 649 node.set("expressions", concat_exprs) 650 return node 651 if len(exprs) == 1: 652 return exprs[0] 653 return self.expression(exp.Concat, expressions=args, safe=True) 654 655 args = self._parse_csv(self._parse_lambda) 656 657 if args: 658 order = args[-1] if isinstance(args[-1], exp.Order) else None 659 660 if order: 661 # Order By is the last (or only) expression in the list and has consumed the 'expr' before it, 662 # remove 'expr' from exp.Order and add it back to args 663 args[-1] = order.this 664 order.set("this", concat_exprs(order.this, args)) 665 666 this = order or concat_exprs(args[0], args) 667 else: 668 this = None 669 670 separator = self._parse_field() if self._match(TokenType.SEPARATOR) else None 671 672 return self.expression(exp.GroupConcat, this=this, separator=separator) 673 674 def _parse_json_value(self) -> exp.JSONValue: 675 this = self._parse_bitwise() 676 self._match(TokenType.COMMA) 677 path = self._parse_bitwise() 678 679 returning = self._match(TokenType.RETURNING) and self._parse_type() 680 681 return self.expression( 682 exp.JSONValue, 683 this=this, 684 path=self.dialect.to_json_path(path), 685 returning=returning, 686 on_condition=self._parse_on_condition(), 687 ) 688 689 class Generator(generator.Generator): 690 INTERVAL_ALLOWS_PLURAL_FORM = False 691 LOCKING_READS_SUPPORTED = True 692 NULL_ORDERING_SUPPORTED = None 693 JOIN_HINTS = False 694 TABLE_HINTS = True 695 DUPLICATE_KEY_UPDATE_WITH_SET = False 696 QUERY_HINT_SEP = " " 697 VALUES_AS_TABLE = False 698 NVL2_SUPPORTED = False 699 LAST_DAY_SUPPORTS_DATE_PART = False 700 JSON_TYPE_REQUIRED_FOR_EXTRACTION = True 701 JSON_PATH_BRACKETED_KEY_SUPPORTED = False 702 JSON_KEY_VALUE_PAIR_SEP = "," 703 SUPPORTS_TO_NUMBER = False 704 PARSE_JSON_NAME: t.Optional[str] = None 705 PAD_FILL_PATTERN_IS_REQUIRED = True 706 WRAP_DERIVED_VALUES = False 707 VARCHAR_REQUIRES_SIZE = True 708 SUPPORTS_MEDIAN = False 709 710 TRANSFORMS = { 711 **generator.Generator.TRANSFORMS, 712 exp.ArrayAgg: rename_func("GROUP_CONCAT"), 713 exp.CurrentDate: no_paren_current_date_sql, 714 exp.DateDiff: _remove_ts_or_ds_to_date( 715 lambda self, e: self.func("DATEDIFF", e.this, e.expression), ("this", "expression") 716 ), 717 exp.DateAdd: _remove_ts_or_ds_to_date(date_add_sql("ADD")), 718 exp.DateStrToDate: datestrtodate_sql, 719 exp.DateSub: _remove_ts_or_ds_to_date(date_add_sql("SUB")), 720 exp.DateTrunc: _date_trunc_sql, 721 exp.Day: _remove_ts_or_ds_to_date(), 722 exp.DayOfMonth: _remove_ts_or_ds_to_date(rename_func("DAYOFMONTH")), 723 exp.DayOfWeek: _remove_ts_or_ds_to_date(rename_func("DAYOFWEEK")), 724 exp.DayOfYear: _remove_ts_or_ds_to_date(rename_func("DAYOFYEAR")), 725 exp.GroupConcat: lambda self, 726 e: f"""GROUP_CONCAT({self.sql(e, "this")} SEPARATOR {self.sql(e, "separator") or "','"})""", 727 exp.ILike: no_ilike_sql, 728 exp.JSONExtractScalar: arrow_json_extract_sql, 729 exp.Max: max_or_greatest, 730 exp.Min: min_or_least, 731 exp.Month: _remove_ts_or_ds_to_date(), 732 exp.NullSafeEQ: lambda self, e: self.binary(e, "<=>"), 733 exp.NullSafeNEQ: lambda self, e: f"NOT {self.binary(e, '<=>')}", 734 exp.Pivot: no_pivot_sql, 735 exp.Select: transforms.preprocess( 736 [ 737 transforms.eliminate_distinct_on, 738 transforms.eliminate_semi_and_anti_joins, 739 transforms.eliminate_qualify, 740 transforms.eliminate_full_outer_join, 741 transforms.unnest_generate_date_array_using_recursive_cte, 742 ] 743 ), 744 exp.StrPosition: strposition_to_locate_sql, 745 exp.StrToDate: _str_to_date_sql, 746 exp.StrToTime: _str_to_date_sql, 747 exp.Stuff: rename_func("INSERT"), 748 exp.TableSample: no_tablesample_sql, 749 exp.TimeFromParts: rename_func("MAKETIME"), 750 exp.TimestampAdd: date_add_interval_sql("DATE", "ADD"), 751 exp.TimestampDiff: lambda self, e: self.func( 752 "TIMESTAMPDIFF", unit_to_var(e), e.expression, e.this 753 ), 754 exp.TimestampSub: date_add_interval_sql("DATE", "SUB"), 755 exp.TimeStrToUnix: rename_func("UNIX_TIMESTAMP"), 756 exp.TimeStrToTime: lambda self, e: timestrtotime_sql( 757 self, 758 e, 759 include_precision=not e.args.get("zone"), 760 ), 761 exp.TimeToStr: _remove_ts_or_ds_to_date( 762 lambda self, e: self.func("DATE_FORMAT", e.this, self.format_time(e)) 763 ), 764 exp.Trim: trim_sql, 765 exp.TryCast: no_trycast_sql, 766 exp.TsOrDsAdd: date_add_sql("ADD"), 767 exp.TsOrDsDiff: lambda self, e: self.func("DATEDIFF", e.this, e.expression), 768 exp.TsOrDsToDate: _ts_or_ds_to_date_sql, 769 exp.UnixToTime: _unix_to_time_sql, 770 exp.Week: _remove_ts_or_ds_to_date(), 771 exp.WeekOfYear: _remove_ts_or_ds_to_date(rename_func("WEEKOFYEAR")), 772 exp.Year: _remove_ts_or_ds_to_date(), 773 } 774 775 UNSIGNED_TYPE_MAPPING = { 776 exp.DataType.Type.UBIGINT: "BIGINT", 777 exp.DataType.Type.UINT: "INT", 778 exp.DataType.Type.UMEDIUMINT: "MEDIUMINT", 779 exp.DataType.Type.USMALLINT: "SMALLINT", 780 exp.DataType.Type.UTINYINT: "TINYINT", 781 exp.DataType.Type.UDECIMAL: "DECIMAL", 782 } 783 784 TIMESTAMP_TYPE_MAPPING = { 785 exp.DataType.Type.TIMESTAMP: "DATETIME", 786 exp.DataType.Type.TIMESTAMPTZ: "TIMESTAMP", 787 exp.DataType.Type.TIMESTAMPLTZ: "TIMESTAMP", 788 } 789 790 TYPE_MAPPING = { 791 **generator.Generator.TYPE_MAPPING, 792 **UNSIGNED_TYPE_MAPPING, 793 **TIMESTAMP_TYPE_MAPPING, 794 } 795 796 TYPE_MAPPING.pop(exp.DataType.Type.MEDIUMTEXT) 797 TYPE_MAPPING.pop(exp.DataType.Type.LONGTEXT) 798 TYPE_MAPPING.pop(exp.DataType.Type.TINYTEXT) 799 TYPE_MAPPING.pop(exp.DataType.Type.MEDIUMBLOB) 800 TYPE_MAPPING.pop(exp.DataType.Type.LONGBLOB) 801 TYPE_MAPPING.pop(exp.DataType.Type.TINYBLOB) 802 803 PROPERTIES_LOCATION = { 804 **generator.Generator.PROPERTIES_LOCATION, 805 exp.TransientProperty: exp.Properties.Location.UNSUPPORTED, 806 exp.VolatileProperty: exp.Properties.Location.UNSUPPORTED, 807 } 808 809 LIMIT_FETCH = "LIMIT" 810 811 LIMIT_ONLY_LITERALS = True 812 813 CHAR_CAST_MAPPING = dict.fromkeys( 814 ( 815 exp.DataType.Type.LONGTEXT, 816 exp.DataType.Type.LONGBLOB, 817 exp.DataType.Type.MEDIUMBLOB, 818 exp.DataType.Type.MEDIUMTEXT, 819 exp.DataType.Type.TEXT, 820 exp.DataType.Type.TINYBLOB, 821 exp.DataType.Type.TINYTEXT, 822 exp.DataType.Type.VARCHAR, 823 ), 824 "CHAR", 825 ) 826 SIGNED_CAST_MAPPING = dict.fromkeys( 827 ( 828 exp.DataType.Type.BIGINT, 829 exp.DataType.Type.BOOLEAN, 830 exp.DataType.Type.INT, 831 exp.DataType.Type.SMALLINT, 832 exp.DataType.Type.TINYINT, 833 exp.DataType.Type.MEDIUMINT, 834 ), 835 "SIGNED", 836 ) 837 838 # MySQL doesn't support many datatypes in cast. 839 # https://dev.mysql.com/doc/refman/8.0/en/cast-functions.html#function_cast 840 CAST_MAPPING = { 841 **CHAR_CAST_MAPPING, 842 **SIGNED_CAST_MAPPING, 843 exp.DataType.Type.UBIGINT: "UNSIGNED", 844 } 845 846 TIMESTAMP_FUNC_TYPES = { 847 exp.DataType.Type.TIMESTAMPTZ, 848 exp.DataType.Type.TIMESTAMPLTZ, 849 } 850 851 # https://dev.mysql.com/doc/refman/8.0/en/keywords.html 852 RESERVED_KEYWORDS = { 853 "accessible", 854 "add", 855 "all", 856 "alter", 857 "analyze", 858 "and", 859 "as", 860 "asc", 861 "asensitive", 862 "before", 863 "between", 864 "bigint", 865 "binary", 866 "blob", 867 "both", 868 "by", 869 "call", 870 "cascade", 871 "case", 872 "change", 873 "char", 874 "character", 875 "check", 876 "collate", 877 "column", 878 "condition", 879 "constraint", 880 "continue", 881 "convert", 882 "create", 883 "cross", 884 "cube", 885 "cume_dist", 886 "current_date", 887 "current_time", 888 "current_timestamp", 889 "current_user", 890 "cursor", 891 "database", 892 "databases", 893 "day_hour", 894 "day_microsecond", 895 "day_minute", 896 "day_second", 897 "dec", 898 "decimal", 899 "declare", 900 "default", 901 "delayed", 902 "delete", 903 "dense_rank", 904 "desc", 905 "describe", 906 "deterministic", 907 "distinct", 908 "distinctrow", 909 "div", 910 "double", 911 "drop", 912 "dual", 913 "each", 914 "else", 915 "elseif", 916 "empty", 917 "enclosed", 918 "escaped", 919 "except", 920 "exists", 921 "exit", 922 "explain", 923 "false", 924 "fetch", 925 "first_value", 926 "float", 927 "float4", 928 "float8", 929 "for", 930 "force", 931 "foreign", 932 "from", 933 "fulltext", 934 "function", 935 "generated", 936 "get", 937 "grant", 938 "group", 939 "grouping", 940 "groups", 941 "having", 942 "high_priority", 943 "hour_microsecond", 944 "hour_minute", 945 "hour_second", 946 "if", 947 "ignore", 948 "in", 949 "index", 950 "infile", 951 "inner", 952 "inout", 953 "insensitive", 954 "insert", 955 "int", 956 "int1", 957 "int2", 958 "int3", 959 "int4", 960 "int8", 961 "integer", 962 "intersect", 963 "interval", 964 "into", 965 "io_after_gtids", 966 "io_before_gtids", 967 "is", 968 "iterate", 969 "join", 970 "json_table", 971 "key", 972 "keys", 973 "kill", 974 "lag", 975 "last_value", 976 "lateral", 977 "lead", 978 "leading", 979 "leave", 980 "left", 981 "like", 982 "limit", 983 "linear", 984 "lines", 985 "load", 986 "localtime", 987 "localtimestamp", 988 "lock", 989 "long", 990 "longblob", 991 "longtext", 992 "loop", 993 "low_priority", 994 "master_bind", 995 "master_ssl_verify_server_cert", 996 "match", 997 "maxvalue", 998 "mediumblob", 999 "mediumint", 1000 "mediumtext", 1001 "middleint", 1002 "minute_microsecond", 1003 "minute_second", 1004 "mod", 1005 "modifies", 1006 "natural", 1007 "not", 1008 "no_write_to_binlog", 1009 "nth_value", 1010 "ntile", 1011 "null", 1012 "numeric", 1013 "of", 1014 "on", 1015 "optimize", 1016 "optimizer_costs", 1017 "option", 1018 "optionally", 1019 "or", 1020 "order", 1021 "out", 1022 "outer", 1023 "outfile", 1024 "over", 1025 "partition", 1026 "percent_rank", 1027 "precision", 1028 "primary", 1029 "procedure", 1030 "purge", 1031 "range", 1032 "rank", 1033 "read", 1034 "reads", 1035 "read_write", 1036 "real", 1037 "recursive", 1038 "references", 1039 "regexp", 1040 "release", 1041 "rename", 1042 "repeat", 1043 "replace", 1044 "require", 1045 "resignal", 1046 "restrict", 1047 "return", 1048 "revoke", 1049 "right", 1050 "rlike", 1051 "row", 1052 "rows", 1053 "row_number", 1054 "schema", 1055 "schemas", 1056 "second_microsecond", 1057 "select", 1058 "sensitive", 1059 "separator", 1060 "set", 1061 "show", 1062 "signal", 1063 "smallint", 1064 "spatial", 1065 "specific", 1066 "sql", 1067 "sqlexception", 1068 "sqlstate", 1069 "sqlwarning", 1070 "sql_big_result", 1071 "sql_calc_found_rows", 1072 "sql_small_result", 1073 "ssl", 1074 "starting", 1075 "stored", 1076 "straight_join", 1077 "system", 1078 "table", 1079 "terminated", 1080 "then", 1081 "tinyblob", 1082 "tinyint", 1083 "tinytext", 1084 "to", 1085 "trailing", 1086 "trigger", 1087 "true", 1088 "undo", 1089 "union", 1090 "unique", 1091 "unlock", 1092 "unsigned", 1093 "update", 1094 "usage", 1095 "use", 1096 "using", 1097 "utc_date", 1098 "utc_time", 1099 "utc_timestamp", 1100 "values", 1101 "varbinary", 1102 "varchar", 1103 "varcharacter", 1104 "varying", 1105 "virtual", 1106 "when", 1107 "where", 1108 "while", 1109 "window", 1110 "with", 1111 "write", 1112 "xor", 1113 "year_month", 1114 "zerofill", 1115 } 1116 1117 def array_sql(self, expression: exp.Array) -> str: 1118 self.unsupported("Arrays are not supported by MySQL") 1119 return self.function_fallback_sql(expression) 1120 1121 def arraycontainsall_sql(self, expression: exp.ArrayContainsAll) -> str: 1122 self.unsupported("Array operations are not supported by MySQL") 1123 return self.function_fallback_sql(expression) 1124 1125 def dpipe_sql(self, expression: exp.DPipe) -> str: 1126 return self.func("CONCAT", *expression.flatten()) 1127 1128 def extract_sql(self, expression: exp.Extract) -> str: 1129 unit = expression.name 1130 if unit and unit.lower() == "epoch": 1131 return self.func("UNIX_TIMESTAMP", expression.expression) 1132 1133 return super().extract_sql(expression) 1134 1135 def datatype_sql(self, expression: exp.DataType) -> str: 1136 if ( 1137 self.VARCHAR_REQUIRES_SIZE 1138 and expression.is_type(exp.DataType.Type.VARCHAR) 1139 and not expression.expressions 1140 ): 1141 # `VARCHAR` must always have a size - if it doesn't, we always generate `TEXT` 1142 return "TEXT" 1143 1144 # https://dev.mysql.com/doc/refman/8.0/en/numeric-type-syntax.html 1145 result = super().datatype_sql(expression) 1146 if expression.this in self.UNSIGNED_TYPE_MAPPING: 1147 result = f"{result} UNSIGNED" 1148 1149 return result 1150 1151 def jsonarraycontains_sql(self, expression: exp.JSONArrayContains) -> str: 1152 return f"{self.sql(expression, 'this')} MEMBER OF({self.sql(expression, 'expression')})" 1153 1154 def cast_sql(self, expression: exp.Cast, safe_prefix: t.Optional[str] = None) -> str: 1155 if expression.to.this in self.TIMESTAMP_FUNC_TYPES: 1156 return self.func("TIMESTAMP", expression.this) 1157 1158 to = self.CAST_MAPPING.get(expression.to.this) 1159 1160 if to: 1161 expression.to.set("this", to) 1162 return super().cast_sql(expression) 1163 1164 def show_sql(self, expression: exp.Show) -> str: 1165 this = f" {expression.name}" 1166 full = " FULL" if expression.args.get("full") else "" 1167 global_ = " GLOBAL" if expression.args.get("global") else "" 1168 1169 target = self.sql(expression, "target") 1170 target = f" {target}" if target else "" 1171 if expression.name in ("COLUMNS", "INDEX"): 1172 target = f" FROM{target}" 1173 elif expression.name == "GRANTS": 1174 target = f" FOR{target}" 1175 1176 db = self._prefixed_sql("FROM", expression, "db") 1177 1178 like = self._prefixed_sql("LIKE", expression, "like") 1179 where = self.sql(expression, "where") 1180 1181 types = self.expressions(expression, key="types") 1182 types = f" {types}" if types else types 1183 query = self._prefixed_sql("FOR QUERY", expression, "query") 1184 1185 if expression.name == "PROFILE": 1186 offset = self._prefixed_sql("OFFSET", expression, "offset") 1187 limit = self._prefixed_sql("LIMIT", expression, "limit") 1188 else: 1189 offset = "" 1190 limit = self._oldstyle_limit_sql(expression) 1191 1192 log = self._prefixed_sql("IN", expression, "log") 1193 position = self._prefixed_sql("FROM", expression, "position") 1194 1195 channel = self._prefixed_sql("FOR CHANNEL", expression, "channel") 1196 1197 if expression.name == "ENGINE": 1198 mutex_or_status = " MUTEX" if expression.args.get("mutex") else " STATUS" 1199 else: 1200 mutex_or_status = "" 1201 1202 return f"SHOW{full}{global_}{this}{target}{types}{db}{query}{log}{position}{channel}{mutex_or_status}{like}{where}{offset}{limit}" 1203 1204 def altercolumn_sql(self, expression: exp.AlterColumn) -> str: 1205 dtype = self.sql(expression, "dtype") 1206 if not dtype: 1207 return super().altercolumn_sql(expression) 1208 1209 this = self.sql(expression, "this") 1210 return f"MODIFY COLUMN {this} {dtype}" 1211 1212 def _prefixed_sql(self, prefix: str, expression: exp.Expression, arg: str) -> str: 1213 sql = self.sql(expression, arg) 1214 return f" {prefix} {sql}" if sql else "" 1215 1216 def _oldstyle_limit_sql(self, expression: exp.Show) -> str: 1217 limit = self.sql(expression, "limit") 1218 offset = self.sql(expression, "offset") 1219 if limit: 1220 limit_offset = f"{offset}, {limit}" if offset else limit 1221 return f" LIMIT {limit_offset}" 1222 return "" 1223 1224 def chr_sql(self, expression: exp.Chr) -> str: 1225 this = self.expressions(sqls=[expression.this] + expression.expressions) 1226 charset = expression.args.get("charset") 1227 using = f" USING {self.sql(charset)}" if charset else "" 1228 return f"CHAR({this}{using})" 1229 1230 def timestamptrunc_sql(self, expression: exp.TimestampTrunc) -> str: 1231 unit = expression.args.get("unit") 1232 1233 # Pick an old-enough date to avoid negative timestamp diffs 1234 start_ts = "'0000-01-01 00:00:00'" 1235 1236 # Source: https://stackoverflow.com/a/32955740 1237 timestamp_diff = build_date_delta(exp.TimestampDiff)([unit, start_ts, expression.this]) 1238 interval = exp.Interval(this=timestamp_diff, unit=unit) 1239 dateadd = build_date_delta_with_interval(exp.DateAdd)([start_ts, interval]) 1240 1241 return self.sql(dateadd) 1242 1243 def converttimezone_sql(self, expression: exp.ConvertTimezone) -> str: 1244 from_tz = expression.args.get("source_tz") 1245 to_tz = expression.args.get("target_tz") 1246 dt = expression.args.get("timestamp") 1247 1248 return self.func("CONVERT_TZ", dt, from_tz, to_tz) 1249 1250 def attimezone_sql(self, expression: exp.AtTimeZone) -> str: 1251 self.unsupported("AT TIME ZONE is not supported by MySQL") 1252 return self.sql(expression.this)
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
- 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
- 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
180 class Tokenizer(tokens.Tokenizer): 181 QUOTES = ["'", '"'] 182 COMMENTS = ["--", "#", ("/*", "*/")] 183 IDENTIFIERS = ["`"] 184 STRING_ESCAPES = ["'", '"', "\\"] 185 BIT_STRINGS = [("b'", "'"), ("B'", "'"), ("0b", "")] 186 HEX_STRINGS = [("x'", "'"), ("X'", "'"), ("0x", "")] 187 188 KEYWORDS = { 189 **tokens.Tokenizer.KEYWORDS, 190 "CHARSET": TokenType.CHARACTER_SET, 191 # The DESCRIBE and EXPLAIN statements are synonyms. 192 # https://dev.mysql.com/doc/refman/8.4/en/explain.html 193 "EXPLAIN": TokenType.DESCRIBE, 194 "FORCE": TokenType.FORCE, 195 "IGNORE": TokenType.IGNORE, 196 "KEY": TokenType.KEY, 197 "LOCK TABLES": TokenType.COMMAND, 198 "LONGBLOB": TokenType.LONGBLOB, 199 "LONGTEXT": TokenType.LONGTEXT, 200 "MEDIUMBLOB": TokenType.MEDIUMBLOB, 201 "TINYBLOB": TokenType.TINYBLOB, 202 "TINYTEXT": TokenType.TINYTEXT, 203 "MEDIUMTEXT": TokenType.MEDIUMTEXT, 204 "MEDIUMINT": TokenType.MEDIUMINT, 205 "MEMBER OF": TokenType.MEMBER_OF, 206 "SEPARATOR": TokenType.SEPARATOR, 207 "START": TokenType.BEGIN, 208 "SIGNED": TokenType.BIGINT, 209 "SIGNED INTEGER": TokenType.BIGINT, 210 "UNLOCK TABLES": TokenType.COMMAND, 211 "UNSIGNED": TokenType.UBIGINT, 212 "UNSIGNED INTEGER": TokenType.UBIGINT, 213 "YEAR": TokenType.YEAR, 214 "_ARMSCII8": TokenType.INTRODUCER, 215 "_ASCII": TokenType.INTRODUCER, 216 "_BIG5": TokenType.INTRODUCER, 217 "_BINARY": TokenType.INTRODUCER, 218 "_CP1250": TokenType.INTRODUCER, 219 "_CP1251": TokenType.INTRODUCER, 220 "_CP1256": TokenType.INTRODUCER, 221 "_CP1257": TokenType.INTRODUCER, 222 "_CP850": TokenType.INTRODUCER, 223 "_CP852": TokenType.INTRODUCER, 224 "_CP866": TokenType.INTRODUCER, 225 "_CP932": TokenType.INTRODUCER, 226 "_DEC8": TokenType.INTRODUCER, 227 "_EUCJPMS": TokenType.INTRODUCER, 228 "_EUCKR": TokenType.INTRODUCER, 229 "_GB18030": TokenType.INTRODUCER, 230 "_GB2312": TokenType.INTRODUCER, 231 "_GBK": TokenType.INTRODUCER, 232 "_GEOSTD8": TokenType.INTRODUCER, 233 "_GREEK": TokenType.INTRODUCER, 234 "_HEBREW": TokenType.INTRODUCER, 235 "_HP8": TokenType.INTRODUCER, 236 "_KEYBCS2": TokenType.INTRODUCER, 237 "_KOI8R": TokenType.INTRODUCER, 238 "_KOI8U": TokenType.INTRODUCER, 239 "_LATIN1": TokenType.INTRODUCER, 240 "_LATIN2": TokenType.INTRODUCER, 241 "_LATIN5": TokenType.INTRODUCER, 242 "_LATIN7": TokenType.INTRODUCER, 243 "_MACCE": TokenType.INTRODUCER, 244 "_MACROMAN": TokenType.INTRODUCER, 245 "_SJIS": TokenType.INTRODUCER, 246 "_SWE7": TokenType.INTRODUCER, 247 "_TIS620": TokenType.INTRODUCER, 248 "_UCS2": TokenType.INTRODUCER, 249 "_UJIS": TokenType.INTRODUCER, 250 # https://dev.mysql.com/doc/refman/8.0/en/string-literals.html 251 "_UTF8": TokenType.INTRODUCER, 252 "_UTF16": TokenType.INTRODUCER, 253 "_UTF16LE": TokenType.INTRODUCER, 254 "_UTF32": TokenType.INTRODUCER, 255 "_UTF8MB3": TokenType.INTRODUCER, 256 "_UTF8MB4": TokenType.INTRODUCER, 257 "@@": TokenType.SESSION_PARAMETER, 258 } 259 260 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.REPLACE: 'REPLACE'>, <TokenType.COMMAND: 'COMMAND'>, <TokenType.RENAME: 'RENAME'>}
Inherited Members
- sqlglot.tokens.Tokenizer
- Tokenizer
- SINGLE_TOKENS
- BYTE_STRINGS
- RAW_STRINGS
- HEREDOC_STRINGS
- UNICODE_STRINGS
- VAR_SINGLE_TOKENS
- IDENTIFIER_ESCAPES
- HEREDOC_TAG_IS_IDENTIFIER
- HEREDOC_STRING_ALTERNATIVE
- STRING_ESCAPES_ALLOWED_IN_RAW_STRINGS
- NESTED_COMMENTS
- WHITE_SPACE
- COMMAND_PREFIX_TOKENS
- NUMERIC_LITERALS
- dialect
- reset
- tokenize
- tokenize_rs
- size
- sql
- tokens
262 class Parser(parser.Parser): 263 FUNC_TOKENS = { 264 *parser.Parser.FUNC_TOKENS, 265 TokenType.DATABASE, 266 TokenType.SCHEMA, 267 TokenType.VALUES, 268 } 269 270 CONJUNCTION = { 271 **parser.Parser.CONJUNCTION, 272 TokenType.DAMP: exp.And, 273 TokenType.XOR: exp.Xor, 274 } 275 276 DISJUNCTION = { 277 **parser.Parser.DISJUNCTION, 278 TokenType.DPIPE: exp.Or, 279 } 280 281 TABLE_ALIAS_TOKENS = ( 282 parser.Parser.TABLE_ALIAS_TOKENS - parser.Parser.TABLE_INDEX_HINT_TOKENS 283 ) 284 285 RANGE_PARSERS = { 286 **parser.Parser.RANGE_PARSERS, 287 TokenType.MEMBER_OF: lambda self, this: self.expression( 288 exp.JSONArrayContains, 289 this=this, 290 expression=self._parse_wrapped(self._parse_expression), 291 ), 292 } 293 294 FUNCTIONS = { 295 **parser.Parser.FUNCTIONS, 296 "CONVERT_TZ": lambda args: exp.ConvertTimezone( 297 source_tz=seq_get(args, 1), target_tz=seq_get(args, 2), timestamp=seq_get(args, 0) 298 ), 299 "DATE": lambda args: exp.TsOrDsToDate(this=seq_get(args, 0)), 300 "DATE_ADD": build_date_delta_with_interval(exp.DateAdd), 301 "DATE_FORMAT": build_formatted_time(exp.TimeToStr, "mysql"), 302 "DATE_SUB": build_date_delta_with_interval(exp.DateSub), 303 "DAY": lambda args: exp.Day(this=exp.TsOrDsToDate(this=seq_get(args, 0))), 304 "DAYOFMONTH": lambda args: exp.DayOfMonth(this=exp.TsOrDsToDate(this=seq_get(args, 0))), 305 "DAYOFWEEK": lambda args: exp.DayOfWeek(this=exp.TsOrDsToDate(this=seq_get(args, 0))), 306 "DAYOFYEAR": lambda args: exp.DayOfYear(this=exp.TsOrDsToDate(this=seq_get(args, 0))), 307 "FROM_UNIXTIME": build_formatted_time(exp.UnixToTime, "mysql"), 308 "ISNULL": isnull_to_is_null, 309 "LOCATE": locate_to_strposition, 310 "MAKETIME": exp.TimeFromParts.from_arg_list, 311 "MONTH": lambda args: exp.Month(this=exp.TsOrDsToDate(this=seq_get(args, 0))), 312 "MONTHNAME": lambda args: exp.TimeToStr( 313 this=exp.TsOrDsToDate(this=seq_get(args, 0)), 314 format=exp.Literal.string("%B"), 315 ), 316 "STR_TO_DATE": _str_to_date, 317 "TIMESTAMPDIFF": build_date_delta(exp.TimestampDiff), 318 "TO_DAYS": lambda args: exp.paren( 319 exp.DateDiff( 320 this=exp.TsOrDsToDate(this=seq_get(args, 0)), 321 expression=exp.TsOrDsToDate(this=exp.Literal.string("0000-01-01")), 322 unit=exp.var("DAY"), 323 ) 324 + 1 325 ), 326 "WEEK": lambda args: exp.Week( 327 this=exp.TsOrDsToDate(this=seq_get(args, 0)), mode=seq_get(args, 1) 328 ), 329 "WEEKOFYEAR": lambda args: exp.WeekOfYear(this=exp.TsOrDsToDate(this=seq_get(args, 0))), 330 "YEAR": lambda args: exp.Year(this=exp.TsOrDsToDate(this=seq_get(args, 0))), 331 } 332 333 FUNCTION_PARSERS = { 334 **parser.Parser.FUNCTION_PARSERS, 335 "CHAR": lambda self: self.expression( 336 exp.Chr, 337 expressions=self._parse_csv(self._parse_assignment), 338 charset=self._match(TokenType.USING) and self._parse_var(), 339 ), 340 "GROUP_CONCAT": lambda self: self._parse_group_concat(), 341 # https://dev.mysql.com/doc/refman/5.7/en/miscellaneous-functions.html#function_values 342 "VALUES": lambda self: self.expression( 343 exp.Anonymous, this="VALUES", expressions=[self._parse_id_var()] 344 ), 345 "JSON_VALUE": lambda self: self._parse_json_value(), 346 } 347 348 STATEMENT_PARSERS = { 349 **parser.Parser.STATEMENT_PARSERS, 350 TokenType.SHOW: lambda self: self._parse_show(), 351 } 352 353 SHOW_PARSERS = { 354 "BINARY LOGS": _show_parser("BINARY LOGS"), 355 "MASTER LOGS": _show_parser("BINARY LOGS"), 356 "BINLOG EVENTS": _show_parser("BINLOG EVENTS"), 357 "CHARACTER SET": _show_parser("CHARACTER SET"), 358 "CHARSET": _show_parser("CHARACTER SET"), 359 "COLLATION": _show_parser("COLLATION"), 360 "FULL COLUMNS": _show_parser("COLUMNS", target="FROM", full=True), 361 "COLUMNS": _show_parser("COLUMNS", target="FROM"), 362 "CREATE DATABASE": _show_parser("CREATE DATABASE", target=True), 363 "CREATE EVENT": _show_parser("CREATE EVENT", target=True), 364 "CREATE FUNCTION": _show_parser("CREATE FUNCTION", target=True), 365 "CREATE PROCEDURE": _show_parser("CREATE PROCEDURE", target=True), 366 "CREATE TABLE": _show_parser("CREATE TABLE", target=True), 367 "CREATE TRIGGER": _show_parser("CREATE TRIGGER", target=True), 368 "CREATE VIEW": _show_parser("CREATE VIEW", target=True), 369 "DATABASES": _show_parser("DATABASES"), 370 "SCHEMAS": _show_parser("DATABASES"), 371 "ENGINE": _show_parser("ENGINE", target=True), 372 "STORAGE ENGINES": _show_parser("ENGINES"), 373 "ENGINES": _show_parser("ENGINES"), 374 "ERRORS": _show_parser("ERRORS"), 375 "EVENTS": _show_parser("EVENTS"), 376 "FUNCTION CODE": _show_parser("FUNCTION CODE", target=True), 377 "FUNCTION STATUS": _show_parser("FUNCTION STATUS"), 378 "GRANTS": _show_parser("GRANTS", target="FOR"), 379 "INDEX": _show_parser("INDEX", target="FROM"), 380 "MASTER STATUS": _show_parser("MASTER STATUS"), 381 "OPEN TABLES": _show_parser("OPEN TABLES"), 382 "PLUGINS": _show_parser("PLUGINS"), 383 "PROCEDURE CODE": _show_parser("PROCEDURE CODE", target=True), 384 "PROCEDURE STATUS": _show_parser("PROCEDURE STATUS"), 385 "PRIVILEGES": _show_parser("PRIVILEGES"), 386 "FULL PROCESSLIST": _show_parser("PROCESSLIST", full=True), 387 "PROCESSLIST": _show_parser("PROCESSLIST"), 388 "PROFILE": _show_parser("PROFILE"), 389 "PROFILES": _show_parser("PROFILES"), 390 "RELAYLOG EVENTS": _show_parser("RELAYLOG EVENTS"), 391 "REPLICAS": _show_parser("REPLICAS"), 392 "SLAVE HOSTS": _show_parser("REPLICAS"), 393 "REPLICA STATUS": _show_parser("REPLICA STATUS"), 394 "SLAVE STATUS": _show_parser("REPLICA STATUS"), 395 "GLOBAL STATUS": _show_parser("STATUS", global_=True), 396 "SESSION STATUS": _show_parser("STATUS"), 397 "STATUS": _show_parser("STATUS"), 398 "TABLE STATUS": _show_parser("TABLE STATUS"), 399 "FULL TABLES": _show_parser("TABLES", full=True), 400 "TABLES": _show_parser("TABLES"), 401 "TRIGGERS": _show_parser("TRIGGERS"), 402 "GLOBAL VARIABLES": _show_parser("VARIABLES", global_=True), 403 "SESSION VARIABLES": _show_parser("VARIABLES"), 404 "VARIABLES": _show_parser("VARIABLES"), 405 "WARNINGS": _show_parser("WARNINGS"), 406 } 407 408 PROPERTY_PARSERS = { 409 **parser.Parser.PROPERTY_PARSERS, 410 "LOCK": lambda self: self._parse_property_assignment(exp.LockProperty), 411 } 412 413 SET_PARSERS = { 414 **parser.Parser.SET_PARSERS, 415 "PERSIST": lambda self: self._parse_set_item_assignment("PERSIST"), 416 "PERSIST_ONLY": lambda self: self._parse_set_item_assignment("PERSIST_ONLY"), 417 "CHARACTER SET": lambda self: self._parse_set_item_charset("CHARACTER SET"), 418 "CHARSET": lambda self: self._parse_set_item_charset("CHARACTER SET"), 419 "NAMES": lambda self: self._parse_set_item_names(), 420 } 421 422 CONSTRAINT_PARSERS = { 423 **parser.Parser.CONSTRAINT_PARSERS, 424 "FULLTEXT": lambda self: self._parse_index_constraint(kind="FULLTEXT"), 425 "INDEX": lambda self: self._parse_index_constraint(), 426 "KEY": lambda self: self._parse_index_constraint(), 427 "SPATIAL": lambda self: self._parse_index_constraint(kind="SPATIAL"), 428 } 429 430 ALTER_PARSERS = { 431 **parser.Parser.ALTER_PARSERS, 432 "MODIFY": lambda self: self._parse_alter_table_alter(), 433 } 434 435 SCHEMA_UNNAMED_CONSTRAINTS = { 436 *parser.Parser.SCHEMA_UNNAMED_CONSTRAINTS, 437 "FULLTEXT", 438 "INDEX", 439 "KEY", 440 "SPATIAL", 441 } 442 443 PROFILE_TYPES: parser.OPTIONS_TYPE = { 444 **dict.fromkeys(("ALL", "CPU", "IPC", "MEMORY", "SOURCE", "SWAPS"), tuple()), 445 "BLOCK": ("IO",), 446 "CONTEXT": ("SWITCHES",), 447 "PAGE": ("FAULTS",), 448 } 449 450 TYPE_TOKENS = { 451 *parser.Parser.TYPE_TOKENS, 452 TokenType.SET, 453 } 454 455 ENUM_TYPE_TOKENS = { 456 *parser.Parser.ENUM_TYPE_TOKENS, 457 TokenType.SET, 458 } 459 460 # SELECT [ ALL | DISTINCT | DISTINCTROW ] [ <OPERATION_MODIFIERS> ] 461 OPERATION_MODIFIERS = { 462 "HIGH_PRIORITY", 463 "STRAIGHT_JOIN", 464 "SQL_SMALL_RESULT", 465 "SQL_BIG_RESULT", 466 "SQL_BUFFER_RESULT", 467 "SQL_NO_CACHE", 468 "SQL_CALC_FOUND_ROWS", 469 } 470 471 LOG_DEFAULTS_TO_LN = True 472 STRING_ALIASES = True 473 VALUES_FOLLOWED_BY_PAREN = False 474 SUPPORTS_PARTITION_SELECTION = True 475 476 def _parse_primary_key_part(self) -> t.Optional[exp.Expression]: 477 this = self._parse_id_var() 478 if not self._match(TokenType.L_PAREN): 479 return this 480 481 expression = self._parse_number() 482 self._match_r_paren() 483 return self.expression(exp.ColumnPrefix, this=this, expression=expression) 484 485 def _parse_index_constraint( 486 self, kind: t.Optional[str] = None 487 ) -> exp.IndexColumnConstraint: 488 if kind: 489 self._match_texts(("INDEX", "KEY")) 490 491 this = self._parse_id_var(any_token=False) 492 index_type = self._match(TokenType.USING) and self._advance_any() and self._prev.text 493 expressions = self._parse_wrapped_csv(self._parse_ordered) 494 495 options = [] 496 while True: 497 if self._match_text_seq("KEY_BLOCK_SIZE"): 498 self._match(TokenType.EQ) 499 opt = exp.IndexConstraintOption(key_block_size=self._parse_number()) 500 elif self._match(TokenType.USING): 501 opt = exp.IndexConstraintOption(using=self._advance_any() and self._prev.text) 502 elif self._match_text_seq("WITH", "PARSER"): 503 opt = exp.IndexConstraintOption(parser=self._parse_var(any_token=True)) 504 elif self._match(TokenType.COMMENT): 505 opt = exp.IndexConstraintOption(comment=self._parse_string()) 506 elif self._match_text_seq("VISIBLE"): 507 opt = exp.IndexConstraintOption(visible=True) 508 elif self._match_text_seq("INVISIBLE"): 509 opt = exp.IndexConstraintOption(visible=False) 510 elif self._match_text_seq("ENGINE_ATTRIBUTE"): 511 self._match(TokenType.EQ) 512 opt = exp.IndexConstraintOption(engine_attr=self._parse_string()) 513 elif self._match_text_seq("SECONDARY_ENGINE_ATTRIBUTE"): 514 self._match(TokenType.EQ) 515 opt = exp.IndexConstraintOption(secondary_engine_attr=self._parse_string()) 516 else: 517 opt = None 518 519 if not opt: 520 break 521 522 options.append(opt) 523 524 return self.expression( 525 exp.IndexColumnConstraint, 526 this=this, 527 expressions=expressions, 528 kind=kind, 529 index_type=index_type, 530 options=options, 531 ) 532 533 def _parse_show_mysql( 534 self, 535 this: str, 536 target: bool | str = False, 537 full: t.Optional[bool] = None, 538 global_: t.Optional[bool] = None, 539 ) -> exp.Show: 540 if target: 541 if isinstance(target, str): 542 self._match_text_seq(target) 543 target_id = self._parse_id_var() 544 else: 545 target_id = None 546 547 log = self._parse_string() if self._match_text_seq("IN") else None 548 549 if this in ("BINLOG EVENTS", "RELAYLOG EVENTS"): 550 position = self._parse_number() if self._match_text_seq("FROM") else None 551 db = None 552 else: 553 position = None 554 db = None 555 556 if self._match(TokenType.FROM): 557 db = self._parse_id_var() 558 elif self._match(TokenType.DOT): 559 db = target_id 560 target_id = self._parse_id_var() 561 562 channel = self._parse_id_var() if self._match_text_seq("FOR", "CHANNEL") else None 563 564 like = self._parse_string() if self._match_text_seq("LIKE") else None 565 where = self._parse_where() 566 567 if this == "PROFILE": 568 types = self._parse_csv(lambda: self._parse_var_from_options(self.PROFILE_TYPES)) 569 query = self._parse_number() if self._match_text_seq("FOR", "QUERY") else None 570 offset = self._parse_number() if self._match_text_seq("OFFSET") else None 571 limit = self._parse_number() if self._match_text_seq("LIMIT") else None 572 else: 573 types, query = None, None 574 offset, limit = self._parse_oldstyle_limit() 575 576 mutex = True if self._match_text_seq("MUTEX") else None 577 mutex = False if self._match_text_seq("STATUS") else mutex 578 579 return self.expression( 580 exp.Show, 581 this=this, 582 target=target_id, 583 full=full, 584 log=log, 585 position=position, 586 db=db, 587 channel=channel, 588 like=like, 589 where=where, 590 types=types, 591 query=query, 592 offset=offset, 593 limit=limit, 594 mutex=mutex, 595 **{"global": global_}, # type: ignore 596 ) 597 598 def _parse_oldstyle_limit( 599 self, 600 ) -> t.Tuple[t.Optional[exp.Expression], t.Optional[exp.Expression]]: 601 limit = None 602 offset = None 603 if self._match_text_seq("LIMIT"): 604 parts = self._parse_csv(self._parse_number) 605 if len(parts) == 1: 606 limit = parts[0] 607 elif len(parts) == 2: 608 limit = parts[1] 609 offset = parts[0] 610 611 return offset, limit 612 613 def _parse_set_item_charset(self, kind: str) -> exp.Expression: 614 this = self._parse_string() or self._parse_unquoted_field() 615 return self.expression(exp.SetItem, this=this, kind=kind) 616 617 def _parse_set_item_names(self) -> exp.Expression: 618 charset = self._parse_string() or self._parse_unquoted_field() 619 if self._match_text_seq("COLLATE"): 620 collate = self._parse_string() or self._parse_unquoted_field() 621 else: 622 collate = None 623 624 return self.expression(exp.SetItem, this=charset, collate=collate, kind="NAMES") 625 626 def _parse_type( 627 self, parse_interval: bool = True, fallback_to_identifier: bool = False 628 ) -> t.Optional[exp.Expression]: 629 # mysql binary is special and can work anywhere, even in order by operations 630 # it operates like a no paren func 631 if self._match(TokenType.BINARY, advance=False): 632 data_type = self._parse_types(check_func=True, allow_identifiers=False) 633 634 if isinstance(data_type, exp.DataType): 635 return self.expression(exp.Cast, this=self._parse_column(), to=data_type) 636 637 return super()._parse_type( 638 parse_interval=parse_interval, fallback_to_identifier=fallback_to_identifier 639 ) 640 641 def _parse_group_concat(self) -> t.Optional[exp.Expression]: 642 def concat_exprs( 643 node: t.Optional[exp.Expression], exprs: t.List[exp.Expression] 644 ) -> exp.Expression: 645 if isinstance(node, exp.Distinct) and len(node.expressions) > 1: 646 concat_exprs = [ 647 self.expression(exp.Concat, expressions=node.expressions, safe=True) 648 ] 649 node.set("expressions", concat_exprs) 650 return node 651 if len(exprs) == 1: 652 return exprs[0] 653 return self.expression(exp.Concat, expressions=args, safe=True) 654 655 args = self._parse_csv(self._parse_lambda) 656 657 if args: 658 order = args[-1] if isinstance(args[-1], exp.Order) else None 659 660 if order: 661 # Order By is the last (or only) expression in the list and has consumed the 'expr' before it, 662 # remove 'expr' from exp.Order and add it back to args 663 args[-1] = order.this 664 order.set("this", concat_exprs(order.this, args)) 665 666 this = order or concat_exprs(args[0], args) 667 else: 668 this = None 669 670 separator = self._parse_field() if self._match(TokenType.SEPARATOR) else None 671 672 return self.expression(exp.GroupConcat, this=this, separator=separator) 673 674 def _parse_json_value(self) -> exp.JSONValue: 675 this = self._parse_bitwise() 676 self._match(TokenType.COMMA) 677 path = self._parse_bitwise() 678 679 returning = self._match(TokenType.RETURNING) and self._parse_type() 680 681 return self.expression( 682 exp.JSONValue, 683 this=this, 684 path=self.dialect.to_json_path(path), 685 returning=returning, 686 on_condition=self._parse_on_condition(), 687 )
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.UTINYINT: 'UTINYINT'>, <TokenType.ISNULL: 'ISNULL'>, <TokenType.ILIKE: 'ILIKE'>, <TokenType.JSON: 'JSON'>, <TokenType.SMALLSERIAL: 'SMALLSERIAL'>, <TokenType.TIMESTAMP_NS: 'TIMESTAMP_NS'>, <TokenType.INT: 'INT'>, <TokenType.MULTIPOLYGON: 'MULTIPOLYGON'>, <TokenType.INT8RANGE: 'INT8RANGE'>, <TokenType.TDIGEST: 'TDIGEST'>, <TokenType.ENUM: 'ENUM'>, <TokenType.NULL: 'NULL'>, <TokenType.FLOAT: 'FLOAT'>, <TokenType.LONGBLOB: 'LONGBLOB'>, <TokenType.ALL: 'ALL'>, <TokenType.IPV6: 'IPV6'>, <TokenType.INTERVAL: 'INTERVAL'>, <TokenType.BIGDECIMAL: 'BIGDECIMAL'>, <TokenType.MEDIUMINT: 'MEDIUMINT'>, <TokenType.XML: 'XML'>, <TokenType.VARCHAR: 'VARCHAR'>, <TokenType.ROWVERSION: 'ROWVERSION'>, <TokenType.RANGE: 'RANGE'>, <TokenType.UDECIMAL: 'UDECIMAL'>, <TokenType.VARBINARY: 'VARBINARY'>, <TokenType.FILTER: 'FILTER'>, <TokenType.TIMESTAMP_S: 'TIMESTAMP_S'>, <TokenType.OBJECT_IDENTIFIER: 'OBJECT_IDENTIFIER'>, <TokenType.DECIMAL128: 'DECIMAL128'>, <TokenType.DOUBLE: 'DOUBLE'>, <TokenType.VECTOR: 'VECTOR'>, <TokenType.NULLABLE: 'NULLABLE'>, <TokenType.USERDEFINED: 'USERDEFINED'>, <TokenType.INSERT: 'INSERT'>, <TokenType.IPPREFIX: 'IPPREFIX'>, <TokenType.ENUM8: 'ENUM8'>, <TokenType.BINARY: 'BINARY'>, <TokenType.HSTORE: 'HSTORE'>, <TokenType.UNIQUEIDENTIFIER: 'UNIQUEIDENTIFIER'>, <TokenType.TIMESTAMP: 'TIMESTAMP'>, <TokenType.MEDIUMBLOB: 'MEDIUMBLOB'>, <TokenType.TINYBLOB: 'TINYBLOB'>, <TokenType.DECIMAL256: 'DECIMAL256'>, <TokenType.RING: 'RING'>, <TokenType.SMALLMONEY: 'SMALLMONEY'>, <TokenType.SIMPLEAGGREGATEFUNCTION: 'SIMPLEAGGREGATEFUNCTION'>, <TokenType.NUMRANGE: 'NUMRANGE'>, <TokenType.LONGTEXT: 'LONGTEXT'>, <TokenType.DATE: 'DATE'>, <TokenType.DATETIME: 'DATETIME'>, <TokenType.DATETIME64: 'DATETIME64'>, <TokenType.INT4MULTIRANGE: 'INT4MULTIRANGE'>, <TokenType.INT256: 'INT256'>, <TokenType.UINT: 'UINT'>, <TokenType.SEQUENCE: 'SEQUENCE'>, <TokenType.ARRAY: 'ARRAY'>, <TokenType.SUPER: 'SUPER'>, <TokenType.YEAR: 'YEAR'>, <TokenType.GLOB: 'GLOB'>, <TokenType.LEFT: 'LEFT'>, <TokenType.CURRENT_DATETIME: 'CURRENT_DATETIME'>, <TokenType.IDENTIFIER: 'IDENTIFIER'>, <TokenType.INET: 'INET'>, <TokenType.CURRENT_TIME: 'CURRENT_TIME'>, <TokenType.UBIGINT: 'UBIGINT'>, <TokenType.INT8MULTIRANGE: 'INT8MULTIRANGE'>, <TokenType.GEOMETRY: 'GEOMETRY'>, <TokenType.GEOGRAPHY: 'GEOGRAPHY'>, <TokenType.SCHEMA: 'SCHEMA'>, <TokenType.TSRANGE: 'TSRANGE'>, <TokenType.RIGHT: 'RIGHT'>, <TokenType.FIRST: 'FIRST'>, <TokenType.POINT: 'POINT'>, <TokenType.SERIAL: 'SERIAL'>, <TokenType.NVARCHAR: 'NVARCHAR'>, <TokenType.VARIANT: 'VARIANT'>, <TokenType.RLIKE: 'RLIKE'>, <TokenType.OFFSET: 'OFFSET'>, <TokenType.TIMESTAMP_MS: 'TIMESTAMP_MS'>, <TokenType.MAP: 'MAP'>, <TokenType.DECIMAL: 'DECIMAL'>, <TokenType.WINDOW: 'WINDOW'>, <TokenType.COLLATE: 'COLLATE'>, <TokenType.SMALLINT: 'SMALLINT'>, <TokenType.BIT: 'BIT'>, <TokenType.IPADDRESS: 'IPADDRESS'>, <TokenType.VALUES: 'VALUES'>, <TokenType.NESTED: 'NESTED'>, <TokenType.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, <TokenType.MERGE: 'MERGE'>, <TokenType.UINT256: 'UINT256'>, <TokenType.INT4RANGE: 'INT4RANGE'>, <TokenType.INT128: 'INT128'>, <TokenType.USMALLINT: 'USMALLINT'>, <TokenType.EXISTS: 'EXISTS'>, <TokenType.PSEUDO_TYPE: 'PSEUDO_TYPE'>, <TokenType.OBJECT: 'OBJECT'>, <TokenType.CURRENT_DATE: 'CURRENT_DATE'>, <TokenType.VAR: 'VAR'>, <TokenType.BPCHAR: 'BPCHAR'>, <TokenType.DECIMAL64: 'DECIMAL64'>, <TokenType.NUMMULTIRANGE: 'NUMMULTIRANGE'>, <TokenType.UNION: 'UNION'>, <TokenType.UINT128: 'UINT128'>, <TokenType.UNKNOWN: 'UNKNOWN'>, <TokenType.TSMULTIRANGE: 'TSMULTIRANGE'>, <TokenType.MEDIUMTEXT: 'MEDIUMTEXT'>, <TokenType.TIMESTAMPNTZ: 'TIMESTAMPNTZ'>, <TokenType.BIGSERIAL: 'BIGSERIAL'>, <TokenType.CURRENT_TIMESTAMP: 'CURRENT_TIMESTAMP'>, <TokenType.STRUCT: 'STRUCT'>, <TokenType.INDEX: 'INDEX'>, <TokenType.MULTILINESTRING: 'MULTILINESTRING'>, <TokenType.JSONB: 'JSONB'>, <TokenType.NCHAR: 'NCHAR'>, <TokenType.DATERANGE: 'DATERANGE'>, <TokenType.TRUNCATE: 'TRUNCATE'>, <TokenType.TSTZRANGE: 'TSTZRANGE'>, <TokenType.ROW: 'ROW'>, <TokenType.UUID: 'UUID'>, <TokenType.ENUM16: 'ENUM16'>, <TokenType.DATE32: 'DATE32'>, <TokenType.POLYGON: 'POLYGON'>, <TokenType.DATEMULTIRANGE: 'DATEMULTIRANGE'>, <TokenType.DATABASE: 'DATABASE'>, <TokenType.BOOLEAN: 'BOOLEAN'>, <TokenType.NAME: 'NAME'>, <TokenType.TIMESTAMPTZ: 'TIMESTAMPTZ'>, <TokenType.CHAR: 'CHAR'>, <TokenType.LIKE: 'LIKE'>, <TokenType.BIGINT: 'BIGINT'>, <TokenType.MONEY: 'MONEY'>, <TokenType.LIST: 'LIST'>, <TokenType.FIXEDSTRING: 'FIXEDSTRING'>, <TokenType.UNNEST: 'UNNEST'>, <TokenType.TSTZMULTIRANGE: 'TSTZMULTIRANGE'>, <TokenType.HLLSKETCH: 'HLLSKETCH'>, <TokenType.LINESTRING: 'LINESTRING'>, <TokenType.IPV4: 'IPV4'>, <TokenType.IMAGE: 'IMAGE'>, <TokenType.TINYINT: 'TINYINT'>, <TokenType.DECIMAL32: 'DECIMAL32'>, <TokenType.UMEDIUMINT: 'UMEDIUMINT'>, <TokenType.COMMAND: 'COMMAND'>, <TokenType.PRIMARY_KEY: 'PRIMARY_KEY'>, <TokenType.TIME: 'TIME'>, <TokenType.TABLE: 'TABLE'>, <TokenType.TEXT: 'TEXT'>, <TokenType.AGGREGATEFUNCTION: 'AGGREGATEFUNCTION'>, <TokenType.FORMAT: 'FORMAT'>, <TokenType.LOWCARDINALITY: 'LOWCARDINALITY'>, <TokenType.CURRENT_USER: 'CURRENT_USER'>, <TokenType.TIMETZ: 'TIMETZ'>, <TokenType.TINYTEXT: 'TINYTEXT'>, <TokenType.REPLACE: 'REPLACE'>, <TokenType.XOR: 'XOR'>, <TokenType.SOME: 'SOME'>, <TokenType.ANY: 'ANY'>}
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.PERCENT: 'PERCENT'>, <TokenType.ISNULL: 'ISNULL'>, <TokenType.IS: 'IS'>, <TokenType.VIEW: 'VIEW'>, <TokenType.UTINYINT: 'UTINYINT'>, <TokenType.JSON: 'JSON'>, <TokenType.SMALLSERIAL: 'SMALLSERIAL'>, <TokenType.TIMESTAMP_NS: 'TIMESTAMP_NS'>, <TokenType.INT: 'INT'>, <TokenType.MULTIPOLYGON: 'MULTIPOLYGON'>, <TokenType.INT8RANGE: 'INT8RANGE'>, <TokenType.TDIGEST: 'TDIGEST'>, <TokenType.FALSE: 'FALSE'>, <TokenType.KEEP: 'KEEP'>, <TokenType.ENUM: 'ENUM'>, <TokenType.NULL: 'NULL'>, <TokenType.TAG: 'TAG'>, <TokenType.FLOAT: 'FLOAT'>, <TokenType.LONGBLOB: 'LONGBLOB'>, <TokenType.ALL: 'ALL'>, <TokenType.IPV6: 'IPV6'>, <TokenType.INTERVAL: 'INTERVAL'>, <TokenType.BIGDECIMAL: 'BIGDECIMAL'>, <TokenType.MEDIUMINT: 'MEDIUMINT'>, <TokenType.FINAL: 'FINAL'>, <TokenType.XML: 'XML'>, <TokenType.PIVOT: 'PIVOT'>, <TokenType.OPERATOR: 'OPERATOR'>, <TokenType.VARCHAR: 'VARCHAR'>, <TokenType.ROWVERSION: 'ROWVERSION'>, <TokenType.RANGE: 'RANGE'>, <TokenType.UDECIMAL: 'UDECIMAL'>, <TokenType.VARBINARY: 'VARBINARY'>, <TokenType.FILTER: 'FILTER'>, <TokenType.DELETE: 'DELETE'>, <TokenType.TIMESTAMP_S: 'TIMESTAMP_S'>, <TokenType.OBJECT_IDENTIFIER: 'OBJECT_IDENTIFIER'>, <TokenType.DECIMAL128: 'DECIMAL128'>, <TokenType.DOUBLE: 'DOUBLE'>, <TokenType.OVERLAPS: 'OVERLAPS'>, <TokenType.VECTOR: 'VECTOR'>, <TokenType.NULLABLE: 'NULLABLE'>, <TokenType.STORAGE_INTEGRATION: 'STORAGE_INTEGRATION'>, <TokenType.USERDEFINED: 'USERDEFINED'>, <TokenType.REFRESH: 'REFRESH'>, <TokenType.FUNCTION: 'FUNCTION'>, <TokenType.ORDINALITY: 'ORDINALITY'>, <TokenType.IPPREFIX: 'IPPREFIX'>, <TokenType.ENUM8: 'ENUM8'>, <TokenType.BINARY: 'BINARY'>, <TokenType.HSTORE: 'HSTORE'>, <TokenType.UNIQUEIDENTIFIER: 'UNIQUEIDENTIFIER'>, <TokenType.END: 'END'>, <TokenType.COMMENT: 'COMMENT'>, <TokenType.TIMESTAMP: 'TIMESTAMP'>, <TokenType.MEDIUMBLOB: 'MEDIUMBLOB'>, <TokenType.SEMI: 'SEMI'>, <TokenType.TINYBLOB: 'TINYBLOB'>, <TokenType.ASC: 'ASC'>, <TokenType.DECIMAL256: 'DECIMAL256'>, <TokenType.RING: 'RING'>, <TokenType.SMALLMONEY: 'SMALLMONEY'>, <TokenType.SIMPLEAGGREGATEFUNCTION: 'SIMPLEAGGREGATEFUNCTION'>, <TokenType.UNPIVOT: 'UNPIVOT'>, <TokenType.NUMRANGE: 'NUMRANGE'>, <TokenType.CASE: 'CASE'>, <TokenType.LONGTEXT: 'LONGTEXT'>, <TokenType.DATETIME: 'DATETIME'>, <TokenType.DATE: 'DATE'>, <TokenType.DATETIME64: 'DATETIME64'>, <TokenType.RECURSIVE: 'RECURSIVE'>, <TokenType.PRAGMA: 'PRAGMA'>, <TokenType.INT4MULTIRANGE: 'INT4MULTIRANGE'>, <TokenType.INT256: 'INT256'>, <TokenType.UINT: 'UINT'>, <TokenType.COMMIT: 'COMMIT'>, <TokenType.SEQUENCE: 'SEQUENCE'>, <TokenType.SET: 'SET'>, <TokenType.RENAME: 'RENAME'>, <TokenType.ARRAY: 'ARRAY'>, <TokenType.SUPER: 'SUPER'>, <TokenType.YEAR: 'YEAR'>, <TokenType.IDENTIFIER: 'IDENTIFIER'>, <TokenType.STREAMLIT: 'STREAMLIT'>, <TokenType.CURRENT_DATETIME: 'CURRENT_DATETIME'>, <TokenType.LOAD: 'LOAD'>, <TokenType.INET: 'INET'>, <TokenType.UBIGINT: 'UBIGINT'>, <TokenType.CURRENT_TIME: 'CURRENT_TIME'>, <TokenType.INT8MULTIRANGE: 'INT8MULTIRANGE'>, <TokenType.GEOMETRY: 'GEOMETRY'>, <TokenType.GEOGRAPHY: 'GEOGRAPHY'>, <TokenType.SCHEMA: 'SCHEMA'>, <TokenType.TSRANGE: 'TSRANGE'>, <TokenType.FIRST: 'FIRST'>, <TokenType.POINT: 'POINT'>, <TokenType.DEFAULT: 'DEFAULT'>, <TokenType.SERIAL: 'SERIAL'>, <TokenType.NVARCHAR: 'NVARCHAR'>, <TokenType.ROWS: 'ROWS'>, <TokenType.VARIANT: 'VARIANT'>, <TokenType.DIV: 'DIV'>, <TokenType.TIMESTAMP_MS: 'TIMESTAMP_MS'>, <TokenType.MAP: 'MAP'>, <TokenType.DECIMAL: 'DECIMAL'>, <TokenType.COLLATE: 'COLLATE'>, <TokenType.BEGIN: 'BEGIN'>, <TokenType.SMALLINT: 'SMALLINT'>, <TokenType.BIT: 'BIT'>, <TokenType.IPADDRESS: 'IPADDRESS'>, <TokenType.NESTED: 'NESTED'>, <TokenType.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, <TokenType.MERGE: 'MERGE'>, <TokenType.UINT256: 'UINT256'>, <TokenType.ROLLUP: 'ROLLUP'>, <TokenType.INT4RANGE: 'INT4RANGE'>, <TokenType.NEXT: 'NEXT'>, <TokenType.INT128: 'INT128'>, <TokenType.UPDATE: 'UPDATE'>, <TokenType.USMALLINT: 'USMALLINT'>, <TokenType.ANTI: 'ANTI'>, <TokenType.CUBE: 'CUBE'>, <TokenType.EXISTS: 'EXISTS'>, <TokenType.PSEUDO_TYPE: 'PSEUDO_TYPE'>, <TokenType.OBJECT: 'OBJECT'>, <TokenType.CURRENT_DATE: 'CURRENT_DATE'>, <TokenType.PROCEDURE: 'PROCEDURE'>, <TokenType.VAR: 'VAR'>, <TokenType.BPCHAR: 'BPCHAR'>, <TokenType.DECIMAL64: 'DECIMAL64'>, <TokenType.FOREIGN_KEY: 'FOREIGN_KEY'>, <TokenType.NUMMULTIRANGE: 'NUMMULTIRANGE'>, <TokenType.TOP: 'TOP'>, <TokenType.UINT128: 'UINT128'>, <TokenType.UNKNOWN: 'UNKNOWN'>, <TokenType.TSMULTIRANGE: 'TSMULTIRANGE'>, <TokenType.COPY: 'COPY'>, <TokenType.MEDIUMTEXT: 'MEDIUMTEXT'>, <TokenType.SETTINGS: 'SETTINGS'>, <TokenType.WAREHOUSE: 'WAREHOUSE'>, <TokenType.TIMESTAMPNTZ: 'TIMESTAMPNTZ'>, <TokenType.BIGSERIAL: 'BIGSERIAL'>, <TokenType.CURRENT_TIMESTAMP: 'CURRENT_TIMESTAMP'>, <TokenType.STRUCT: 'STRUCT'>, <TokenType.INDEX: 'INDEX'>, <TokenType.MULTILINESTRING: 'MULTILINESTRING'>, <TokenType.JSONB: 'JSONB'>, <TokenType.NCHAR: 'NCHAR'>, <TokenType.MODEL: 'MODEL'>, <TokenType.DATERANGE: 'DATERANGE'>, <TokenType.SHOW: 'SHOW'>, <TokenType.TRUNCATE: 'TRUNCATE'>, <TokenType.TSTZRANGE: 'TSTZRANGE'>, <TokenType.ROW: 'ROW'>, <TokenType.DATABASE: 'DATABASE'>, <TokenType.AUTO_INCREMENT: 'AUTO_INCREMENT'>, <TokenType.VOLATILE: 'VOLATILE'>, <TokenType.UUID: 'UUID'>, <TokenType.ENUM16: 'ENUM16'>, <TokenType.COLUMN: 'COLUMN'>, <TokenType.DATE32: 'DATE32'>, <TokenType.POLYGON: 'POLYGON'>, <TokenType.DATEMULTIRANGE: 'DATEMULTIRANGE'>, <TokenType.BOOLEAN: 'BOOLEAN'>, <TokenType.NAME: 'NAME'>, <TokenType.ESCAPE: 'ESCAPE'>, <TokenType.CACHE: 'CACHE'>, <TokenType.TIMESTAMPTZ: 'TIMESTAMPTZ'>, <TokenType.CHAR: 'CHAR'>, <TokenType.BIGINT: 'BIGINT'>, <TokenType.OVERWRITE: 'OVERWRITE'>, <TokenType.MONEY: 'MONEY'>, <TokenType.LIST: 'LIST'>, <TokenType.FIXEDSTRING: 'FIXEDSTRING'>, <TokenType.UNNEST: 'UNNEST'>, <TokenType.PARTITION: 'PARTITION'>, <TokenType.TSTZMULTIRANGE: 'TSTZMULTIRANGE'>, <TokenType.HLLSKETCH: 'HLLSKETCH'>, <TokenType.LINESTRING: 'LINESTRING'>, <TokenType.KILL: 'KILL'>, <TokenType.DESCRIBE: 'DESCRIBE'>, <TokenType.UNIQUE: 'UNIQUE'>, <TokenType.REFERENCES: 'REFERENCES'>, <TokenType.IPV4: 'IPV4'>, <TokenType.IMAGE: 'IMAGE'>, <TokenType.TINYINT: 'TINYINT'>, <TokenType.DECIMAL32: 'DECIMAL32'>, <TokenType.CONSTRAINT: 'CONSTRAINT'>, <TokenType.EXECUTE: 'EXECUTE'>, <TokenType.UMEDIUMINT: 'UMEDIUMINT'>, <TokenType.COMMAND: 'COMMAND'>, <TokenType.TEMPORARY: 'TEMPORARY'>, <TokenType.TIME: 'TIME'>, <TokenType.TRUE: 'TRUE'>, <TokenType.TABLE: 'TABLE'>, <TokenType.TEXT: 'TEXT'>, <TokenType.AGGREGATEFUNCTION: 'AGGREGATEFUNCTION'>, <TokenType.FORMAT: 'FORMAT'>, <TokenType.LOWCARDINALITY: 'LOWCARDINALITY'>, <TokenType.CURRENT_USER: 'CURRENT_USER'>, <TokenType.TIMETZ: 'TIMETZ'>, <TokenType.TINYTEXT: 'TINYTEXT'>, <TokenType.DESC: 'DESC'>, <TokenType.REPLACE: 'REPLACE'>, <TokenType.SOME: 'SOME'>, <TokenType.DICTIONARY: 'DICTIONARY'>, <TokenType.ANY: 'ANY'>}
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'>>, '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'>>, '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'>>, '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_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'>>, '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'>>, '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_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_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_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>, 'CONVERT_TZ': <function MySQL.Parser.<lambda>>, 'DATE_FORMAT': <function build_formatted_time.<locals>._builder>, '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>>, '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 =
{'PERIOD', 'UNIQUE', 'KEY', 'FOREIGN KEY', 'CHECK', 'PRIMARY KEY', 'EXCLUDE', 'LIKE', 'SPATIAL', 'INDEX', 'FULLTEXT'}
PROFILE_TYPES: Dict[str, Sequence[Union[Sequence[str], str]]] =
{'ALL': (), 'CPU': (), 'IPC': (), 'MEMORY': (), 'SOURCE': (), 'SWAPS': (), 'BLOCK': ('IO',), 'CONTEXT': ('SWITCHES',), 'PAGE': ('FAULTS',)}
TYPE_TOKENS =
{<TokenType.UTINYINT: 'UTINYINT'>, <TokenType.TIMESTAMP_MS: 'TIMESTAMP_MS'>, <TokenType.MAP: 'MAP'>, <TokenType.DECIMAL: 'DECIMAL'>, <TokenType.JSON: 'JSON'>, <TokenType.SMALLSERIAL: 'SMALLSERIAL'>, <TokenType.TIMESTAMP_NS: 'TIMESTAMP_NS'>, <TokenType.INT: 'INT'>, <TokenType.MULTIPOLYGON: 'MULTIPOLYGON'>, <TokenType.INT8RANGE: 'INT8RANGE'>, <TokenType.TDIGEST: 'TDIGEST'>, <TokenType.ENUM: 'ENUM'>, <TokenType.NULL: 'NULL'>, <TokenType.SMALLINT: 'SMALLINT'>, <TokenType.BIT: 'BIT'>, <TokenType.IPADDRESS: 'IPADDRESS'>, <TokenType.NESTED: 'NESTED'>, <TokenType.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, <TokenType.FLOAT: 'FLOAT'>, <TokenType.LONGBLOB: 'LONGBLOB'>, <TokenType.UINT256: 'UINT256'>, <TokenType.INT4RANGE: 'INT4RANGE'>, <TokenType.IPV6: 'IPV6'>, <TokenType.INTERVAL: 'INTERVAL'>, <TokenType.INT128: 'INT128'>, <TokenType.BIGDECIMAL: 'BIGDECIMAL'>, <TokenType.MEDIUMINT: 'MEDIUMINT'>, <TokenType.USMALLINT: 'USMALLINT'>, <TokenType.XML: 'XML'>, <TokenType.PSEUDO_TYPE: 'PSEUDO_TYPE'>, <TokenType.OBJECT: 'OBJECT'>, <TokenType.VARCHAR: 'VARCHAR'>, <TokenType.ROWVERSION: 'ROWVERSION'>, <TokenType.UDECIMAL: 'UDECIMAL'>, <TokenType.VARBINARY: 'VARBINARY'>, <TokenType.TIMESTAMP_S: 'TIMESTAMP_S'>, <TokenType.OBJECT_IDENTIFIER: 'OBJECT_IDENTIFIER'>, <TokenType.RANGE: 'RANGE'>, <TokenType.DECIMAL128: 'DECIMAL128'>, <TokenType.DOUBLE: 'DOUBLE'>, <TokenType.BPCHAR: 'BPCHAR'>, <TokenType.DECIMAL64: 'DECIMAL64'>, <TokenType.VECTOR: 'VECTOR'>, <TokenType.NULLABLE: 'NULLABLE'>, <TokenType.NUMMULTIRANGE: 'NUMMULTIRANGE'>, <TokenType.UNION: 'UNION'>, <TokenType.USERDEFINED: 'USERDEFINED'>, <TokenType.UINT128: 'UINT128'>, <TokenType.UNKNOWN: 'UNKNOWN'>, <TokenType.TSMULTIRANGE: 'TSMULTIRANGE'>, <TokenType.MEDIUMTEXT: 'MEDIUMTEXT'>, <TokenType.IPPREFIX: 'IPPREFIX'>, <TokenType.TIMESTAMPNTZ: 'TIMESTAMPNTZ'>, <TokenType.BIGSERIAL: 'BIGSERIAL'>, <TokenType.ENUM8: 'ENUM8'>, <TokenType.BINARY: 'BINARY'>, <TokenType.HSTORE: 'HSTORE'>, <TokenType.UNIQUEIDENTIFIER: 'UNIQUEIDENTIFIER'>, <TokenType.STRUCT: 'STRUCT'>, <TokenType.MULTILINESTRING: 'MULTILINESTRING'>, <TokenType.TIMESTAMP: 'TIMESTAMP'>, <TokenType.JSONB: 'JSONB'>, <TokenType.MEDIUMBLOB: 'MEDIUMBLOB'>, <TokenType.NCHAR: 'NCHAR'>, <TokenType.TINYBLOB: 'TINYBLOB'>, <TokenType.DATERANGE: 'DATERANGE'>, <TokenType.TSTZRANGE: 'TSTZRANGE'>, <TokenType.UUID: 'UUID'>, <TokenType.DECIMAL256: 'DECIMAL256'>, <TokenType.RING: 'RING'>, <TokenType.ENUM16: 'ENUM16'>, <TokenType.DATE32: 'DATE32'>, <TokenType.POLYGON: 'POLYGON'>, <TokenType.DATEMULTIRANGE: 'DATEMULTIRANGE'>, <TokenType.SMALLMONEY: 'SMALLMONEY'>, <TokenType.BOOLEAN: 'BOOLEAN'>, <TokenType.NAME: 'NAME'>, <TokenType.SIMPLEAGGREGATEFUNCTION: 'SIMPLEAGGREGATEFUNCTION'>, <TokenType.NUMRANGE: 'NUMRANGE'>, <TokenType.TIMESTAMPTZ: 'TIMESTAMPTZ'>, <TokenType.CHAR: 'CHAR'>, <TokenType.BIGINT: 'BIGINT'>, <TokenType.LONGTEXT: 'LONGTEXT'>, <TokenType.DATETIME: 'DATETIME'>, <TokenType.DATE: 'DATE'>, <TokenType.DATETIME64: 'DATETIME64'>, <TokenType.INT4MULTIRANGE: 'INT4MULTIRANGE'>, <TokenType.MONEY: 'MONEY'>, <TokenType.LIST: 'LIST'>, <TokenType.FIXEDSTRING: 'FIXEDSTRING'>, <TokenType.INT256: 'INT256'>, <TokenType.TSTZMULTIRANGE: 'TSTZMULTIRANGE'>, <TokenType.UINT: 'UINT'>, <TokenType.HLLSKETCH: 'HLLSKETCH'>, <TokenType.LINESTRING: 'LINESTRING'>, <TokenType.ARRAY: 'ARRAY'>, <TokenType.SET: 'SET'>, <TokenType.SUPER: 'SUPER'>, <TokenType.YEAR: 'YEAR'>, <TokenType.IPV4: 'IPV4'>, <TokenType.IMAGE: 'IMAGE'>, <TokenType.TINYINT: 'TINYINT'>, <TokenType.DECIMAL32: 'DECIMAL32'>, <TokenType.INET: 'INET'>, <TokenType.UBIGINT: 'UBIGINT'>, <TokenType.INT8MULTIRANGE: 'INT8MULTIRANGE'>, <TokenType.GEOMETRY: 'GEOMETRY'>, <TokenType.GEOGRAPHY: 'GEOGRAPHY'>, <TokenType.UMEDIUMINT: 'UMEDIUMINT'>, <TokenType.TSRANGE: 'TSRANGE'>, <TokenType.TIME: 'TIME'>, <TokenType.POINT: 'POINT'>, <TokenType.SERIAL: 'SERIAL'>, <TokenType.TEXT: 'TEXT'>, <TokenType.AGGREGATEFUNCTION: 'AGGREGATEFUNCTION'>, <TokenType.NVARCHAR: 'NVARCHAR'>, <TokenType.LOWCARDINALITY: 'LOWCARDINALITY'>, <TokenType.TIMETZ: 'TIMETZ'>, <TokenType.TINYTEXT: 'TINYTEXT'>, <TokenType.VARIANT: 'VARIANT'>}
ENUM_TYPE_TOKENS =
{<TokenType.ENUM16: 'ENUM16'>, <TokenType.ENUM8: 'ENUM8'>, <TokenType.SET: 'SET'>, <TokenType.ENUM: 'ENUM'>}
OPERATION_MODIFIERS =
{'HIGH_PRIORITY', 'SQL_CALC_FOUND_ROWS', 'SQL_BUFFER_RESULT', 'SQL_BIG_RESULT', 'STRAIGHT_JOIN', 'SQL_NO_CACHE', 'SQL_SMALL_RESULT'}
SHOW_TRIE: Dict =
{'BINARY': {'LOGS': {0: True}}, 'MASTER': {'LOGS': {0: True}, 'STATUS': {0: True}}, 'BINLOG': {'EVENTS': {0: True}}, 'CHARACTER': {'SET': {0: True}}, 'CHARSET': {0: True}, 'COLLATION': {0: True}, 'FULL': {'COLUMNS': {0: True}, 'PROCESSLIST': {0: True}, 'TABLES': {0: True}}, 'COLUMNS': {0: True}, 'CREATE': {'DATABASE': {0: True}, 'EVENT': {0: True}, 'FUNCTION': {0: True}, 'PROCEDURE': {0: True}, 'TABLE': {0: True}, 'TRIGGER': {0: True}, 'VIEW': {0: True}}, 'DATABASES': {0: True}, 'SCHEMAS': {0: True}, 'ENGINE': {0: True}, 'STORAGE': {'ENGINES': {0: True}}, 'ENGINES': {0: True}, 'ERRORS': {0: True}, 'EVENTS': {0: True}, 'FUNCTION': {'CODE': {0: True}, 'STATUS': {0: True}}, 'GRANTS': {0: True}, 'INDEX': {0: True}, 'OPEN': {'TABLES': {0: True}}, 'PLUGINS': {0: True}, 'PROCEDURE': {'CODE': {0: True}, 'STATUS': {0: True}}, 'PRIVILEGES': {0: True}, 'PROCESSLIST': {0: True}, 'PROFILE': {0: True}, 'PROFILES': {0: True}, 'RELAYLOG': {'EVENTS': {0: True}}, 'REPLICAS': {0: True}, 'SLAVE': {'HOSTS': {0: True}, 'STATUS': {0: True}}, 'REPLICA': {'STATUS': {0: True}}, 'GLOBAL': {'STATUS': {0: True}, 'VARIABLES': {0: True}}, 'SESSION': {'STATUS': {0: True}, 'VARIABLES': {0: True}}, 'STATUS': {0: True}, 'TABLE': {'STATUS': {0: True}}, 'TABLES': {0: True}, 'TRIGGERS': {0: True}, 'VARIABLES': {0: True}, 'WARNINGS': {0: True}}
SET_TRIE: Dict =
{'GLOBAL': {0: True}, 'LOCAL': {0: True}, 'SESSION': {0: True}, 'TRANSACTION': {0: True}, 'PERSIST': {0: True}, 'PERSIST_ONLY': {0: True}, 'CHARACTER': {'SET': {0: True}}, 'CHARSET': {0: True}, 'NAMES': {0: True}}
Inherited Members
- sqlglot.parser.Parser
- Parser
- NO_PAREN_FUNCTIONS
- STRUCT_TYPE_TOKENS
- NESTED_TYPE_TOKENS
- AGGREGATE_TYPE_TOKENS
- SIGNED_TO_UNSIGNED_TYPE_TOKEN
- SUBQUERY_PREDICATES
- RESERVED_TOKENS
- DB_CREATABLES
- CREATABLES
- ALTERABLES
- ID_VAR_TOKENS
- INTERVAL_VARS
- ALIAS_TOKENS
- ARRAY_CONSTRUCTORS
- COMMENT_TABLE_ALIAS_TOKENS
- UPDATE_ALIAS_TOKENS
- TRIM_TYPES
- ASSIGNMENT
- EQUALITY
- COMPARISON
- BITWISE
- TERM
- FACTOR
- EXPONENT
- TIMES
- TIMESTAMPS
- SET_OPERATIONS
- JOIN_METHODS
- JOIN_SIDES
- JOIN_KINDS
- JOIN_HINTS
- LAMBDAS
- COLUMN_OPERATORS
- EXPRESSION_PARSERS
- UNARY_PARSERS
- STRING_PARSERS
- NUMERIC_PARSERS
- PRIMARY_PARSERS
- PLACEHOLDER_PARSERS
- ALTER_ALTER_PARSERS
- NO_PAREN_FUNCTION_PARSERS
- INVALID_FUNC_NAME_TOKENS
- FUNCTIONS_WITH_ALIASED_ARGS
- KEY_VALUE_DEFINITIONS
- QUERY_MODIFIER_PARSERS
- TYPE_LITERAL_PARSERS
- TYPE_CONVERTERS
- DDL_SELECT_TOKENS
- PRE_VOLATILE_TOKENS
- TRANSACTION_KIND
- TRANSACTION_CHARACTERISTICS
- CONFLICT_ACTIONS
- CREATE_SEQUENCE
- ISOLATED_LOADING_OPTIONS
- USABLES
- CAST_ACTIONS
- SCHEMA_BINDING_OPTIONS
- PROCEDURE_OPTIONS
- EXECUTE_AS_OPTIONS
- KEY_CONSTRAINT_OPTIONS
- INSERT_ALTERNATIVES
- CLONE_KEYWORDS
- HISTORICAL_DATA_PREFIX
- HISTORICAL_DATA_KIND
- OPCLASS_FOLLOW_KEYWORDS
- OPTYPE_FOLLOW_TOKENS
- TABLE_INDEX_HINT_TOKENS
- VIEW_ATTRIBUTES
- WINDOW_ALIAS_TOKENS
- WINDOW_BEFORE_PAREN_TOKENS
- WINDOW_SIDES
- JSON_KEY_VALUE_SEPARATOR_TOKENS
- FETCH_TOKENS
- ADD_CONSTRAINT_TOKENS
- DISTINCT_TOKENS
- NULL_TOKENS
- UNNEST_OFFSET_ALIAS_TOKENS
- SELECT_START_TOKENS
- COPY_INTO_VARLEN_OPTIONS
- IS_JSON_PREDICATE_KIND
- ODBC_DATETIME_LITERALS
- ON_CONDITION_TOKENS
- PRIVILEGE_FOLLOW_TOKENS
- DESCRIBE_STYLES
- STRICT_CAST
- PREFIXED_PIVOT_COLUMNS
- IDENTIFY_PIVOT_STRINGS
- ALTER_TABLE_ADD_REQUIRED_FOR_EACH_COLUMN
- TABLESAMPLE_CSV
- DEFAULT_SAMPLING_METHOD
- SET_REQUIRES_ASSIGNMENT_DELIMITER
- TRIM_PATTERN_FIRST
- MODIFIERS_ATTACHED_TO_SET_OP
- SET_OP_MODIFIERS
- NO_PAREN_IF_COMMANDS
- JSON_ARROWS_REQUIRE_JSON_TYPE
- COLON_IS_VARIANT_EXTRACT
- SUPPORTS_IMPLICIT_UNNEST
- INTERVAL_SPANS
- error_level
- error_message_context
- max_errors
- dialect
- reset
- parse
- parse_into
- check_errors
- raise_error
- expression
- validate_expression
- errors
- sql
689 class Generator(generator.Generator): 690 INTERVAL_ALLOWS_PLURAL_FORM = False 691 LOCKING_READS_SUPPORTED = True 692 NULL_ORDERING_SUPPORTED = None 693 JOIN_HINTS = False 694 TABLE_HINTS = True 695 DUPLICATE_KEY_UPDATE_WITH_SET = False 696 QUERY_HINT_SEP = " " 697 VALUES_AS_TABLE = False 698 NVL2_SUPPORTED = False 699 LAST_DAY_SUPPORTS_DATE_PART = False 700 JSON_TYPE_REQUIRED_FOR_EXTRACTION = True 701 JSON_PATH_BRACKETED_KEY_SUPPORTED = False 702 JSON_KEY_VALUE_PAIR_SEP = "," 703 SUPPORTS_TO_NUMBER = False 704 PARSE_JSON_NAME: t.Optional[str] = None 705 PAD_FILL_PATTERN_IS_REQUIRED = True 706 WRAP_DERIVED_VALUES = False 707 VARCHAR_REQUIRES_SIZE = True 708 SUPPORTS_MEDIAN = False 709 710 TRANSFORMS = { 711 **generator.Generator.TRANSFORMS, 712 exp.ArrayAgg: rename_func("GROUP_CONCAT"), 713 exp.CurrentDate: no_paren_current_date_sql, 714 exp.DateDiff: _remove_ts_or_ds_to_date( 715 lambda self, e: self.func("DATEDIFF", e.this, e.expression), ("this", "expression") 716 ), 717 exp.DateAdd: _remove_ts_or_ds_to_date(date_add_sql("ADD")), 718 exp.DateStrToDate: datestrtodate_sql, 719 exp.DateSub: _remove_ts_or_ds_to_date(date_add_sql("SUB")), 720 exp.DateTrunc: _date_trunc_sql, 721 exp.Day: _remove_ts_or_ds_to_date(), 722 exp.DayOfMonth: _remove_ts_or_ds_to_date(rename_func("DAYOFMONTH")), 723 exp.DayOfWeek: _remove_ts_or_ds_to_date(rename_func("DAYOFWEEK")), 724 exp.DayOfYear: _remove_ts_or_ds_to_date(rename_func("DAYOFYEAR")), 725 exp.GroupConcat: lambda self, 726 e: f"""GROUP_CONCAT({self.sql(e, "this")} SEPARATOR {self.sql(e, "separator") or "','"})""", 727 exp.ILike: no_ilike_sql, 728 exp.JSONExtractScalar: arrow_json_extract_sql, 729 exp.Max: max_or_greatest, 730 exp.Min: min_or_least, 731 exp.Month: _remove_ts_or_ds_to_date(), 732 exp.NullSafeEQ: lambda self, e: self.binary(e, "<=>"), 733 exp.NullSafeNEQ: lambda self, e: f"NOT {self.binary(e, '<=>')}", 734 exp.Pivot: no_pivot_sql, 735 exp.Select: transforms.preprocess( 736 [ 737 transforms.eliminate_distinct_on, 738 transforms.eliminate_semi_and_anti_joins, 739 transforms.eliminate_qualify, 740 transforms.eliminate_full_outer_join, 741 transforms.unnest_generate_date_array_using_recursive_cte, 742 ] 743 ), 744 exp.StrPosition: strposition_to_locate_sql, 745 exp.StrToDate: _str_to_date_sql, 746 exp.StrToTime: _str_to_date_sql, 747 exp.Stuff: rename_func("INSERT"), 748 exp.TableSample: no_tablesample_sql, 749 exp.TimeFromParts: rename_func("MAKETIME"), 750 exp.TimestampAdd: date_add_interval_sql("DATE", "ADD"), 751 exp.TimestampDiff: lambda self, e: self.func( 752 "TIMESTAMPDIFF", unit_to_var(e), e.expression, e.this 753 ), 754 exp.TimestampSub: date_add_interval_sql("DATE", "SUB"), 755 exp.TimeStrToUnix: rename_func("UNIX_TIMESTAMP"), 756 exp.TimeStrToTime: lambda self, e: timestrtotime_sql( 757 self, 758 e, 759 include_precision=not e.args.get("zone"), 760 ), 761 exp.TimeToStr: _remove_ts_or_ds_to_date( 762 lambda self, e: self.func("DATE_FORMAT", e.this, self.format_time(e)) 763 ), 764 exp.Trim: trim_sql, 765 exp.TryCast: no_trycast_sql, 766 exp.TsOrDsAdd: date_add_sql("ADD"), 767 exp.TsOrDsDiff: lambda self, e: self.func("DATEDIFF", e.this, e.expression), 768 exp.TsOrDsToDate: _ts_or_ds_to_date_sql, 769 exp.UnixToTime: _unix_to_time_sql, 770 exp.Week: _remove_ts_or_ds_to_date(), 771 exp.WeekOfYear: _remove_ts_or_ds_to_date(rename_func("WEEKOFYEAR")), 772 exp.Year: _remove_ts_or_ds_to_date(), 773 } 774 775 UNSIGNED_TYPE_MAPPING = { 776 exp.DataType.Type.UBIGINT: "BIGINT", 777 exp.DataType.Type.UINT: "INT", 778 exp.DataType.Type.UMEDIUMINT: "MEDIUMINT", 779 exp.DataType.Type.USMALLINT: "SMALLINT", 780 exp.DataType.Type.UTINYINT: "TINYINT", 781 exp.DataType.Type.UDECIMAL: "DECIMAL", 782 } 783 784 TIMESTAMP_TYPE_MAPPING = { 785 exp.DataType.Type.TIMESTAMP: "DATETIME", 786 exp.DataType.Type.TIMESTAMPTZ: "TIMESTAMP", 787 exp.DataType.Type.TIMESTAMPLTZ: "TIMESTAMP", 788 } 789 790 TYPE_MAPPING = { 791 **generator.Generator.TYPE_MAPPING, 792 **UNSIGNED_TYPE_MAPPING, 793 **TIMESTAMP_TYPE_MAPPING, 794 } 795 796 TYPE_MAPPING.pop(exp.DataType.Type.MEDIUMTEXT) 797 TYPE_MAPPING.pop(exp.DataType.Type.LONGTEXT) 798 TYPE_MAPPING.pop(exp.DataType.Type.TINYTEXT) 799 TYPE_MAPPING.pop(exp.DataType.Type.MEDIUMBLOB) 800 TYPE_MAPPING.pop(exp.DataType.Type.LONGBLOB) 801 TYPE_MAPPING.pop(exp.DataType.Type.TINYBLOB) 802 803 PROPERTIES_LOCATION = { 804 **generator.Generator.PROPERTIES_LOCATION, 805 exp.TransientProperty: exp.Properties.Location.UNSUPPORTED, 806 exp.VolatileProperty: exp.Properties.Location.UNSUPPORTED, 807 } 808 809 LIMIT_FETCH = "LIMIT" 810 811 LIMIT_ONLY_LITERALS = True 812 813 CHAR_CAST_MAPPING = dict.fromkeys( 814 ( 815 exp.DataType.Type.LONGTEXT, 816 exp.DataType.Type.LONGBLOB, 817 exp.DataType.Type.MEDIUMBLOB, 818 exp.DataType.Type.MEDIUMTEXT, 819 exp.DataType.Type.TEXT, 820 exp.DataType.Type.TINYBLOB, 821 exp.DataType.Type.TINYTEXT, 822 exp.DataType.Type.VARCHAR, 823 ), 824 "CHAR", 825 ) 826 SIGNED_CAST_MAPPING = dict.fromkeys( 827 ( 828 exp.DataType.Type.BIGINT, 829 exp.DataType.Type.BOOLEAN, 830 exp.DataType.Type.INT, 831 exp.DataType.Type.SMALLINT, 832 exp.DataType.Type.TINYINT, 833 exp.DataType.Type.MEDIUMINT, 834 ), 835 "SIGNED", 836 ) 837 838 # MySQL doesn't support many datatypes in cast. 839 # https://dev.mysql.com/doc/refman/8.0/en/cast-functions.html#function_cast 840 CAST_MAPPING = { 841 **CHAR_CAST_MAPPING, 842 **SIGNED_CAST_MAPPING, 843 exp.DataType.Type.UBIGINT: "UNSIGNED", 844 } 845 846 TIMESTAMP_FUNC_TYPES = { 847 exp.DataType.Type.TIMESTAMPTZ, 848 exp.DataType.Type.TIMESTAMPLTZ, 849 } 850 851 # https://dev.mysql.com/doc/refman/8.0/en/keywords.html 852 RESERVED_KEYWORDS = { 853 "accessible", 854 "add", 855 "all", 856 "alter", 857 "analyze", 858 "and", 859 "as", 860 "asc", 861 "asensitive", 862 "before", 863 "between", 864 "bigint", 865 "binary", 866 "blob", 867 "both", 868 "by", 869 "call", 870 "cascade", 871 "case", 872 "change", 873 "char", 874 "character", 875 "check", 876 "collate", 877 "column", 878 "condition", 879 "constraint", 880 "continue", 881 "convert", 882 "create", 883 "cross", 884 "cube", 885 "cume_dist", 886 "current_date", 887 "current_time", 888 "current_timestamp", 889 "current_user", 890 "cursor", 891 "database", 892 "databases", 893 "day_hour", 894 "day_microsecond", 895 "day_minute", 896 "day_second", 897 "dec", 898 "decimal", 899 "declare", 900 "default", 901 "delayed", 902 "delete", 903 "dense_rank", 904 "desc", 905 "describe", 906 "deterministic", 907 "distinct", 908 "distinctrow", 909 "div", 910 "double", 911 "drop", 912 "dual", 913 "each", 914 "else", 915 "elseif", 916 "empty", 917 "enclosed", 918 "escaped", 919 "except", 920 "exists", 921 "exit", 922 "explain", 923 "false", 924 "fetch", 925 "first_value", 926 "float", 927 "float4", 928 "float8", 929 "for", 930 "force", 931 "foreign", 932 "from", 933 "fulltext", 934 "function", 935 "generated", 936 "get", 937 "grant", 938 "group", 939 "grouping", 940 "groups", 941 "having", 942 "high_priority", 943 "hour_microsecond", 944 "hour_minute", 945 "hour_second", 946 "if", 947 "ignore", 948 "in", 949 "index", 950 "infile", 951 "inner", 952 "inout", 953 "insensitive", 954 "insert", 955 "int", 956 "int1", 957 "int2", 958 "int3", 959 "int4", 960 "int8", 961 "integer", 962 "intersect", 963 "interval", 964 "into", 965 "io_after_gtids", 966 "io_before_gtids", 967 "is", 968 "iterate", 969 "join", 970 "json_table", 971 "key", 972 "keys", 973 "kill", 974 "lag", 975 "last_value", 976 "lateral", 977 "lead", 978 "leading", 979 "leave", 980 "left", 981 "like", 982 "limit", 983 "linear", 984 "lines", 985 "load", 986 "localtime", 987 "localtimestamp", 988 "lock", 989 "long", 990 "longblob", 991 "longtext", 992 "loop", 993 "low_priority", 994 "master_bind", 995 "master_ssl_verify_server_cert", 996 "match", 997 "maxvalue", 998 "mediumblob", 999 "mediumint", 1000 "mediumtext", 1001 "middleint", 1002 "minute_microsecond", 1003 "minute_second", 1004 "mod", 1005 "modifies", 1006 "natural", 1007 "not", 1008 "no_write_to_binlog", 1009 "nth_value", 1010 "ntile", 1011 "null", 1012 "numeric", 1013 "of", 1014 "on", 1015 "optimize", 1016 "optimizer_costs", 1017 "option", 1018 "optionally", 1019 "or", 1020 "order", 1021 "out", 1022 "outer", 1023 "outfile", 1024 "over", 1025 "partition", 1026 "percent_rank", 1027 "precision", 1028 "primary", 1029 "procedure", 1030 "purge", 1031 "range", 1032 "rank", 1033 "read", 1034 "reads", 1035 "read_write", 1036 "real", 1037 "recursive", 1038 "references", 1039 "regexp", 1040 "release", 1041 "rename", 1042 "repeat", 1043 "replace", 1044 "require", 1045 "resignal", 1046 "restrict", 1047 "return", 1048 "revoke", 1049 "right", 1050 "rlike", 1051 "row", 1052 "rows", 1053 "row_number", 1054 "schema", 1055 "schemas", 1056 "second_microsecond", 1057 "select", 1058 "sensitive", 1059 "separator", 1060 "set", 1061 "show", 1062 "signal", 1063 "smallint", 1064 "spatial", 1065 "specific", 1066 "sql", 1067 "sqlexception", 1068 "sqlstate", 1069 "sqlwarning", 1070 "sql_big_result", 1071 "sql_calc_found_rows", 1072 "sql_small_result", 1073 "ssl", 1074 "starting", 1075 "stored", 1076 "straight_join", 1077 "system", 1078 "table", 1079 "terminated", 1080 "then", 1081 "tinyblob", 1082 "tinyint", 1083 "tinytext", 1084 "to", 1085 "trailing", 1086 "trigger", 1087 "true", 1088 "undo", 1089 "union", 1090 "unique", 1091 "unlock", 1092 "unsigned", 1093 "update", 1094 "usage", 1095 "use", 1096 "using", 1097 "utc_date", 1098 "utc_time", 1099 "utc_timestamp", 1100 "values", 1101 "varbinary", 1102 "varchar", 1103 "varcharacter", 1104 "varying", 1105 "virtual", 1106 "when", 1107 "where", 1108 "while", 1109 "window", 1110 "with", 1111 "write", 1112 "xor", 1113 "year_month", 1114 "zerofill", 1115 } 1116 1117 def array_sql(self, expression: exp.Array) -> str: 1118 self.unsupported("Arrays are not supported by MySQL") 1119 return self.function_fallback_sql(expression) 1120 1121 def arraycontainsall_sql(self, expression: exp.ArrayContainsAll) -> str: 1122 self.unsupported("Array operations are not supported by MySQL") 1123 return self.function_fallback_sql(expression) 1124 1125 def dpipe_sql(self, expression: exp.DPipe) -> str: 1126 return self.func("CONCAT", *expression.flatten()) 1127 1128 def extract_sql(self, expression: exp.Extract) -> str: 1129 unit = expression.name 1130 if unit and unit.lower() == "epoch": 1131 return self.func("UNIX_TIMESTAMP", expression.expression) 1132 1133 return super().extract_sql(expression) 1134 1135 def datatype_sql(self, expression: exp.DataType) -> str: 1136 if ( 1137 self.VARCHAR_REQUIRES_SIZE 1138 and expression.is_type(exp.DataType.Type.VARCHAR) 1139 and not expression.expressions 1140 ): 1141 # `VARCHAR` must always have a size - if it doesn't, we always generate `TEXT` 1142 return "TEXT" 1143 1144 # https://dev.mysql.com/doc/refman/8.0/en/numeric-type-syntax.html 1145 result = super().datatype_sql(expression) 1146 if expression.this in self.UNSIGNED_TYPE_MAPPING: 1147 result = f"{result} UNSIGNED" 1148 1149 return result 1150 1151 def jsonarraycontains_sql(self, expression: exp.JSONArrayContains) -> str: 1152 return f"{self.sql(expression, 'this')} MEMBER OF({self.sql(expression, 'expression')})" 1153 1154 def cast_sql(self, expression: exp.Cast, safe_prefix: t.Optional[str] = None) -> str: 1155 if expression.to.this in self.TIMESTAMP_FUNC_TYPES: 1156 return self.func("TIMESTAMP", expression.this) 1157 1158 to = self.CAST_MAPPING.get(expression.to.this) 1159 1160 if to: 1161 expression.to.set("this", to) 1162 return super().cast_sql(expression) 1163 1164 def show_sql(self, expression: exp.Show) -> str: 1165 this = f" {expression.name}" 1166 full = " FULL" if expression.args.get("full") else "" 1167 global_ = " GLOBAL" if expression.args.get("global") else "" 1168 1169 target = self.sql(expression, "target") 1170 target = f" {target}" if target else "" 1171 if expression.name in ("COLUMNS", "INDEX"): 1172 target = f" FROM{target}" 1173 elif expression.name == "GRANTS": 1174 target = f" FOR{target}" 1175 1176 db = self._prefixed_sql("FROM", expression, "db") 1177 1178 like = self._prefixed_sql("LIKE", expression, "like") 1179 where = self.sql(expression, "where") 1180 1181 types = self.expressions(expression, key="types") 1182 types = f" {types}" if types else types 1183 query = self._prefixed_sql("FOR QUERY", expression, "query") 1184 1185 if expression.name == "PROFILE": 1186 offset = self._prefixed_sql("OFFSET", expression, "offset") 1187 limit = self._prefixed_sql("LIMIT", expression, "limit") 1188 else: 1189 offset = "" 1190 limit = self._oldstyle_limit_sql(expression) 1191 1192 log = self._prefixed_sql("IN", expression, "log") 1193 position = self._prefixed_sql("FROM", expression, "position") 1194 1195 channel = self._prefixed_sql("FOR CHANNEL", expression, "channel") 1196 1197 if expression.name == "ENGINE": 1198 mutex_or_status = " MUTEX" if expression.args.get("mutex") else " STATUS" 1199 else: 1200 mutex_or_status = "" 1201 1202 return f"SHOW{full}{global_}{this}{target}{types}{db}{query}{log}{position}{channel}{mutex_or_status}{like}{where}{offset}{limit}" 1203 1204 def altercolumn_sql(self, expression: exp.AlterColumn) -> str: 1205 dtype = self.sql(expression, "dtype") 1206 if not dtype: 1207 return super().altercolumn_sql(expression) 1208 1209 this = self.sql(expression, "this") 1210 return f"MODIFY COLUMN {this} {dtype}" 1211 1212 def _prefixed_sql(self, prefix: str, expression: exp.Expression, arg: str) -> str: 1213 sql = self.sql(expression, arg) 1214 return f" {prefix} {sql}" if sql else "" 1215 1216 def _oldstyle_limit_sql(self, expression: exp.Show) -> str: 1217 limit = self.sql(expression, "limit") 1218 offset = self.sql(expression, "offset") 1219 if limit: 1220 limit_offset = f"{offset}, {limit}" if offset else limit 1221 return f" LIMIT {limit_offset}" 1222 return "" 1223 1224 def chr_sql(self, expression: exp.Chr) -> str: 1225 this = self.expressions(sqls=[expression.this] + expression.expressions) 1226 charset = expression.args.get("charset") 1227 using = f" USING {self.sql(charset)}" if charset else "" 1228 return f"CHAR({this}{using})" 1229 1230 def timestamptrunc_sql(self, expression: exp.TimestampTrunc) -> str: 1231 unit = expression.args.get("unit") 1232 1233 # Pick an old-enough date to avoid negative timestamp diffs 1234 start_ts = "'0000-01-01 00:00:00'" 1235 1236 # Source: https://stackoverflow.com/a/32955740 1237 timestamp_diff = build_date_delta(exp.TimestampDiff)([unit, start_ts, expression.this]) 1238 interval = exp.Interval(this=timestamp_diff, unit=unit) 1239 dateadd = build_date_delta_with_interval(exp.DateAdd)([start_ts, interval]) 1240 1241 return self.sql(dateadd) 1242 1243 def converttimezone_sql(self, expression: exp.ConvertTimezone) -> str: 1244 from_tz = expression.args.get("source_tz") 1245 to_tz = expression.args.get("target_tz") 1246 dt = expression.args.get("timestamp") 1247 1248 return self.func("CONVERT_TZ", dt, from_tz, to_tz) 1249 1250 def attimezone_sql(self, expression: exp.AtTimeZone) -> str: 1251 self.unsupported("AT TIME ZONE is not supported by MySQL") 1252 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.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.TagColumnConstraint'>: <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.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.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.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.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.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 =
{'dense_rank', 'mod', 'release', 'read_write', 'sqlwarning', 'key', 'hour_second', 'continue', 'generated', 'row', 'double', 'separator', 'binary', 'io_before_gtids', 'convert', 'each', 'to', 'current_timestamp', 'localtime', 'longtext', 'unique', 'float8', 'databases', 'leave', 'by', 'match', 'sqlstate', 'constraint', 'join', 'interval', 'call', 'both', 'div', 'option', 'longblob', 'int4', 'precision', 'add', 'tinyint', 'in', 'read', 'check', 'ssl', 'varbinary', 'sqlexception', 'desc', 'foreign', 'cascade', 'varcharacter', 'hour_microsecond', 'rlike', 'analyze', 'false', 'show', 'as', 'column', 'optimize', 'set', 'intersect', 'describe', 'replace', 'blob', 'integer', 'tinyblob', 'lag', 'int', 'limit', 'asc', 'change', 'ntile', 'primary', 'unlock', 'spatial', 'ignore', 'alter', 'range', 'lead', 'natural', 'select', 'exists', 'partition', 'int2', 'localtimestamp', 'escaped', 'inner', 'schema', 'fulltext', 'and', 'second_microsecond', 'database', 'union', 'smallint', 'undo', 'default', 'use', 'asensitive', 'elseif', 'zerofill', 'into', 'outfile', 'repeat', 'hour_minute', 'distinctrow', 'current_date', 'mediumblob', 'mediumint', 'cursor', 'resignal', 'true', 'function', 'long', 'linear', 'kill', 'outer', 'low_priority', 'force', 'having', 'leading', 'float', 'day_hour', 'insensitive', 'except', 'lock', 'schemas', 'out', 'character', 'group', 'specific', 'optionally', 'then', 'purge', 'accessible', 'sql_calc_found_rows', 'all', 'terminated', 'revoke', 'int8', 'lines', 'rows', 'percent_rank', 'decimal', 'utc_time', 'last_value', 'order', 'of', 'restrict', 'condition', 'grouping', 'year_month', 'current_user', 'collate', 'straight_join', 'sql_big_result', 'is', 'int1', 'usage', 'while', 'before', 'deterministic', 'table', 'reads', 'varying', 'day_second', 'enclosed', 'day_microsecond', 'modifies', 'trailing', 'high_priority', 'drop', 'first_value', 'rename', 'fetch', 'optimizer_costs', 'sensitive', 'where', 'lateral', 'recursive', 'current_time', 'int3', 'when', 'window', 'delayed', 'xor', 'real', 'loop', 'char', 'insert', 'declare', 'between', 'sql', 'with', 'master_ssl_verify_server_cert', 'utc_timestamp', 'virtual', 'write', 'get', 'regexp', 'master_bind', 'for', 'from', 'minute_microsecond', 'delete', 'maxvalue', 'mediumtext', 'dual', 'nth_value', 'day_minute', 'groups', 'json_table', 'null', 'unsigned', 'cube', 'over', 'references', 'like', 'left', 'float4', 'io_after_gtids', 'row_number', 'starting', 'load', 'distinct', 'explain', 'numeric', 'return', 'cume_dist', 'sql_small_result', 'empty', 'update', 'cross', 'bigint', 'system', 'else', 'exit', 'trigger', 'minute_second', 'rank', 'right', 'tinytext', 'values', 'signal', 'on', 'dec', 'iterate', 'grant', 'procedure', 'inout', 'keys', 'case', 'middleint', 'using', 'stored', 'or', 'index', 'varchar', 'no_write_to_binlog', 'if', 'create', 'not', 'utc_date', 'infile', 'require'}
1135 def datatype_sql(self, expression: exp.DataType) -> str: 1136 if ( 1137 self.VARCHAR_REQUIRES_SIZE 1138 and expression.is_type(exp.DataType.Type.VARCHAR) 1139 and not expression.expressions 1140 ): 1141 # `VARCHAR` must always have a size - if it doesn't, we always generate `TEXT` 1142 return "TEXT" 1143 1144 # https://dev.mysql.com/doc/refman/8.0/en/numeric-type-syntax.html 1145 result = super().datatype_sql(expression) 1146 if expression.this in self.UNSIGNED_TYPE_MAPPING: 1147 result = f"{result} UNSIGNED" 1148 1149 return result
def
cast_sql( self, expression: sqlglot.expressions.Cast, safe_prefix: Optional[str] = None) -> str:
1154 def cast_sql(self, expression: exp.Cast, safe_prefix: t.Optional[str] = None) -> str: 1155 if expression.to.this in self.TIMESTAMP_FUNC_TYPES: 1156 return self.func("TIMESTAMP", expression.this) 1157 1158 to = self.CAST_MAPPING.get(expression.to.this) 1159 1160 if to: 1161 expression.to.set("this", to) 1162 return super().cast_sql(expression)
1164 def show_sql(self, expression: exp.Show) -> str: 1165 this = f" {expression.name}" 1166 full = " FULL" if expression.args.get("full") else "" 1167 global_ = " GLOBAL" if expression.args.get("global") else "" 1168 1169 target = self.sql(expression, "target") 1170 target = f" {target}" if target else "" 1171 if expression.name in ("COLUMNS", "INDEX"): 1172 target = f" FROM{target}" 1173 elif expression.name == "GRANTS": 1174 target = f" FOR{target}" 1175 1176 db = self._prefixed_sql("FROM", expression, "db") 1177 1178 like = self._prefixed_sql("LIKE", expression, "like") 1179 where = self.sql(expression, "where") 1180 1181 types = self.expressions(expression, key="types") 1182 types = f" {types}" if types else types 1183 query = self._prefixed_sql("FOR QUERY", expression, "query") 1184 1185 if expression.name == "PROFILE": 1186 offset = self._prefixed_sql("OFFSET", expression, "offset") 1187 limit = self._prefixed_sql("LIMIT", expression, "limit") 1188 else: 1189 offset = "" 1190 limit = self._oldstyle_limit_sql(expression) 1191 1192 log = self._prefixed_sql("IN", expression, "log") 1193 position = self._prefixed_sql("FROM", expression, "position") 1194 1195 channel = self._prefixed_sql("FOR CHANNEL", expression, "channel") 1196 1197 if expression.name == "ENGINE": 1198 mutex_or_status = " MUTEX" if expression.args.get("mutex") else " STATUS" 1199 else: 1200 mutex_or_status = "" 1201 1202 return f"SHOW{full}{global_}{this}{target}{types}{db}{query}{log}{position}{channel}{mutex_or_status}{like}{where}{offset}{limit}"
1230 def timestamptrunc_sql(self, expression: exp.TimestampTrunc) -> str: 1231 unit = expression.args.get("unit") 1232 1233 # Pick an old-enough date to avoid negative timestamp diffs 1234 start_ts = "'0000-01-01 00:00:00'" 1235 1236 # Source: https://stackoverflow.com/a/32955740 1237 timestamp_diff = build_date_delta(exp.TimestampDiff)([unit, start_ts, expression.this]) 1238 interval = exp.Interval(this=timestamp_diff, unit=unit) 1239 dateadd = build_date_delta_with_interval(exp.DateAdd)([start_ts, interval]) 1240 1241 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
- TIME_PART_SINGULARS
- TOKEN_MAPPING
- STRUCT_DELIMITER
- PARAMETER_TOKEN
- NAMED_PLACEHOLDER_TOKEN
- 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
- 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