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