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