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_json_value(self) -> exp.JSONValue: 713 this = self._parse_bitwise() 714 self._match(TokenType.COMMA) 715 path = self._parse_bitwise() 716 717 returning = self._match(TokenType.RETURNING) and self._parse_type() 718 719 return self.expression( 720 exp.JSONValue, 721 this=this, 722 path=self.dialect.to_json_path(path), 723 returning=returning, 724 on_condition=self._parse_on_condition(), 725 ) 726 727 def _parse_alter_table_alter_index(self) -> exp.AlterIndex: 728 index = self._parse_field(any_token=True) 729 730 if self._match_text_seq("VISIBLE"): 731 visible = True 732 elif self._match_text_seq("INVISIBLE"): 733 visible = False 734 else: 735 visible = None 736 737 return self.expression(exp.AlterIndex, this=index, visible=visible) 738 739 class Generator(generator.Generator): 740 INTERVAL_ALLOWS_PLURAL_FORM = False 741 LOCKING_READS_SUPPORTED = True 742 NULL_ORDERING_SUPPORTED = None 743 JOIN_HINTS = False 744 TABLE_HINTS = True 745 DUPLICATE_KEY_UPDATE_WITH_SET = False 746 QUERY_HINT_SEP = " " 747 VALUES_AS_TABLE = False 748 NVL2_SUPPORTED = False 749 LAST_DAY_SUPPORTS_DATE_PART = False 750 JSON_TYPE_REQUIRED_FOR_EXTRACTION = True 751 JSON_PATH_BRACKETED_KEY_SUPPORTED = False 752 JSON_KEY_VALUE_PAIR_SEP = "," 753 SUPPORTS_TO_NUMBER = False 754 PARSE_JSON_NAME: t.Optional[str] = None 755 PAD_FILL_PATTERN_IS_REQUIRED = True 756 WRAP_DERIVED_VALUES = False 757 VARCHAR_REQUIRES_SIZE = True 758 SUPPORTS_MEDIAN = False 759 760 TRANSFORMS = { 761 **generator.Generator.TRANSFORMS, 762 exp.ArrayAgg: rename_func("GROUP_CONCAT"), 763 exp.CurrentDate: no_paren_current_date_sql, 764 exp.DateDiff: _remove_ts_or_ds_to_date( 765 lambda self, e: self.func("DATEDIFF", e.this, e.expression), ("this", "expression") 766 ), 767 exp.DateAdd: _remove_ts_or_ds_to_date(date_add_sql("ADD")), 768 exp.DateStrToDate: datestrtodate_sql, 769 exp.DateSub: _remove_ts_or_ds_to_date(date_add_sql("SUB")), 770 exp.DateTrunc: _date_trunc_sql, 771 exp.Day: _remove_ts_or_ds_to_date(), 772 exp.DayOfMonth: _remove_ts_or_ds_to_date(rename_func("DAYOFMONTH")), 773 exp.DayOfWeek: _remove_ts_or_ds_to_date(rename_func("DAYOFWEEK")), 774 exp.DayOfYear: _remove_ts_or_ds_to_date(rename_func("DAYOFYEAR")), 775 exp.GroupConcat: lambda self, 776 e: f"""GROUP_CONCAT({self.sql(e, "this")} SEPARATOR {self.sql(e, "separator") or "','"})""", 777 exp.ILike: no_ilike_sql, 778 exp.JSONExtractScalar: arrow_json_extract_sql, 779 exp.Length: length_or_char_length_sql, 780 exp.LogicalOr: rename_func("MAX"), 781 exp.LogicalAnd: rename_func("MIN"), 782 exp.Max: max_or_greatest, 783 exp.Min: min_or_least, 784 exp.Month: _remove_ts_or_ds_to_date(), 785 exp.NullSafeEQ: lambda self, e: self.binary(e, "<=>"), 786 exp.NullSafeNEQ: lambda self, e: f"NOT {self.binary(e, '<=>')}", 787 exp.NumberToStr: rename_func("FORMAT"), 788 exp.Pivot: no_pivot_sql, 789 exp.Select: transforms.preprocess( 790 [ 791 transforms.eliminate_distinct_on, 792 transforms.eliminate_semi_and_anti_joins, 793 transforms.eliminate_qualify, 794 transforms.eliminate_full_outer_join, 795 transforms.unnest_generate_date_array_using_recursive_cte, 796 ] 797 ), 798 exp.StrPosition: lambda self, e: strposition_sql( 799 self, e, func_name="LOCATE", supports_position=True 800 ), 801 exp.StrToDate: _str_to_date_sql, 802 exp.StrToTime: _str_to_date_sql, 803 exp.Stuff: rename_func("INSERT"), 804 exp.TableSample: no_tablesample_sql, 805 exp.TimeFromParts: rename_func("MAKETIME"), 806 exp.TimestampAdd: date_add_interval_sql("DATE", "ADD"), 807 exp.TimestampDiff: lambda self, e: self.func( 808 "TIMESTAMPDIFF", unit_to_var(e), e.expression, e.this 809 ), 810 exp.TimestampSub: date_add_interval_sql("DATE", "SUB"), 811 exp.TimeStrToUnix: rename_func("UNIX_TIMESTAMP"), 812 exp.TimeStrToTime: lambda self, e: timestrtotime_sql( 813 self, 814 e, 815 include_precision=not e.args.get("zone"), 816 ), 817 exp.TimeToStr: _remove_ts_or_ds_to_date( 818 lambda self, e: self.func("DATE_FORMAT", e.this, self.format_time(e)) 819 ), 820 exp.Trim: trim_sql, 821 exp.TryCast: no_trycast_sql, 822 exp.TsOrDsAdd: date_add_sql("ADD"), 823 exp.TsOrDsDiff: lambda self, e: self.func("DATEDIFF", e.this, e.expression), 824 exp.TsOrDsToDate: _ts_or_ds_to_date_sql, 825 exp.Unicode: lambda self, e: f"ORD(CONVERT({self.sql(e.this)} USING utf32))", 826 exp.UnixToTime: _unix_to_time_sql, 827 exp.Week: _remove_ts_or_ds_to_date(), 828 exp.WeekOfYear: _remove_ts_or_ds_to_date(rename_func("WEEKOFYEAR")), 829 exp.Year: _remove_ts_or_ds_to_date(), 830 } 831 832 UNSIGNED_TYPE_MAPPING = { 833 exp.DataType.Type.UBIGINT: "BIGINT", 834 exp.DataType.Type.UINT: "INT", 835 exp.DataType.Type.UMEDIUMINT: "MEDIUMINT", 836 exp.DataType.Type.USMALLINT: "SMALLINT", 837 exp.DataType.Type.UTINYINT: "TINYINT", 838 exp.DataType.Type.UDECIMAL: "DECIMAL", 839 exp.DataType.Type.UDOUBLE: "DOUBLE", 840 } 841 842 TIMESTAMP_TYPE_MAPPING = { 843 exp.DataType.Type.DATETIME2: "DATETIME", 844 exp.DataType.Type.SMALLDATETIME: "DATETIME", 845 exp.DataType.Type.TIMESTAMP: "DATETIME", 846 exp.DataType.Type.TIMESTAMPNTZ: "DATETIME", 847 exp.DataType.Type.TIMESTAMPTZ: "TIMESTAMP", 848 exp.DataType.Type.TIMESTAMPLTZ: "TIMESTAMP", 849 } 850 851 TYPE_MAPPING = { 852 **generator.Generator.TYPE_MAPPING, 853 **UNSIGNED_TYPE_MAPPING, 854 **TIMESTAMP_TYPE_MAPPING, 855 } 856 857 TYPE_MAPPING.pop(exp.DataType.Type.MEDIUMTEXT) 858 TYPE_MAPPING.pop(exp.DataType.Type.LONGTEXT) 859 TYPE_MAPPING.pop(exp.DataType.Type.TINYTEXT) 860 TYPE_MAPPING.pop(exp.DataType.Type.BLOB) 861 TYPE_MAPPING.pop(exp.DataType.Type.MEDIUMBLOB) 862 TYPE_MAPPING.pop(exp.DataType.Type.LONGBLOB) 863 TYPE_MAPPING.pop(exp.DataType.Type.TINYBLOB) 864 865 PROPERTIES_LOCATION = { 866 **generator.Generator.PROPERTIES_LOCATION, 867 exp.TransientProperty: exp.Properties.Location.UNSUPPORTED, 868 exp.VolatileProperty: exp.Properties.Location.UNSUPPORTED, 869 } 870 871 LIMIT_FETCH = "LIMIT" 872 873 LIMIT_ONLY_LITERALS = True 874 875 CHAR_CAST_MAPPING = dict.fromkeys( 876 ( 877 exp.DataType.Type.LONGTEXT, 878 exp.DataType.Type.LONGBLOB, 879 exp.DataType.Type.MEDIUMBLOB, 880 exp.DataType.Type.MEDIUMTEXT, 881 exp.DataType.Type.TEXT, 882 exp.DataType.Type.TINYBLOB, 883 exp.DataType.Type.TINYTEXT, 884 exp.DataType.Type.VARCHAR, 885 ), 886 "CHAR", 887 ) 888 SIGNED_CAST_MAPPING = dict.fromkeys( 889 ( 890 exp.DataType.Type.BIGINT, 891 exp.DataType.Type.BOOLEAN, 892 exp.DataType.Type.INT, 893 exp.DataType.Type.SMALLINT, 894 exp.DataType.Type.TINYINT, 895 exp.DataType.Type.MEDIUMINT, 896 ), 897 "SIGNED", 898 ) 899 900 # MySQL doesn't support many datatypes in cast. 901 # https://dev.mysql.com/doc/refman/8.0/en/cast-functions.html#function_cast 902 CAST_MAPPING = { 903 **CHAR_CAST_MAPPING, 904 **SIGNED_CAST_MAPPING, 905 exp.DataType.Type.UBIGINT: "UNSIGNED", 906 } 907 908 TIMESTAMP_FUNC_TYPES = { 909 exp.DataType.Type.TIMESTAMPTZ, 910 exp.DataType.Type.TIMESTAMPLTZ, 911 } 912 913 # https://dev.mysql.com/doc/refman/8.0/en/keywords.html 914 RESERVED_KEYWORDS = { 915 "accessible", 916 "add", 917 "all", 918 "alter", 919 "analyze", 920 "and", 921 "as", 922 "asc", 923 "asensitive", 924 "before", 925 "between", 926 "bigint", 927 "binary", 928 "blob", 929 "both", 930 "by", 931 "call", 932 "cascade", 933 "case", 934 "change", 935 "char", 936 "character", 937 "check", 938 "collate", 939 "column", 940 "condition", 941 "constraint", 942 "continue", 943 "convert", 944 "create", 945 "cross", 946 "cube", 947 "cume_dist", 948 "current_date", 949 "current_time", 950 "current_timestamp", 951 "current_user", 952 "cursor", 953 "database", 954 "databases", 955 "day_hour", 956 "day_microsecond", 957 "day_minute", 958 "day_second", 959 "dec", 960 "decimal", 961 "declare", 962 "default", 963 "delayed", 964 "delete", 965 "dense_rank", 966 "desc", 967 "describe", 968 "deterministic", 969 "distinct", 970 "distinctrow", 971 "div", 972 "double", 973 "drop", 974 "dual", 975 "each", 976 "else", 977 "elseif", 978 "empty", 979 "enclosed", 980 "escaped", 981 "except", 982 "exists", 983 "exit", 984 "explain", 985 "false", 986 "fetch", 987 "first_value", 988 "float", 989 "float4", 990 "float8", 991 "for", 992 "force", 993 "foreign", 994 "from", 995 "fulltext", 996 "function", 997 "generated", 998 "get", 999 "grant", 1000 "group", 1001 "grouping", 1002 "groups", 1003 "having", 1004 "high_priority", 1005 "hour_microsecond", 1006 "hour_minute", 1007 "hour_second", 1008 "if", 1009 "ignore", 1010 "in", 1011 "index", 1012 "infile", 1013 "inner", 1014 "inout", 1015 "insensitive", 1016 "insert", 1017 "int", 1018 "int1", 1019 "int2", 1020 "int3", 1021 "int4", 1022 "int8", 1023 "integer", 1024 "intersect", 1025 "interval", 1026 "into", 1027 "io_after_gtids", 1028 "io_before_gtids", 1029 "is", 1030 "iterate", 1031 "join", 1032 "json_table", 1033 "key", 1034 "keys", 1035 "kill", 1036 "lag", 1037 "last_value", 1038 "lateral", 1039 "lead", 1040 "leading", 1041 "leave", 1042 "left", 1043 "like", 1044 "limit", 1045 "linear", 1046 "lines", 1047 "load", 1048 "localtime", 1049 "localtimestamp", 1050 "lock", 1051 "long", 1052 "longblob", 1053 "longtext", 1054 "loop", 1055 "low_priority", 1056 "master_bind", 1057 "master_ssl_verify_server_cert", 1058 "match", 1059 "maxvalue", 1060 "mediumblob", 1061 "mediumint", 1062 "mediumtext", 1063 "middleint", 1064 "minute_microsecond", 1065 "minute_second", 1066 "mod", 1067 "modifies", 1068 "natural", 1069 "not", 1070 "no_write_to_binlog", 1071 "nth_value", 1072 "ntile", 1073 "null", 1074 "numeric", 1075 "of", 1076 "on", 1077 "optimize", 1078 "optimizer_costs", 1079 "option", 1080 "optionally", 1081 "or", 1082 "order", 1083 "out", 1084 "outer", 1085 "outfile", 1086 "over", 1087 "partition", 1088 "percent_rank", 1089 "precision", 1090 "primary", 1091 "procedure", 1092 "purge", 1093 "range", 1094 "rank", 1095 "read", 1096 "reads", 1097 "read_write", 1098 "real", 1099 "recursive", 1100 "references", 1101 "regexp", 1102 "release", 1103 "rename", 1104 "repeat", 1105 "replace", 1106 "require", 1107 "resignal", 1108 "restrict", 1109 "return", 1110 "revoke", 1111 "right", 1112 "rlike", 1113 "row", 1114 "rows", 1115 "row_number", 1116 "schema", 1117 "schemas", 1118 "second_microsecond", 1119 "select", 1120 "sensitive", 1121 "separator", 1122 "set", 1123 "show", 1124 "signal", 1125 "smallint", 1126 "spatial", 1127 "specific", 1128 "sql", 1129 "sqlexception", 1130 "sqlstate", 1131 "sqlwarning", 1132 "sql_big_result", 1133 "sql_calc_found_rows", 1134 "sql_small_result", 1135 "ssl", 1136 "starting", 1137 "stored", 1138 "straight_join", 1139 "system", 1140 "table", 1141 "terminated", 1142 "then", 1143 "tinyblob", 1144 "tinyint", 1145 "tinytext", 1146 "to", 1147 "trailing", 1148 "trigger", 1149 "true", 1150 "undo", 1151 "union", 1152 "unique", 1153 "unlock", 1154 "unsigned", 1155 "update", 1156 "usage", 1157 "use", 1158 "using", 1159 "utc_date", 1160 "utc_time", 1161 "utc_timestamp", 1162 "values", 1163 "varbinary", 1164 "varchar", 1165 "varcharacter", 1166 "varying", 1167 "virtual", 1168 "when", 1169 "where", 1170 "while", 1171 "window", 1172 "with", 1173 "write", 1174 "xor", 1175 "year_month", 1176 "zerofill", 1177 } 1178 1179 def computedcolumnconstraint_sql(self, expression: exp.ComputedColumnConstraint) -> str: 1180 persisted = "STORED" if expression.args.get("persisted") else "VIRTUAL" 1181 return f"GENERATED ALWAYS AS ({self.sql(expression.this.unnest())}) {persisted}" 1182 1183 def array_sql(self, expression: exp.Array) -> str: 1184 self.unsupported("Arrays are not supported by MySQL") 1185 return self.function_fallback_sql(expression) 1186 1187 def arraycontainsall_sql(self, expression: exp.ArrayContainsAll) -> str: 1188 self.unsupported("Array operations are not supported by MySQL") 1189 return self.function_fallback_sql(expression) 1190 1191 def dpipe_sql(self, expression: exp.DPipe) -> str: 1192 return self.func("CONCAT", *expression.flatten()) 1193 1194 def extract_sql(self, expression: exp.Extract) -> str: 1195 unit = expression.name 1196 if unit and unit.lower() == "epoch": 1197 return self.func("UNIX_TIMESTAMP", expression.expression) 1198 1199 return super().extract_sql(expression) 1200 1201 def datatype_sql(self, expression: exp.DataType) -> str: 1202 if ( 1203 self.VARCHAR_REQUIRES_SIZE 1204 and expression.is_type(exp.DataType.Type.VARCHAR) 1205 and not expression.expressions 1206 ): 1207 # `VARCHAR` must always have a size - if it doesn't, we always generate `TEXT` 1208 return "TEXT" 1209 1210 # https://dev.mysql.com/doc/refman/8.0/en/numeric-type-syntax.html 1211 result = super().datatype_sql(expression) 1212 if expression.this in self.UNSIGNED_TYPE_MAPPING: 1213 result = f"{result} UNSIGNED" 1214 1215 return result 1216 1217 def jsonarraycontains_sql(self, expression: exp.JSONArrayContains) -> str: 1218 return f"{self.sql(expression, 'this')} MEMBER OF({self.sql(expression, 'expression')})" 1219 1220 def cast_sql(self, expression: exp.Cast, safe_prefix: t.Optional[str] = None) -> str: 1221 if expression.to.this in self.TIMESTAMP_FUNC_TYPES: 1222 return self.func("TIMESTAMP", expression.this) 1223 1224 to = self.CAST_MAPPING.get(expression.to.this) 1225 1226 if to: 1227 expression.to.set("this", to) 1228 return super().cast_sql(expression) 1229 1230 def show_sql(self, expression: exp.Show) -> str: 1231 this = f" {expression.name}" 1232 full = " FULL" if expression.args.get("full") else "" 1233 global_ = " GLOBAL" if expression.args.get("global") else "" 1234 1235 target = self.sql(expression, "target") 1236 target = f" {target}" if target else "" 1237 if expression.name in ("COLUMNS", "INDEX"): 1238 target = f" FROM{target}" 1239 elif expression.name == "GRANTS": 1240 target = f" FOR{target}" 1241 1242 db = self._prefixed_sql("FROM", expression, "db") 1243 1244 like = self._prefixed_sql("LIKE", expression, "like") 1245 where = self.sql(expression, "where") 1246 1247 types = self.expressions(expression, key="types") 1248 types = f" {types}" if types else types 1249 query = self._prefixed_sql("FOR QUERY", expression, "query") 1250 1251 if expression.name == "PROFILE": 1252 offset = self._prefixed_sql("OFFSET", expression, "offset") 1253 limit = self._prefixed_sql("LIMIT", expression, "limit") 1254 else: 1255 offset = "" 1256 limit = self._oldstyle_limit_sql(expression) 1257 1258 log = self._prefixed_sql("IN", expression, "log") 1259 position = self._prefixed_sql("FROM", expression, "position") 1260 1261 channel = self._prefixed_sql("FOR CHANNEL", expression, "channel") 1262 1263 if expression.name == "ENGINE": 1264 mutex_or_status = " MUTEX" if expression.args.get("mutex") else " STATUS" 1265 else: 1266 mutex_or_status = "" 1267 1268 return f"SHOW{full}{global_}{this}{target}{types}{db}{query}{log}{position}{channel}{mutex_or_status}{like}{where}{offset}{limit}" 1269 1270 def altercolumn_sql(self, expression: exp.AlterColumn) -> str: 1271 dtype = self.sql(expression, "dtype") 1272 if not dtype: 1273 return super().altercolumn_sql(expression) 1274 1275 this = self.sql(expression, "this") 1276 return f"MODIFY COLUMN {this} {dtype}" 1277 1278 def _prefixed_sql(self, prefix: str, expression: exp.Expression, arg: str) -> str: 1279 sql = self.sql(expression, arg) 1280 return f" {prefix} {sql}" if sql else "" 1281 1282 def _oldstyle_limit_sql(self, expression: exp.Show) -> str: 1283 limit = self.sql(expression, "limit") 1284 offset = self.sql(expression, "offset") 1285 if limit: 1286 limit_offset = f"{offset}, {limit}" if offset else limit 1287 return f" LIMIT {limit_offset}" 1288 return "" 1289 1290 def chr_sql(self, expression: exp.Chr) -> str: 1291 this = self.expressions(sqls=[expression.this] + expression.expressions) 1292 charset = expression.args.get("charset") 1293 using = f" USING {self.sql(charset)}" if charset else "" 1294 return f"CHAR({this}{using})" 1295 1296 def timestamptrunc_sql(self, expression: exp.TimestampTrunc) -> str: 1297 unit = expression.args.get("unit") 1298 1299 # Pick an old-enough date to avoid negative timestamp diffs 1300 start_ts = "'0000-01-01 00:00:00'" 1301 1302 # Source: https://stackoverflow.com/a/32955740 1303 timestamp_diff = build_date_delta(exp.TimestampDiff)([unit, start_ts, expression.this]) 1304 interval = exp.Interval(this=timestamp_diff, unit=unit) 1305 dateadd = build_date_delta_with_interval(exp.DateAdd)([start_ts, interval]) 1306 1307 return self.sql(dateadd) 1308 1309 def converttimezone_sql(self, expression: exp.ConvertTimezone) -> str: 1310 from_tz = expression.args.get("source_tz") 1311 to_tz = expression.args.get("target_tz") 1312 dt = expression.args.get("timestamp") 1313 1314 return self.func("CONVERT_TZ", dt, from_tz, to_tz) 1315 1316 def attimezone_sql(self, expression: exp.AtTimeZone) -> str: 1317 self.unsupported("AT TIME ZONE is not supported by MySQL") 1318 return self.sql(expression.this) 1319 1320 def isascii_sql(self, expression: exp.IsAscii) -> str: 1321 return f"REGEXP_LIKE({self.sql(expression.this)}, '^[[:ascii:]]*$')" 1322 1323 @unsupported_args("this") 1324 def currentschema_sql(self, expression: exp.CurrentSchema) -> str: 1325 return self.func("SCHEMA")
TIME_SPECIFIERS =
{'I', 'H', 'k', 'h', 'r', 'T', 'f', 'i', 'S', 'p', 's', 'l'}
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_json_value(self) -> exp.JSONValue: 714 this = self._parse_bitwise() 715 self._match(TokenType.COMMA) 716 path = self._parse_bitwise() 717 718 returning = self._match(TokenType.RETURNING) and self._parse_type() 719 720 return self.expression( 721 exp.JSONValue, 722 this=this, 723 path=self.dialect.to_json_path(path), 724 returning=returning, 725 on_condition=self._parse_on_condition(), 726 ) 727 728 def _parse_alter_table_alter_index(self) -> exp.AlterIndex: 729 index = self._parse_field(any_token=True) 730 731 if self._match_text_seq("VISIBLE"): 732 visible = True 733 elif self._match_text_seq("INVISIBLE"): 734 visible = False 735 else: 736 visible = None 737 738 return self.expression(exp.AlterIndex, this=index, visible=visible) 739 740 class Generator(generator.Generator): 741 INTERVAL_ALLOWS_PLURAL_FORM = False 742 LOCKING_READS_SUPPORTED = True 743 NULL_ORDERING_SUPPORTED = None 744 JOIN_HINTS = False 745 TABLE_HINTS = True 746 DUPLICATE_KEY_UPDATE_WITH_SET = False 747 QUERY_HINT_SEP = " " 748 VALUES_AS_TABLE = False 749 NVL2_SUPPORTED = False 750 LAST_DAY_SUPPORTS_DATE_PART = False 751 JSON_TYPE_REQUIRED_FOR_EXTRACTION = True 752 JSON_PATH_BRACKETED_KEY_SUPPORTED = False 753 JSON_KEY_VALUE_PAIR_SEP = "," 754 SUPPORTS_TO_NUMBER = False 755 PARSE_JSON_NAME: t.Optional[str] = None 756 PAD_FILL_PATTERN_IS_REQUIRED = True 757 WRAP_DERIVED_VALUES = False 758 VARCHAR_REQUIRES_SIZE = True 759 SUPPORTS_MEDIAN = False 760 761 TRANSFORMS = { 762 **generator.Generator.TRANSFORMS, 763 exp.ArrayAgg: rename_func("GROUP_CONCAT"), 764 exp.CurrentDate: no_paren_current_date_sql, 765 exp.DateDiff: _remove_ts_or_ds_to_date( 766 lambda self, e: self.func("DATEDIFF", e.this, e.expression), ("this", "expression") 767 ), 768 exp.DateAdd: _remove_ts_or_ds_to_date(date_add_sql("ADD")), 769 exp.DateStrToDate: datestrtodate_sql, 770 exp.DateSub: _remove_ts_or_ds_to_date(date_add_sql("SUB")), 771 exp.DateTrunc: _date_trunc_sql, 772 exp.Day: _remove_ts_or_ds_to_date(), 773 exp.DayOfMonth: _remove_ts_or_ds_to_date(rename_func("DAYOFMONTH")), 774 exp.DayOfWeek: _remove_ts_or_ds_to_date(rename_func("DAYOFWEEK")), 775 exp.DayOfYear: _remove_ts_or_ds_to_date(rename_func("DAYOFYEAR")), 776 exp.GroupConcat: lambda self, 777 e: f"""GROUP_CONCAT({self.sql(e, "this")} SEPARATOR {self.sql(e, "separator") or "','"})""", 778 exp.ILike: no_ilike_sql, 779 exp.JSONExtractScalar: arrow_json_extract_sql, 780 exp.Length: length_or_char_length_sql, 781 exp.LogicalOr: rename_func("MAX"), 782 exp.LogicalAnd: rename_func("MIN"), 783 exp.Max: max_or_greatest, 784 exp.Min: min_or_least, 785 exp.Month: _remove_ts_or_ds_to_date(), 786 exp.NullSafeEQ: lambda self, e: self.binary(e, "<=>"), 787 exp.NullSafeNEQ: lambda self, e: f"NOT {self.binary(e, '<=>')}", 788 exp.NumberToStr: rename_func("FORMAT"), 789 exp.Pivot: no_pivot_sql, 790 exp.Select: transforms.preprocess( 791 [ 792 transforms.eliminate_distinct_on, 793 transforms.eliminate_semi_and_anti_joins, 794 transforms.eliminate_qualify, 795 transforms.eliminate_full_outer_join, 796 transforms.unnest_generate_date_array_using_recursive_cte, 797 ] 798 ), 799 exp.StrPosition: lambda self, e: strposition_sql( 800 self, e, func_name="LOCATE", supports_position=True 801 ), 802 exp.StrToDate: _str_to_date_sql, 803 exp.StrToTime: _str_to_date_sql, 804 exp.Stuff: rename_func("INSERT"), 805 exp.TableSample: no_tablesample_sql, 806 exp.TimeFromParts: rename_func("MAKETIME"), 807 exp.TimestampAdd: date_add_interval_sql("DATE", "ADD"), 808 exp.TimestampDiff: lambda self, e: self.func( 809 "TIMESTAMPDIFF", unit_to_var(e), e.expression, e.this 810 ), 811 exp.TimestampSub: date_add_interval_sql("DATE", "SUB"), 812 exp.TimeStrToUnix: rename_func("UNIX_TIMESTAMP"), 813 exp.TimeStrToTime: lambda self, e: timestrtotime_sql( 814 self, 815 e, 816 include_precision=not e.args.get("zone"), 817 ), 818 exp.TimeToStr: _remove_ts_or_ds_to_date( 819 lambda self, e: self.func("DATE_FORMAT", e.this, self.format_time(e)) 820 ), 821 exp.Trim: trim_sql, 822 exp.TryCast: no_trycast_sql, 823 exp.TsOrDsAdd: date_add_sql("ADD"), 824 exp.TsOrDsDiff: lambda self, e: self.func("DATEDIFF", e.this, e.expression), 825 exp.TsOrDsToDate: _ts_or_ds_to_date_sql, 826 exp.Unicode: lambda self, e: f"ORD(CONVERT({self.sql(e.this)} USING utf32))", 827 exp.UnixToTime: _unix_to_time_sql, 828 exp.Week: _remove_ts_or_ds_to_date(), 829 exp.WeekOfYear: _remove_ts_or_ds_to_date(rename_func("WEEKOFYEAR")), 830 exp.Year: _remove_ts_or_ds_to_date(), 831 } 832 833 UNSIGNED_TYPE_MAPPING = { 834 exp.DataType.Type.UBIGINT: "BIGINT", 835 exp.DataType.Type.UINT: "INT", 836 exp.DataType.Type.UMEDIUMINT: "MEDIUMINT", 837 exp.DataType.Type.USMALLINT: "SMALLINT", 838 exp.DataType.Type.UTINYINT: "TINYINT", 839 exp.DataType.Type.UDECIMAL: "DECIMAL", 840 exp.DataType.Type.UDOUBLE: "DOUBLE", 841 } 842 843 TIMESTAMP_TYPE_MAPPING = { 844 exp.DataType.Type.DATETIME2: "DATETIME", 845 exp.DataType.Type.SMALLDATETIME: "DATETIME", 846 exp.DataType.Type.TIMESTAMP: "DATETIME", 847 exp.DataType.Type.TIMESTAMPNTZ: "DATETIME", 848 exp.DataType.Type.TIMESTAMPTZ: "TIMESTAMP", 849 exp.DataType.Type.TIMESTAMPLTZ: "TIMESTAMP", 850 } 851 852 TYPE_MAPPING = { 853 **generator.Generator.TYPE_MAPPING, 854 **UNSIGNED_TYPE_MAPPING, 855 **TIMESTAMP_TYPE_MAPPING, 856 } 857 858 TYPE_MAPPING.pop(exp.DataType.Type.MEDIUMTEXT) 859 TYPE_MAPPING.pop(exp.DataType.Type.LONGTEXT) 860 TYPE_MAPPING.pop(exp.DataType.Type.TINYTEXT) 861 TYPE_MAPPING.pop(exp.DataType.Type.BLOB) 862 TYPE_MAPPING.pop(exp.DataType.Type.MEDIUMBLOB) 863 TYPE_MAPPING.pop(exp.DataType.Type.LONGBLOB) 864 TYPE_MAPPING.pop(exp.DataType.Type.TINYBLOB) 865 866 PROPERTIES_LOCATION = { 867 **generator.Generator.PROPERTIES_LOCATION, 868 exp.TransientProperty: exp.Properties.Location.UNSUPPORTED, 869 exp.VolatileProperty: exp.Properties.Location.UNSUPPORTED, 870 } 871 872 LIMIT_FETCH = "LIMIT" 873 874 LIMIT_ONLY_LITERALS = True 875 876 CHAR_CAST_MAPPING = dict.fromkeys( 877 ( 878 exp.DataType.Type.LONGTEXT, 879 exp.DataType.Type.LONGBLOB, 880 exp.DataType.Type.MEDIUMBLOB, 881 exp.DataType.Type.MEDIUMTEXT, 882 exp.DataType.Type.TEXT, 883 exp.DataType.Type.TINYBLOB, 884 exp.DataType.Type.TINYTEXT, 885 exp.DataType.Type.VARCHAR, 886 ), 887 "CHAR", 888 ) 889 SIGNED_CAST_MAPPING = dict.fromkeys( 890 ( 891 exp.DataType.Type.BIGINT, 892 exp.DataType.Type.BOOLEAN, 893 exp.DataType.Type.INT, 894 exp.DataType.Type.SMALLINT, 895 exp.DataType.Type.TINYINT, 896 exp.DataType.Type.MEDIUMINT, 897 ), 898 "SIGNED", 899 ) 900 901 # MySQL doesn't support many datatypes in cast. 902 # https://dev.mysql.com/doc/refman/8.0/en/cast-functions.html#function_cast 903 CAST_MAPPING = { 904 **CHAR_CAST_MAPPING, 905 **SIGNED_CAST_MAPPING, 906 exp.DataType.Type.UBIGINT: "UNSIGNED", 907 } 908 909 TIMESTAMP_FUNC_TYPES = { 910 exp.DataType.Type.TIMESTAMPTZ, 911 exp.DataType.Type.TIMESTAMPLTZ, 912 } 913 914 # https://dev.mysql.com/doc/refman/8.0/en/keywords.html 915 RESERVED_KEYWORDS = { 916 "accessible", 917 "add", 918 "all", 919 "alter", 920 "analyze", 921 "and", 922 "as", 923 "asc", 924 "asensitive", 925 "before", 926 "between", 927 "bigint", 928 "binary", 929 "blob", 930 "both", 931 "by", 932 "call", 933 "cascade", 934 "case", 935 "change", 936 "char", 937 "character", 938 "check", 939 "collate", 940 "column", 941 "condition", 942 "constraint", 943 "continue", 944 "convert", 945 "create", 946 "cross", 947 "cube", 948 "cume_dist", 949 "current_date", 950 "current_time", 951 "current_timestamp", 952 "current_user", 953 "cursor", 954 "database", 955 "databases", 956 "day_hour", 957 "day_microsecond", 958 "day_minute", 959 "day_second", 960 "dec", 961 "decimal", 962 "declare", 963 "default", 964 "delayed", 965 "delete", 966 "dense_rank", 967 "desc", 968 "describe", 969 "deterministic", 970 "distinct", 971 "distinctrow", 972 "div", 973 "double", 974 "drop", 975 "dual", 976 "each", 977 "else", 978 "elseif", 979 "empty", 980 "enclosed", 981 "escaped", 982 "except", 983 "exists", 984 "exit", 985 "explain", 986 "false", 987 "fetch", 988 "first_value", 989 "float", 990 "float4", 991 "float8", 992 "for", 993 "force", 994 "foreign", 995 "from", 996 "fulltext", 997 "function", 998 "generated", 999 "get", 1000 "grant", 1001 "group", 1002 "grouping", 1003 "groups", 1004 "having", 1005 "high_priority", 1006 "hour_microsecond", 1007 "hour_minute", 1008 "hour_second", 1009 "if", 1010 "ignore", 1011 "in", 1012 "index", 1013 "infile", 1014 "inner", 1015 "inout", 1016 "insensitive", 1017 "insert", 1018 "int", 1019 "int1", 1020 "int2", 1021 "int3", 1022 "int4", 1023 "int8", 1024 "integer", 1025 "intersect", 1026 "interval", 1027 "into", 1028 "io_after_gtids", 1029 "io_before_gtids", 1030 "is", 1031 "iterate", 1032 "join", 1033 "json_table", 1034 "key", 1035 "keys", 1036 "kill", 1037 "lag", 1038 "last_value", 1039 "lateral", 1040 "lead", 1041 "leading", 1042 "leave", 1043 "left", 1044 "like", 1045 "limit", 1046 "linear", 1047 "lines", 1048 "load", 1049 "localtime", 1050 "localtimestamp", 1051 "lock", 1052 "long", 1053 "longblob", 1054 "longtext", 1055 "loop", 1056 "low_priority", 1057 "master_bind", 1058 "master_ssl_verify_server_cert", 1059 "match", 1060 "maxvalue", 1061 "mediumblob", 1062 "mediumint", 1063 "mediumtext", 1064 "middleint", 1065 "minute_microsecond", 1066 "minute_second", 1067 "mod", 1068 "modifies", 1069 "natural", 1070 "not", 1071 "no_write_to_binlog", 1072 "nth_value", 1073 "ntile", 1074 "null", 1075 "numeric", 1076 "of", 1077 "on", 1078 "optimize", 1079 "optimizer_costs", 1080 "option", 1081 "optionally", 1082 "or", 1083 "order", 1084 "out", 1085 "outer", 1086 "outfile", 1087 "over", 1088 "partition", 1089 "percent_rank", 1090 "precision", 1091 "primary", 1092 "procedure", 1093 "purge", 1094 "range", 1095 "rank", 1096 "read", 1097 "reads", 1098 "read_write", 1099 "real", 1100 "recursive", 1101 "references", 1102 "regexp", 1103 "release", 1104 "rename", 1105 "repeat", 1106 "replace", 1107 "require", 1108 "resignal", 1109 "restrict", 1110 "return", 1111 "revoke", 1112 "right", 1113 "rlike", 1114 "row", 1115 "rows", 1116 "row_number", 1117 "schema", 1118 "schemas", 1119 "second_microsecond", 1120 "select", 1121 "sensitive", 1122 "separator", 1123 "set", 1124 "show", 1125 "signal", 1126 "smallint", 1127 "spatial", 1128 "specific", 1129 "sql", 1130 "sqlexception", 1131 "sqlstate", 1132 "sqlwarning", 1133 "sql_big_result", 1134 "sql_calc_found_rows", 1135 "sql_small_result", 1136 "ssl", 1137 "starting", 1138 "stored", 1139 "straight_join", 1140 "system", 1141 "table", 1142 "terminated", 1143 "then", 1144 "tinyblob", 1145 "tinyint", 1146 "tinytext", 1147 "to", 1148 "trailing", 1149 "trigger", 1150 "true", 1151 "undo", 1152 "union", 1153 "unique", 1154 "unlock", 1155 "unsigned", 1156 "update", 1157 "usage", 1158 "use", 1159 "using", 1160 "utc_date", 1161 "utc_time", 1162 "utc_timestamp", 1163 "values", 1164 "varbinary", 1165 "varchar", 1166 "varcharacter", 1167 "varying", 1168 "virtual", 1169 "when", 1170 "where", 1171 "while", 1172 "window", 1173 "with", 1174 "write", 1175 "xor", 1176 "year_month", 1177 "zerofill", 1178 } 1179 1180 def computedcolumnconstraint_sql(self, expression: exp.ComputedColumnConstraint) -> str: 1181 persisted = "STORED" if expression.args.get("persisted") else "VIRTUAL" 1182 return f"GENERATED ALWAYS AS ({self.sql(expression.this.unnest())}) {persisted}" 1183 1184 def array_sql(self, expression: exp.Array) -> str: 1185 self.unsupported("Arrays are not supported by MySQL") 1186 return self.function_fallback_sql(expression) 1187 1188 def arraycontainsall_sql(self, expression: exp.ArrayContainsAll) -> str: 1189 self.unsupported("Array operations are not supported by MySQL") 1190 return self.function_fallback_sql(expression) 1191 1192 def dpipe_sql(self, expression: exp.DPipe) -> str: 1193 return self.func("CONCAT", *expression.flatten()) 1194 1195 def extract_sql(self, expression: exp.Extract) -> str: 1196 unit = expression.name 1197 if unit and unit.lower() == "epoch": 1198 return self.func("UNIX_TIMESTAMP", expression.expression) 1199 1200 return super().extract_sql(expression) 1201 1202 def datatype_sql(self, expression: exp.DataType) -> str: 1203 if ( 1204 self.VARCHAR_REQUIRES_SIZE 1205 and expression.is_type(exp.DataType.Type.VARCHAR) 1206 and not expression.expressions 1207 ): 1208 # `VARCHAR` must always have a size - if it doesn't, we always generate `TEXT` 1209 return "TEXT" 1210 1211 # https://dev.mysql.com/doc/refman/8.0/en/numeric-type-syntax.html 1212 result = super().datatype_sql(expression) 1213 if expression.this in self.UNSIGNED_TYPE_MAPPING: 1214 result = f"{result} UNSIGNED" 1215 1216 return result 1217 1218 def jsonarraycontains_sql(self, expression: exp.JSONArrayContains) -> str: 1219 return f"{self.sql(expression, 'this')} MEMBER OF({self.sql(expression, 'expression')})" 1220 1221 def cast_sql(self, expression: exp.Cast, safe_prefix: t.Optional[str] = None) -> str: 1222 if expression.to.this in self.TIMESTAMP_FUNC_TYPES: 1223 return self.func("TIMESTAMP", expression.this) 1224 1225 to = self.CAST_MAPPING.get(expression.to.this) 1226 1227 if to: 1228 expression.to.set("this", to) 1229 return super().cast_sql(expression) 1230 1231 def show_sql(self, expression: exp.Show) -> str: 1232 this = f" {expression.name}" 1233 full = " FULL" if expression.args.get("full") else "" 1234 global_ = " GLOBAL" if expression.args.get("global") else "" 1235 1236 target = self.sql(expression, "target") 1237 target = f" {target}" if target else "" 1238 if expression.name in ("COLUMNS", "INDEX"): 1239 target = f" FROM{target}" 1240 elif expression.name == "GRANTS": 1241 target = f" FOR{target}" 1242 1243 db = self._prefixed_sql("FROM", expression, "db") 1244 1245 like = self._prefixed_sql("LIKE", expression, "like") 1246 where = self.sql(expression, "where") 1247 1248 types = self.expressions(expression, key="types") 1249 types = f" {types}" if types else types 1250 query = self._prefixed_sql("FOR QUERY", expression, "query") 1251 1252 if expression.name == "PROFILE": 1253 offset = self._prefixed_sql("OFFSET", expression, "offset") 1254 limit = self._prefixed_sql("LIMIT", expression, "limit") 1255 else: 1256 offset = "" 1257 limit = self._oldstyle_limit_sql(expression) 1258 1259 log = self._prefixed_sql("IN", expression, "log") 1260 position = self._prefixed_sql("FROM", expression, "position") 1261 1262 channel = self._prefixed_sql("FOR CHANNEL", expression, "channel") 1263 1264 if expression.name == "ENGINE": 1265 mutex_or_status = " MUTEX" if expression.args.get("mutex") else " STATUS" 1266 else: 1267 mutex_or_status = "" 1268 1269 return f"SHOW{full}{global_}{this}{target}{types}{db}{query}{log}{position}{channel}{mutex_or_status}{like}{where}{offset}{limit}" 1270 1271 def altercolumn_sql(self, expression: exp.AlterColumn) -> str: 1272 dtype = self.sql(expression, "dtype") 1273 if not dtype: 1274 return super().altercolumn_sql(expression) 1275 1276 this = self.sql(expression, "this") 1277 return f"MODIFY COLUMN {this} {dtype}" 1278 1279 def _prefixed_sql(self, prefix: str, expression: exp.Expression, arg: str) -> str: 1280 sql = self.sql(expression, arg) 1281 return f" {prefix} {sql}" if sql else "" 1282 1283 def _oldstyle_limit_sql(self, expression: exp.Show) -> str: 1284 limit = self.sql(expression, "limit") 1285 offset = self.sql(expression, "offset") 1286 if limit: 1287 limit_offset = f"{offset}, {limit}" if offset else limit 1288 return f" LIMIT {limit_offset}" 1289 return "" 1290 1291 def chr_sql(self, expression: exp.Chr) -> str: 1292 this = self.expressions(sqls=[expression.this] + expression.expressions) 1293 charset = expression.args.get("charset") 1294 using = f" USING {self.sql(charset)}" if charset else "" 1295 return f"CHAR({this}{using})" 1296 1297 def timestamptrunc_sql(self, expression: exp.TimestampTrunc) -> str: 1298 unit = expression.args.get("unit") 1299 1300 # Pick an old-enough date to avoid negative timestamp diffs 1301 start_ts = "'0000-01-01 00:00:00'" 1302 1303 # Source: https://stackoverflow.com/a/32955740 1304 timestamp_diff = build_date_delta(exp.TimestampDiff)([unit, start_ts, expression.this]) 1305 interval = exp.Interval(this=timestamp_diff, unit=unit) 1306 dateadd = build_date_delta_with_interval(exp.DateAdd)([start_ts, interval]) 1307 1308 return self.sql(dateadd) 1309 1310 def converttimezone_sql(self, expression: exp.ConvertTimezone) -> str: 1311 from_tz = expression.args.get("source_tz") 1312 to_tz = expression.args.get("target_tz") 1313 dt = expression.args.get("timestamp") 1314 1315 return self.func("CONVERT_TZ", dt, from_tz, to_tz) 1316 1317 def attimezone_sql(self, expression: exp.AtTimeZone) -> str: 1318 self.unsupported("AT TIME ZONE is not supported by MySQL") 1319 return self.sql(expression.this) 1320 1321 def isascii_sql(self, expression: exp.IsAscii) -> str: 1322 return f"REGEXP_LIKE({self.sql(expression.this)}, '^[[:ascii:]]*$')" 1323 1324 @unsupported_args("this") 1325 def currentschema_sql(self, expression: exp.CurrentSchema) -> str: 1326 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.COMMAND: 'COMMAND'>, <TokenType.RENAME: 'RENAME'>, <TokenType.FETCH: 'FETCH'>, <TokenType.REPLACE: 'REPLACE'>, <TokenType.EXECUTE: 'EXECUTE'>}
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_json_value(self) -> exp.JSONValue: 714 this = self._parse_bitwise() 715 self._match(TokenType.COMMA) 716 path = self._parse_bitwise() 717 718 returning = self._match(TokenType.RETURNING) and self._parse_type() 719 720 return self.expression( 721 exp.JSONValue, 722 this=this, 723 path=self.dialect.to_json_path(path), 724 returning=returning, 725 on_condition=self._parse_on_condition(), 726 ) 727 728 def _parse_alter_table_alter_index(self) -> exp.AlterIndex: 729 index = self._parse_field(any_token=True) 730 731 if self._match_text_seq("VISIBLE"): 732 visible = True 733 elif self._match_text_seq("INVISIBLE"): 734 visible = False 735 else: 736 visible = None 737 738 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.COMMAND: 'COMMAND'>, <TokenType.ENUM: 'ENUM'>, <TokenType.FILTER: 'FILTER'>, <TokenType.XOR: 'XOR'>, <TokenType.UINT: 'UINT'>, <TokenType.LEFT: 'LEFT'>, <TokenType.FLOAT: 'FLOAT'>, <TokenType.RIGHT: 'RIGHT'>, <TokenType.LOWCARDINALITY: 'LOWCARDINALITY'>, <TokenType.BIGDECIMAL: 'BIGDECIMAL'>, <TokenType.BIGSERIAL: 'BIGSERIAL'>, <TokenType.STRUCT: 'STRUCT'>, <TokenType.NCHAR: 'NCHAR'>, <TokenType.IPPREFIX: 'IPPREFIX'>, <TokenType.UNNEST: 'UNNEST'>, <TokenType.INT128: 'INT128'>, <TokenType.INT256: 'INT256'>, <TokenType.XML: 'XML'>, <TokenType.ARRAY: 'ARRAY'>, <TokenType.REPLACE: 'REPLACE'>, <TokenType.YEAR: 'YEAR'>, <TokenType.USERDEFINED: 'USERDEFINED'>, <TokenType.JSONB: 'JSONB'>, <TokenType.CURRENT_TIME: 'CURRENT_TIME'>, <TokenType.FIRST: 'FIRST'>, <TokenType.DATEMULTIRANGE: 'DATEMULTIRANGE'>, <TokenType.DATERANGE: 'DATERANGE'>, <TokenType.GEOMETRY: 'GEOMETRY'>, <TokenType.LIST: 'LIST'>, <TokenType.SMALLSERIAL: 'SMALLSERIAL'>, <TokenType.DATETIME2: 'DATETIME2'>, <TokenType.DECIMAL256: 'DECIMAL256'>, <TokenType.DECIMAL32: 'DECIMAL32'>, <TokenType.ANY: 'ANY'>, <TokenType.UINT256: 'UINT256'>, <TokenType.IPV4: 'IPV4'>, <TokenType.GET: 'GET'>, <TokenType.ENUM16: 'ENUM16'>, <TokenType.TINYTEXT: 'TINYTEXT'>, <TokenType.INT8RANGE: 'INT8RANGE'>, <TokenType.VECTOR: 'VECTOR'>, <TokenType.ISNULL: 'ISNULL'>, <TokenType.TSMULTIRANGE: 'TSMULTIRANGE'>, <TokenType.ILIKE: 'ILIKE'>, <TokenType.OBJECT_IDENTIFIER: 'OBJECT_IDENTIFIER'>, <TokenType.LONGBLOB: 'LONGBLOB'>, <TokenType.NVARCHAR: 'NVARCHAR'>, <TokenType.UDECIMAL: 'UDECIMAL'>, <TokenType.OBJECT: 'OBJECT'>, <TokenType.CHAR: 'CHAR'>, <TokenType.CURRENT_TIMESTAMP: 'CURRENT_TIMESTAMP'>, <TokenType.POINT: 'POINT'>, <TokenType.IPV6: 'IPV6'>, <TokenType.TIMESTAMPNTZ: 'TIMESTAMPNTZ'>, <TokenType.DYNAMIC: 'DYNAMIC'>, <TokenType.DATETIME: 'DATETIME'>, <TokenType.UBIGINT: 'UBIGINT'>, <TokenType.VALUES: 'VALUES'>, <TokenType.POLYGON: 'POLYGON'>, <TokenType.EXISTS: 'EXISTS'>, <TokenType.INDEX: 'INDEX'>, <TokenType.VAR: 'VAR'>, <TokenType.IMAGE: 'IMAGE'>, <TokenType.ROWVERSION: 'ROWVERSION'>, <TokenType.BOOLEAN: 'BOOLEAN'>, <TokenType.TSTZRANGE: 'TSTZRANGE'>, <TokenType.DECIMAL128: 'DECIMAL128'>, <TokenType.INTERVAL: 'INTERVAL'>, <TokenType.PSEUDO_TYPE: 'PSEUDO_TYPE'>, <TokenType.UUID: 'UUID'>, <TokenType.RANGE: 'RANGE'>, <TokenType.SCHEMA: 'SCHEMA'>, <TokenType.CURRENT_DATETIME: 'CURRENT_DATETIME'>, <TokenType.SERIAL: 'SERIAL'>, <TokenType.GEOGRAPHY: 'GEOGRAPHY'>, <TokenType.TIME: 'TIME'>, <TokenType.LIKE: 'LIKE'>, <TokenType.GEOGRAPHYPOINT: 'GEOGRAPHYPOINT'>, <TokenType.VOID: 'VOID'>, <TokenType.AGGREGATEFUNCTION: 'AGGREGATEFUNCTION'>, <TokenType.SMALLMONEY: 'SMALLMONEY'>, <TokenType.BIT: 'BIT'>, <TokenType.BPCHAR: 'BPCHAR'>, <TokenType.TIMESTAMP_S: 'TIMESTAMP_S'>, <TokenType.NESTED: 'NESTED'>, <TokenType.VARIANT: 'VARIANT'>, <TokenType.JSON: 'JSON'>, <TokenType.NEXT: 'NEXT'>, <TokenType.MONEY: 'MONEY'>, <TokenType.MEDIUMINT: 'MEDIUMINT'>, <TokenType.TIMESTAMP_NS: 'TIMESTAMP_NS'>, <TokenType.CURRENT_DATE: 'CURRENT_DATE'>, <TokenType.CURRENT_SCHEMA: 'CURRENT_SCHEMA'>, <TokenType.TSRANGE: 'TSRANGE'>, <TokenType.IDENTIFIER: 'IDENTIFIER'>, <TokenType.LONGTEXT: 'LONGTEXT'>, <TokenType.FIXEDSTRING: 'FIXEDSTRING'>, <TokenType.MULTILINESTRING: 'MULTILINESTRING'>, <TokenType.TIMESTAMP: 'TIMESTAMP'>, <TokenType.TIMESTAMPTZ: 'TIMESTAMPTZ'>, <TokenType.DECIMAL64: 'DECIMAL64'>, <TokenType.COLLATE: 'COLLATE'>, <TokenType.DATE32: 'DATE32'>, <TokenType.BINARY: 'BINARY'>, <TokenType.SUPER: 'SUPER'>, <TokenType.INT8MULTIRANGE: 'INT8MULTIRANGE'>, <TokenType.INSERT: 'INSERT'>, <TokenType.DOUBLE: 'DOUBLE'>, <TokenType.OFFSET: 'OFFSET'>, <TokenType.TINYBLOB: 'TINYBLOB'>, <TokenType.ALL: 'ALL'>, <TokenType.CURRENT_USER: 'CURRENT_USER'>, <TokenType.TRUNCATE: 'TRUNCATE'>, <TokenType.RING: 'RING'>, <TokenType.UMEDIUMINT: 'UMEDIUMINT'>, <TokenType.INET: 'INET'>, <TokenType.NUMRANGE: 'NUMRANGE'>, <TokenType.NUMMULTIRANGE: 'NUMMULTIRANGE'>, <TokenType.HSTORE: 'HSTORE'>, <TokenType.INT4MULTIRANGE: 'INT4MULTIRANGE'>, <TokenType.SMALLINT: 'SMALLINT'>, <TokenType.FORMAT: 'FORMAT'>, <TokenType.MULTIPOLYGON: 'MULTIPOLYGON'>, <TokenType.SIMPLEAGGREGATEFUNCTION: 'SIMPLEAGGREGATEFUNCTION'>, <TokenType.TEXT: 'TEXT'>, <TokenType.IPADDRESS: 'IPADDRESS'>, <TokenType.NOTHING: 'NOTHING'>, <TokenType.WINDOW: 'WINDOW'>, <TokenType.INT: 'INT'>, <TokenType.DATABASE: 'DATABASE'>, <TokenType.UDOUBLE: 'UDOUBLE'>, <TokenType.INT4RANGE: 'INT4RANGE'>, <TokenType.SMALLDATETIME: 'SMALLDATETIME'>, <TokenType.TINYINT: 'TINYINT'>, <TokenType.PRIMARY_KEY: 'PRIMARY_KEY'>, <TokenType.VARBINARY: 'VARBINARY'>, <TokenType.TIMETZ: 'TIMETZ'>, <TokenType.USMALLINT: 'USMALLINT'>, <TokenType.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, <TokenType.DATE: 'DATE'>, <TokenType.NULL: 'NULL'>, <TokenType.VARCHAR: 'VARCHAR'>, <TokenType.MEDIUMTEXT: 'MEDIUMTEXT'>, <TokenType.TIMESTAMP_MS: 'TIMESTAMP_MS'>, <TokenType.UTINYINT: 'UTINYINT'>, <TokenType.SOME: 'SOME'>, <TokenType.DECIMAL: 'DECIMAL'>, <TokenType.GLOB: 'GLOB'>, <TokenType.HLLSKETCH: 'HLLSKETCH'>, <TokenType.NULLABLE: 'NULLABLE'>, <TokenType.BLOB: 'BLOB'>, <TokenType.DATETIME64: 'DATETIME64'>, <TokenType.UNION: 'UNION'>, <TokenType.UNKNOWN: 'UNKNOWN'>, <TokenType.TDIGEST: 'TDIGEST'>, <TokenType.RLIKE: 'RLIKE'>, <TokenType.BIGINT: 'BIGINT'>, <TokenType.MEDIUMBLOB: 'MEDIUMBLOB'>, <TokenType.TABLE: 'TABLE'>, <TokenType.ENUM8: 'ENUM8'>, <TokenType.UINT128: 'UINT128'>, <TokenType.MERGE: 'MERGE'>, <TokenType.TSTZMULTIRANGE: 'TSTZMULTIRANGE'>, <TokenType.ROW: 'ROW'>, <TokenType.MAP: 'MAP'>, <TokenType.LINESTRING: 'LINESTRING'>, <TokenType.NAME: 'NAME'>, <TokenType.SEQUENCE: 'SEQUENCE'>}
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.COMMAND: 'COMMAND'>, <TokenType.ASC: 'ASC'>, <TokenType.PARTITION: 'PARTITION'>, <TokenType.FILTER: 'FILTER'>, <TokenType.ENUM: 'ENUM'>, <TokenType.UINT: 'UINT'>, <TokenType.FLOAT: 'FLOAT'>, <TokenType.LOWCARDINALITY: 'LOWCARDINALITY'>, <TokenType.BIGDECIMAL: 'BIGDECIMAL'>, <TokenType.BIGSERIAL: 'BIGSERIAL'>, <TokenType.STRUCT: 'STRUCT'>, <TokenType.NCHAR: 'NCHAR'>, <TokenType.IPPREFIX: 'IPPREFIX'>, <TokenType.UNNEST: 'UNNEST'>, <TokenType.INT128: 'INT128'>, <TokenType.INT256: 'INT256'>, <TokenType.XML: 'XML'>, <TokenType.ARRAY: 'ARRAY'>, <TokenType.REPLACE: 'REPLACE'>, <TokenType.YEAR: 'YEAR'>, <TokenType.USERDEFINED: 'USERDEFINED'>, <TokenType.SEMI: 'SEMI'>, <TokenType.JSONB: 'JSONB'>, <TokenType.CURRENT_TIME: 'CURRENT_TIME'>, <TokenType.ATTACH: 'ATTACH'>, <TokenType.FIRST: 'FIRST'>, <TokenType.SHOW: 'SHOW'>, <TokenType.DATEMULTIRANGE: 'DATEMULTIRANGE'>, <TokenType.DATERANGE: 'DATERANGE'>, <TokenType.GEOMETRY: 'GEOMETRY'>, <TokenType.LIST: 'LIST'>, <TokenType.RECURSIVE: 'RECURSIVE'>, <TokenType.SMALLSERIAL: 'SMALLSERIAL'>, <TokenType.DATETIME2: 'DATETIME2'>, <TokenType.ANY: 'ANY'>, <TokenType.DECIMAL256: 'DECIMAL256'>, <TokenType.DECIMAL32: 'DECIMAL32'>, <TokenType.PIVOT: 'PIVOT'>, <TokenType.UINT256: 'UINT256'>, <TokenType.IPV4: 'IPV4'>, <TokenType.GET: 'GET'>, <TokenType.ENUM16: 'ENUM16'>, <TokenType.SEQUENCE: 'SEQUENCE'>, <TokenType.TINYTEXT: 'TINYTEXT'>, <TokenType.INT8RANGE: 'INT8RANGE'>, <TokenType.VECTOR: 'VECTOR'>, <TokenType.ISNULL: 'ISNULL'>, <TokenType.COPY: 'COPY'>, <TokenType.TSMULTIRANGE: 'TSMULTIRANGE'>, <TokenType.OBJECT_IDENTIFIER: 'OBJECT_IDENTIFIER'>, <TokenType.END: 'END'>, <TokenType.LONGBLOB: 'LONGBLOB'>, <TokenType.NVARCHAR: 'NVARCHAR'>, <TokenType.UDECIMAL: 'UDECIMAL'>, <TokenType.OBJECT: 'OBJECT'>, <TokenType.KEEP: 'KEEP'>, <TokenType.CHAR: 'CHAR'>, <TokenType.POINT: 'POINT'>, <TokenType.STAGE: 'STAGE'>, <TokenType.VOLATILE: 'VOLATILE'>, <TokenType.BEGIN: 'BEGIN'>, <TokenType.PROCEDURE: 'PROCEDURE'>, <TokenType.IPV6: 'IPV6'>, <TokenType.TIMESTAMPNTZ: 'TIMESTAMPNTZ'>, <TokenType.FILE_FORMAT: 'FILE_FORMAT'>, <TokenType.DYNAMIC: 'DYNAMIC'>, <TokenType.DATETIME: 'DATETIME'>, <TokenType.DEFAULT: 'DEFAULT'>, <TokenType.DELETE: 'DELETE'>, <TokenType.DIV: 'DIV'>, <TokenType.UBIGINT: 'UBIGINT'>, <TokenType.WAREHOUSE: 'WAREHOUSE'>, <TokenType.POLYGON: 'POLYGON'>, <TokenType.EXISTS: 'EXISTS'>, <TokenType.INDEX: 'INDEX'>, <TokenType.PUT: 'PUT'>, <TokenType.VAR: 'VAR'>, <TokenType.IMAGE: 'IMAGE'>, <TokenType.TOP: 'TOP'>, <TokenType.FOREIGN_KEY: 'FOREIGN_KEY'>, <TokenType.SOURCE: 'SOURCE'>, <TokenType.ROWVERSION: 'ROWVERSION'>, <TokenType.BOOLEAN: 'BOOLEAN'>, <TokenType.TSTZRANGE: 'TSTZRANGE'>, <TokenType.DECIMAL128: 'DECIMAL128'>, <TokenType.INTERVAL: 'INTERVAL'>, <TokenType.PSEUDO_TYPE: 'PSEUDO_TYPE'>, <TokenType.SCHEMA: 'SCHEMA'>, <TokenType.RANGE: 'RANGE'>, <TokenType.UUID: 'UUID'>, <TokenType.CURRENT_DATETIME: 'CURRENT_DATETIME'>, <TokenType.IS: 'IS'>, <TokenType.SERIAL: 'SERIAL'>, <TokenType.GEOGRAPHY: 'GEOGRAPHY'>, <TokenType.OVERLAPS: 'OVERLAPS'>, <TokenType.UPDATE: 'UPDATE'>, <TokenType.TIME: 'TIME'>, <TokenType.FALSE: 'FALSE'>, <TokenType.GEOGRAPHYPOINT: 'GEOGRAPHYPOINT'>, <TokenType.VOID: 'VOID'>, <TokenType.AGGREGATEFUNCTION: 'AGGREGATEFUNCTION'>, <TokenType.ROLLUP: 'ROLLUP'>, <TokenType.EXECUTE: 'EXECUTE'>, <TokenType.SMALLMONEY: 'SMALLMONEY'>, <TokenType.STORAGE_INTEGRATION: 'STORAGE_INTEGRATION'>, <TokenType.TAG: 'TAG'>, <TokenType.BPCHAR: 'BPCHAR'>, <TokenType.EXPORT: 'EXPORT'>, <TokenType.BIT: 'BIT'>, <TokenType.TIMESTAMP_S: 'TIMESTAMP_S'>, <TokenType.NESTED: 'NESTED'>, <TokenType.VARIANT: 'VARIANT'>, <TokenType.JSON: 'JSON'>, <TokenType.NEXT: 'NEXT'>, <TokenType.MONEY: 'MONEY'>, <TokenType.MEDIUMINT: 'MEDIUMINT'>, <TokenType.SEMANTIC_VIEW: 'SEMANTIC_VIEW'>, <TokenType.TIMESTAMP_NS: 'TIMESTAMP_NS'>, <TokenType.CURRENT_DATE: 'CURRENT_DATE'>, <TokenType.CURRENT_SCHEMA: 'CURRENT_SCHEMA'>, <TokenType.TSRANGE: 'TSRANGE'>, <TokenType.IDENTIFIER: 'IDENTIFIER'>, <TokenType.OVERWRITE: 'OVERWRITE'>, <TokenType.LONGTEXT: 'LONGTEXT'>, <TokenType.TRUE: 'TRUE'>, <TokenType.FIXEDSTRING: 'FIXEDSTRING'>, <TokenType.CASE: 'CASE'>, <TokenType.MULTILINESTRING: 'MULTILINESTRING'>, <TokenType.TIMESTAMP: 'TIMESTAMP'>, <TokenType.TIMESTAMPTZ: 'TIMESTAMPTZ'>, <TokenType.DECIMAL64: 'DECIMAL64'>, <TokenType.COLLATE: 'COLLATE'>, <TokenType.FINAL: 'FINAL'>, <TokenType.DATE32: 'DATE32'>, <TokenType.BINARY: 'BINARY'>, <TokenType.SET: 'SET'>, <TokenType.SUPER: 'SUPER'>, <TokenType.TEMPORARY: 'TEMPORARY'>, <TokenType.INT8MULTIRANGE: 'INT8MULTIRANGE'>, <TokenType.ALL: 'ALL'>, <TokenType.DOUBLE: 'DOUBLE'>, <TokenType.OFFSET: 'OFFSET'>, <TokenType.TINYBLOB: 'TINYBLOB'>, <TokenType.LOAD: 'LOAD'>, <TokenType.CURRENT_USER: 'CURRENT_USER'>, <TokenType.TRUNCATE: 'TRUNCATE'>, <TokenType.RING: 'RING'>, <TokenType.NAMESPACE: 'NAMESPACE'>, <TokenType.UMEDIUMINT: 'UMEDIUMINT'>, <TokenType.INET: 'INET'>, <TokenType.UNIQUE: 'UNIQUE'>, <TokenType.NUMRANGE: 'NUMRANGE'>, <TokenType.MODEL: 'MODEL'>, <TokenType.NUMMULTIRANGE: 'NUMMULTIRANGE'>, <TokenType.HSTORE: 'HSTORE'>, <TokenType.INT4MULTIRANGE: 'INT4MULTIRANGE'>, <TokenType.AUTO_INCREMENT: 'AUTO_INCREMENT'>, <TokenType.SMALLINT: 'SMALLINT'>, <TokenType.FORMAT: 'FORMAT'>, <TokenType.MULTIPOLYGON: 'MULTIPOLYGON'>, <TokenType.COMMENT: 'COMMENT'>, <TokenType.SIMPLEAGGREGATEFUNCTION: 'SIMPLEAGGREGATEFUNCTION'>, <TokenType.FUNCTION: 'FUNCTION'>, <TokenType.TEXT: 'TEXT'>, <TokenType.IPADDRESS: 'IPADDRESS'>, <TokenType.ORDINALITY: 'ORDINALITY'>, <TokenType.NOTHING: 'NOTHING'>, <TokenType.CUBE: 'CUBE'>, <TokenType.DESCRIBE: 'DESCRIBE'>, <TokenType.COLUMN: 'COLUMN'>, <TokenType.DATABASE: 'DATABASE'>, <TokenType.INT: 'INT'>, <TokenType.UDOUBLE: 'UDOUBLE'>, <TokenType.SETTINGS: 'SETTINGS'>, <TokenType.REFERENCES: 'REFERENCES'>, <TokenType.INT4RANGE: 'INT4RANGE'>, <TokenType.ROWS: 'ROWS'>, <TokenType.UNPIVOT: 'UNPIVOT'>, <TokenType.SMALLDATETIME: 'SMALLDATETIME'>, <TokenType.DETACH: 'DETACH'>, <TokenType.TINYINT: 'TINYINT'>, <TokenType.KILL: 'KILL'>, <TokenType.DICTIONARY: 'DICTIONARY'>, <TokenType.VARBINARY: 'VARBINARY'>, <TokenType.TIMETZ: 'TIMETZ'>, <TokenType.USMALLINT: 'USMALLINT'>, <TokenType.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, <TokenType.DATE: 'DATE'>, <TokenType.NULL: 'NULL'>, <TokenType.VARCHAR: 'VARCHAR'>, <TokenType.VIEW: 'VIEW'>, <TokenType.CONSTRAINT: 'CONSTRAINT'>, <TokenType.MEDIUMTEXT: 'MEDIUMTEXT'>, <TokenType.TIMESTAMP_MS: 'TIMESTAMP_MS'>, <TokenType.SOME: 'SOME'>, <TokenType.UTINYINT: 'UTINYINT'>, <TokenType.DECIMAL: 'DECIMAL'>, <TokenType.CACHE: 'CACHE'>, <TokenType.PERCENT: 'PERCENT'>, <TokenType.OPERATOR: 'OPERATOR'>, <TokenType.DESC: 'DESC'>, <TokenType.STREAMLIT: 'STREAMLIT'>, <TokenType.COMMIT: 'COMMIT'>, <TokenType.HLLSKETCH: 'HLLSKETCH'>, <TokenType.NULLABLE: 'NULLABLE'>, <TokenType.BLOB: 'BLOB'>, <TokenType.DATETIME64: 'DATETIME64'>, <TokenType.ESCAPE: 'ESCAPE'>, <TokenType.ANTI: 'ANTI'>, <TokenType.UNKNOWN: 'UNKNOWN'>, <TokenType.TDIGEST: 'TDIGEST'>, <TokenType.BIGINT: 'BIGINT'>, <TokenType.SINK: 'SINK'>, <TokenType.MEDIUMBLOB: 'MEDIUMBLOB'>, <TokenType.PRAGMA: 'PRAGMA'>, <TokenType.TABLE: 'TABLE'>, <TokenType.ENUM8: 'ENUM8'>, <TokenType.REFRESH: 'REFRESH'>, <TokenType.RENAME: 'RENAME'>, <TokenType.MERGE: 'MERGE'>, <TokenType.UINT128: 'UINT128'>, <TokenType.TSTZMULTIRANGE: 'TSTZMULTIRANGE'>, <TokenType.ROW: 'ROW'>, <TokenType.MAP: 'MAP'>, <TokenType.LINESTRING: 'LINESTRING'>, <TokenType.LIMIT: 'LIMIT'>, <TokenType.NAME: 'NAME'>, <TokenType.CURRENT_TIMESTAMP: 'CURRENT_TIMESTAMP'>}
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'>>, 'CASE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Case'>>, 'CAST': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Cast'>>, 'CAST_TO_STR_TYPE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CastToStrType'>>, 'CBRT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Cbrt'>>, 'CEIL': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Ceil'>>, 'CEILING': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Ceil'>>, 'CHR': <function Parser.<lambda>>, 'CHAR': <function Parser.<lambda>>, 'COALESCE': <function build_coalesce>, 'IFNULL': <function build_coalesce>, 'NVL': <function build_coalesce>, 'COLLATE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Collate'>>, 'COLUMNS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Columns'>>, 'COMBINED_AGG_FUNC': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CombinedAggFunc'>>, 'COMBINED_PARAMETERIZED_AGG': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CombinedParameterizedAgg'>>, 'CONCAT': <function Parser.<lambda>>, 'CONCAT_WS': <function Parser.<lambda>>, 'CONNECT_BY_ROOT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ConnectByRoot'>>, 'CONTAINS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Contains'>>, 'CONVERT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Convert'>>, 'CONVERT_TIMEZONE': <function build_convert_timezone>, 'CONVERT_TO_CHARSET': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ConvertToCharset'>>, 'CORR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Corr'>>, 'COUNT': <function Parser.<lambda>>, 'COUNT_IF': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CountIf'>>, 'COUNTIF': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CountIf'>>, 'COVAR_POP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CovarPop'>>, 'COVAR_SAMP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CovarSamp'>>, 'CURRENT_DATE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CurrentDate'>>, 'CURRENT_DATETIME': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CurrentDatetime'>>, 'CURRENT_SCHEMA': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CurrentSchema'>>, 'CURRENT_TIME': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CurrentTime'>>, 'CURRENT_TIMESTAMP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CurrentTimestamp'>>, 'CURRENT_TIMESTAMP_L_T_Z': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CurrentTimestampLTZ'>>, 'CURRENT_USER': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CurrentUser'>>, 'DATE': <function MySQL.Parser.<lambda>>, 'DATE_ADD': <function build_date_delta_with_interval.<locals>._builder>, 'DATE_BIN': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DateBin'>>, 'DATEDIFF': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DateDiff'>>, 'DATE_DIFF': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DateDiff'>>, 'DATE_FROM_PARTS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DateFromParts'>>, 'DATEFROMPARTS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DateFromParts'>>, 'DATE_STR_TO_DATE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DateStrToDate'>>, 'DATE_SUB': <function build_date_delta_with_interval.<locals>._builder>, 'DATE_TO_DATE_STR': <function Parser.<lambda>>, 'DATE_TO_DI': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DateToDi'>>, 'DATE_TRUNC': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DateTrunc'>>, 'DATETIME': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Datetime'>>, 'DATETIME_ADD': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DatetimeAdd'>>, 'DATETIME_DIFF': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DatetimeDiff'>>, 'DATETIME_SUB': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DatetimeSub'>>, 'DATETIME_TRUNC': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DatetimeTrunc'>>, 'DAY': <function MySQL.Parser.<lambda>>, 'DAY_OF_MONTH': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DayOfMonth'>>, 'DAYOFMONTH': <function MySQL.Parser.<lambda>>, 'DAY_OF_WEEK': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DayOfWeek'>>, 'DAYOFWEEK': <function MySQL.Parser.<lambda>>, 'DAYOFWEEK_ISO': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DayOfWeekIso'>>, 'ISODOW': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DayOfWeekIso'>>, 'DAY_OF_YEAR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DayOfYear'>>, 'DAYOFYEAR': <function MySQL.Parser.<lambda>>, 'DECODE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Decode'>>, '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'>>, 'GREATEST': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Greatest'>>, 'GROUP_CONCAT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.GroupConcat'>>, 'HEX': <function build_hex>, 'HLL': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Hll'>>, 'IF': <bound method Func.from_arg_list of <class 'sqlglot.expressions.If'>>, 'IIF': <bound method Func.from_arg_list of <class 'sqlglot.expressions.If'>>, 'INITCAP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Initcap'>>, 'INLINE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Inline'>>, 'INT64': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Int64'>>, 'IS_ASCII': <bound method Func.from_arg_list of <class 'sqlglot.expressions.IsAscii'>>, 'IS_INF': <bound method Func.from_arg_list of <class 'sqlglot.expressions.IsInf'>>, 'ISINF': <bound method Func.from_arg_list of <class 'sqlglot.expressions.IsInf'>>, 'IS_NAN': <bound method Func.from_arg_list of <class 'sqlglot.expressions.IsNan'>>, 'ISNAN': <bound method Func.from_arg_list of <class 'sqlglot.expressions.IsNan'>>, 'J_S_O_N_ARRAY': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONArray'>>, 'J_S_O_N_ARRAY_AGG': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONArrayAgg'>>, 'JSON_ARRAY_CONTAINS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONArrayContains'>>, 'JSONB_CONTAINS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONBContains'>>, 'JSONB_EXISTS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONBExists'>>, 'JSONB_EXTRACT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONBExtract'>>, 'JSONB_EXTRACT_SCALAR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONBExtractScalar'>>, 'J_S_O_N_B_OBJECT_AGG': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONBObjectAgg'>>, 'J_S_O_N_CAST': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONCast'>>, 'J_S_O_N_EXISTS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONExists'>>, 'JSON_EXTRACT': <function build_extract_json_with_path.<locals>._builder>, 'JSON_EXTRACT_ARRAY': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONExtractArray'>>, 'JSON_EXTRACT_SCALAR': <function build_extract_json_with_path.<locals>._builder>, 'JSON_FORMAT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONFormat'>>, 'J_S_O_N_OBJECT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONObject'>>, 'J_S_O_N_OBJECT_AGG': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONObjectAgg'>>, 'J_S_O_N_TABLE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONTable'>>, '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'>>, 'LAG': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Lag'>>, 'LAST': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Last'>>, 'LAST_DAY': <bound method Func.from_arg_list of <class 'sqlglot.expressions.LastDay'>>, 'LAST_DAY_OF_MONTH': <bound method Func.from_arg_list of <class 'sqlglot.expressions.LastDay'>>, 'LAST_VALUE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.LastValue'>>, 'LEAD': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Lead'>>, 'LEAST': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Least'>>, 'LEFT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Left'>>, 'LENGTH': <function MySQL.Parser.<lambda>>, 'LEN': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Length'>>, 'CHAR_LENGTH': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Length'>>, 'CHARACTER_LENGTH': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Length'>>, 'LEVENSHTEIN': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Levenshtein'>>, 'LIST': <bound method Func.from_arg_list of <class 'sqlglot.expressions.List'>>, 'LN': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Ln'>>, 'LOG': <function build_logarithm>, 'LOGICAL_AND': <bound method Func.from_arg_list of <class 'sqlglot.expressions.LogicalAnd'>>, 'BOOL_AND': <bound method Func.from_arg_list of <class 'sqlglot.expressions.LogicalAnd'>>, 'BOOLAND_AGG': <bound method Func.from_arg_list of <class 'sqlglot.expressions.LogicalAnd'>>, 'LOGICAL_OR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.LogicalOr'>>, 'BOOL_OR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.LogicalOr'>>, 'BOOLOR_AGG': <bound method Func.from_arg_list of <class 'sqlglot.expressions.LogicalOr'>>, 'LOWER': <function build_lower>, 'LCASE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Lower'>>, 'LOWER_HEX': <bound method Func.from_arg_list of <class 'sqlglot.expressions.LowerHex'>>, 'MD5': <bound method Func.from_arg_list of <class 'sqlglot.expressions.MD5'>>, 'MD5_DIGEST': <bound method Func.from_arg_list of <class 'sqlglot.expressions.MD5Digest'>>, 'MAKE_INTERVAL': <bound method Func.from_arg_list of <class 'sqlglot.expressions.MakeInterval'>>, 'MAP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Map'>>, 'MAP_FROM_ENTRIES': <bound method Func.from_arg_list of <class 'sqlglot.expressions.MapFromEntries'>>, 'MATCH_AGAINST': <bound method Func.from_arg_list of <class 'sqlglot.expressions.MatchAgainst'>>, 'MAX': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Max'>>, 'MEDIAN': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Median'>>, 'MIN': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Min'>>, 'MONTH': <function MySQL.Parser.<lambda>>, 'MONTHS_BETWEEN': <bound method Func.from_arg_list of <class 'sqlglot.expressions.MonthsBetween'>>, 'NEXT_VALUE_FOR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.NextValueFor'>>, 'NORMALIZE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Normalize'>>, 'NTH_VALUE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.NthValue'>>, 'NULLIF': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Nullif'>>, 'NUMBER_TO_STR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.NumberToStr'>>, 'NVL2': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Nvl2'>>, 'OBJECT_INSERT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ObjectInsert'>>, 'OPEN_J_S_O_N': <bound method Func.from_arg_list of <class 'sqlglot.expressions.OpenJSON'>>, 'OR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Or'>>, 'OVERLAY': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Overlay'>>, 'PAD': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Pad'>>, 'PARAMETERIZED_AGG': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ParameterizedAgg'>>, 'PARSE_JSON': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ParseJSON'>>, 'JSON_PARSE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ParseJSON'>>, 'PERCENTILE_CONT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.PercentileCont'>>, 'PERCENTILE_DISC': <bound method Func.from_arg_list of <class 'sqlglot.expressions.PercentileDisc'>>, 'POSEXPLODE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Posexplode'>>, 'POSEXPLODE_OUTER': <bound method Func.from_arg_list of <class 'sqlglot.expressions.PosexplodeOuter'>>, 'POWER': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Pow'>>, 'POW': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Pow'>>, 'PREDICT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Predict'>>, 'QUANTILE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Quantile'>>, 'QUARTER': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Quarter'>>, 'RAND': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Rand'>>, 'RANDOM': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Rand'>>, 'RANDN': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Randn'>>, 'RANGE_N': <bound method Func.from_arg_list of <class 'sqlglot.expressions.RangeN'>>, 'READ_CSV': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ReadCSV'>>, 'REDUCE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Reduce'>>, 'REGEXP_EXTRACT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.RegexpExtract'>>, 'REGEXP_EXTRACT_ALL': <bound method Func.from_arg_list of <class 'sqlglot.expressions.RegexpExtractAll'>>, 'REGEXP_I_LIKE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.RegexpILike'>>, 'REGEXP_LIKE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.RegexpLike'>>, 'REGEXP_REPLACE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.RegexpReplace'>>, 'REGEXP_SPLIT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.RegexpSplit'>>, 'REPEAT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Repeat'>>, 'REPLACE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Replace'>>, 'RIGHT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Right'>>, 'ROUND': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Round'>>, 'ROW_NUMBER': <bound method Func.from_arg_list of <class 'sqlglot.expressions.RowNumber'>>, 'SHA': <bound method Func.from_arg_list of <class 'sqlglot.expressions.SHA'>>, 'SHA1': <bound method Func.from_arg_list of <class 'sqlglot.expressions.SHA'>>, 'SHA2': <bound method Func.from_arg_list of <class 'sqlglot.expressions.SHA2'>>, 'SAFE_DIVIDE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.SafeDivide'>>, 'SIGN': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Sign'>>, 'SIGNUM': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Sign'>>, 'SORT_ARRAY': <bound method Func.from_arg_list of <class 'sqlglot.expressions.SortArray'>>, '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'>>, '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_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 =
{'UNIQUE', 'KEY', 'FULLTEXT', 'BUCKET', 'CHECK', 'INDEX', 'LIKE', 'PERIOD', 'EXCLUDE', 'TRUNCATE', 'WATERMARK', 'PRIMARY KEY', 'SPATIAL', 'FOREIGN KEY'}
PROFILE_TYPES: Dict[str, Sequence[Union[Sequence[str], str]]] =
{'ALL': (), 'CPU': (), 'IPC': (), 'MEMORY': (), 'SOURCE': (), 'SWAPS': (), 'BLOCK': ('IO',), 'CONTEXT': ('SWITCHES',), 'PAGE': ('FAULTS',)}
TYPE_TOKENS =
{<TokenType.MULTILINESTRING: 'MULTILINESTRING'>, <TokenType.TIMESTAMP: 'TIMESTAMP'>, <TokenType.TIMESTAMPTZ: 'TIMESTAMPTZ'>, <TokenType.DECIMAL64: 'DECIMAL64'>, <TokenType.ENUM: 'ENUM'>, <TokenType.UINT: 'UINT'>, <TokenType.FLOAT: 'FLOAT'>, <TokenType.DATE32: 'DATE32'>, <TokenType.LOWCARDINALITY: 'LOWCARDINALITY'>, <TokenType.BINARY: 'BINARY'>, <TokenType.BIGDECIMAL: 'BIGDECIMAL'>, <TokenType.BIGSERIAL: 'BIGSERIAL'>, <TokenType.STRUCT: 'STRUCT'>, <TokenType.SUPER: 'SUPER'>, <TokenType.INT8MULTIRANGE: 'INT8MULTIRANGE'>, <TokenType.SET: 'SET'>, <TokenType.NCHAR: 'NCHAR'>, <TokenType.IPPREFIX: 'IPPREFIX'>, <TokenType.INT128: 'INT128'>, <TokenType.DOUBLE: 'DOUBLE'>, <TokenType.TINYBLOB: 'TINYBLOB'>, <TokenType.INT256: 'INT256'>, <TokenType.XML: 'XML'>, <TokenType.ARRAY: 'ARRAY'>, <TokenType.RING: 'RING'>, <TokenType.UMEDIUMINT: 'UMEDIUMINT'>, <TokenType.YEAR: 'YEAR'>, <TokenType.INET: 'INET'>, <TokenType.USERDEFINED: 'USERDEFINED'>, <TokenType.JSONB: 'JSONB'>, <TokenType.NUMRANGE: 'NUMRANGE'>, <TokenType.NUMMULTIRANGE: 'NUMMULTIRANGE'>, <TokenType.HSTORE: 'HSTORE'>, <TokenType.INT4MULTIRANGE: 'INT4MULTIRANGE'>, <TokenType.DATEMULTIRANGE: 'DATEMULTIRANGE'>, <TokenType.DATERANGE: 'DATERANGE'>, <TokenType.GEOMETRY: 'GEOMETRY'>, <TokenType.LIST: 'LIST'>, <TokenType.SMALLINT: 'SMALLINT'>, <TokenType.SMALLSERIAL: 'SMALLSERIAL'>, <TokenType.DATETIME2: 'DATETIME2'>, <TokenType.DECIMAL256: 'DECIMAL256'>, <TokenType.DECIMAL32: 'DECIMAL32'>, <TokenType.MULTIPOLYGON: 'MULTIPOLYGON'>, <TokenType.SIMPLEAGGREGATEFUNCTION: 'SIMPLEAGGREGATEFUNCTION'>, <TokenType.TEXT: 'TEXT'>, <TokenType.IPADDRESS: 'IPADDRESS'>, <TokenType.UINT256: 'UINT256'>, <TokenType.NOTHING: 'NOTHING'>, <TokenType.IPV4: 'IPV4'>, <TokenType.INT: 'INT'>, <TokenType.ENUM16: 'ENUM16'>, <TokenType.TINYTEXT: 'TINYTEXT'>, <TokenType.INT8RANGE: 'INT8RANGE'>, <TokenType.VECTOR: 'VECTOR'>, <TokenType.UDOUBLE: 'UDOUBLE'>, <TokenType.INT4RANGE: 'INT4RANGE'>, <TokenType.SMALLDATETIME: 'SMALLDATETIME'>, <TokenType.TSMULTIRANGE: 'TSMULTIRANGE'>, <TokenType.TINYINT: 'TINYINT'>, <TokenType.OBJECT_IDENTIFIER: 'OBJECT_IDENTIFIER'>, <TokenType.LONGBLOB: 'LONGBLOB'>, <TokenType.VARBINARY: 'VARBINARY'>, <TokenType.NVARCHAR: 'NVARCHAR'>, <TokenType.UDECIMAL: 'UDECIMAL'>, <TokenType.OBJECT: 'OBJECT'>, <TokenType.CHAR: 'CHAR'>, <TokenType.TIMETZ: 'TIMETZ'>, <TokenType.USMALLINT: 'USMALLINT'>, <TokenType.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, <TokenType.POINT: 'POINT'>, <TokenType.DATE: 'DATE'>, <TokenType.IPV6: 'IPV6'>, <TokenType.NULL: 'NULL'>, <TokenType.VARCHAR: 'VARCHAR'>, <TokenType.MEDIUMTEXT: 'MEDIUMTEXT'>, <TokenType.TIMESTAMP_MS: 'TIMESTAMP_MS'>, <TokenType.TIMESTAMPNTZ: 'TIMESTAMPNTZ'>, <TokenType.UTINYINT: 'UTINYINT'>, <TokenType.DYNAMIC: 'DYNAMIC'>, <TokenType.DATETIME: 'DATETIME'>, <TokenType.DECIMAL: 'DECIMAL'>, <TokenType.UBIGINT: 'UBIGINT'>, <TokenType.POLYGON: 'POLYGON'>, <TokenType.HLLSKETCH: 'HLLSKETCH'>, <TokenType.NULLABLE: 'NULLABLE'>, <TokenType.IMAGE: 'IMAGE'>, <TokenType.ROWVERSION: 'ROWVERSION'>, <TokenType.BLOB: 'BLOB'>, <TokenType.BOOLEAN: 'BOOLEAN'>, <TokenType.DATETIME64: 'DATETIME64'>, <TokenType.UNION: 'UNION'>, <TokenType.TSTZRANGE: 'TSTZRANGE'>, <TokenType.DECIMAL128: 'DECIMAL128'>, <TokenType.INTERVAL: 'INTERVAL'>, <TokenType.PSEUDO_TYPE: 'PSEUDO_TYPE'>, <TokenType.UUID: 'UUID'>, <TokenType.RANGE: 'RANGE'>, <TokenType.UNKNOWN: 'UNKNOWN'>, <TokenType.TDIGEST: 'TDIGEST'>, <TokenType.SERIAL: 'SERIAL'>, <TokenType.GEOGRAPHY: 'GEOGRAPHY'>, <TokenType.BIGINT: 'BIGINT'>, <TokenType.TIME: 'TIME'>, <TokenType.GEOGRAPHYPOINT: 'GEOGRAPHYPOINT'>, <TokenType.VOID: 'VOID'>, <TokenType.AGGREGATEFUNCTION: 'AGGREGATEFUNCTION'>, <TokenType.MEDIUMBLOB: 'MEDIUMBLOB'>, <TokenType.SMALLMONEY: 'SMALLMONEY'>, <TokenType.BIT: 'BIT'>, <TokenType.BPCHAR: 'BPCHAR'>, <TokenType.TIMESTAMP_S: 'TIMESTAMP_S'>, <TokenType.NESTED: 'NESTED'>, <TokenType.ENUM8: 'ENUM8'>, <TokenType.UINT128: 'UINT128'>, <TokenType.VARIANT: 'VARIANT'>, <TokenType.JSON: 'JSON'>, <TokenType.MONEY: 'MONEY'>, <TokenType.MEDIUMINT: 'MEDIUMINT'>, <TokenType.TIMESTAMP_NS: 'TIMESTAMP_NS'>, <TokenType.TSRANGE: 'TSRANGE'>, <TokenType.TSTZMULTIRANGE: 'TSTZMULTIRANGE'>, <TokenType.LONGTEXT: 'LONGTEXT'>, <TokenType.MAP: 'MAP'>, <TokenType.LINESTRING: 'LINESTRING'>, <TokenType.FIXEDSTRING: 'FIXEDSTRING'>, <TokenType.NAME: 'NAME'>}
ENUM_TYPE_TOKENS =
{<TokenType.SET: 'SET'>, <TokenType.ENUM8: 'ENUM8'>, <TokenType.ENUM16: 'ENUM16'>, <TokenType.ENUM: 'ENUM'>, <TokenType.DYNAMIC: 'DYNAMIC'>}
OPERATION_MODIFIERS =
{'STRAIGHT_JOIN', 'HIGH_PRIORITY', 'SQL_BIG_RESULT', 'SQL_CALC_FOUND_ROWS', 'SQL_BUFFER_RESULT', 'SQL_SMALL_RESULT', 'SQL_NO_CACHE'}
SHOW_TRIE: Dict =
{'BINARY': {'LOGS': {0: True}}, 'MASTER': {'LOGS': {0: True}, 'STATUS': {0: True}}, 'BINLOG': {'EVENTS': {0: True}}, 'CHARACTER': {'SET': {0: True}}, 'CHARSET': {0: True}, 'COLLATION': {0: True}, 'FULL': {'COLUMNS': {0: True}, 'PROCESSLIST': {0: True}, 'TABLES': {0: True}}, 'COLUMNS': {0: True}, 'CREATE': {'DATABASE': {0: True}, 'EVENT': {0: True}, 'FUNCTION': {0: True}, 'PROCEDURE': {0: True}, 'TABLE': {0: True}, 'TRIGGER': {0: True}, 'VIEW': {0: True}}, 'DATABASES': {0: True}, 'SCHEMAS': {0: True}, 'ENGINE': {0: True}, 'STORAGE': {'ENGINES': {0: True}}, 'ENGINES': {0: True}, 'ERRORS': {0: True}, 'EVENTS': {0: True}, 'FUNCTION': {'CODE': {0: True}, 'STATUS': {0: True}}, 'GRANTS': {0: True}, 'INDEX': {0: True}, 'OPEN': {'TABLES': {0: True}}, 'PLUGINS': {0: True}, 'PROCEDURE': {'CODE': {0: True}, 'STATUS': {0: True}}, 'PRIVILEGES': {0: True}, 'PROCESSLIST': {0: True}, 'PROFILE': {0: True}, 'PROFILES': {0: True}, 'RELAYLOG': {'EVENTS': {0: True}}, 'REPLICAS': {0: True}, 'SLAVE': {'HOSTS': {0: True}, 'STATUS': {0: True}}, 'REPLICA': {'STATUS': {0: True}}, 'GLOBAL': {'STATUS': {0: True}, 'VARIABLES': {0: True}}, 'SESSION': {'STATUS': {0: True}, 'VARIABLES': {0: True}}, 'STATUS': {0: True}, 'TABLE': {'STATUS': {0: True}}, 'TABLES': {0: True}, 'TRIGGERS': {0: True}, 'VARIABLES': {0: True}, 'WARNINGS': {0: True}}
SET_TRIE: Dict =
{'GLOBAL': {0: True}, 'LOCAL': {0: True}, 'SESSION': {0: True}, 'TRANSACTION': {0: True}, 'PERSIST': {0: True}, 'PERSIST_ONLY': {0: True}, 'CHARACTER': {'SET': {0: True}}, 'CHARSET': {0: True}, 'NAMES': {0: True}}
Inherited Members
- sqlglot.parser.Parser
- Parser
- NO_PAREN_FUNCTIONS
- STRUCT_TYPE_TOKENS
- NESTED_TYPE_TOKENS
- AGGREGATE_TYPE_TOKENS
- SIGNED_TO_UNSIGNED_TYPE_TOKEN
- SUBQUERY_PREDICATES
- RESERVED_TOKENS
- DB_CREATABLES
- CREATABLES
- ALTERABLES
- ID_VAR_TOKENS
- ALIAS_TOKENS
- COLON_PLACEHOLDER_TOKENS
- ARRAY_CONSTRUCTORS
- COMMENT_TABLE_ALIAS_TOKENS
- UPDATE_ALIAS_TOKENS
- TRIM_TYPES
- ASSIGNMENT
- EQUALITY
- COMPARISON
- BITWISE
- TERM
- FACTOR
- EXPONENT
- TIMES
- TIMESTAMPS
- SET_OPERATIONS
- JOIN_METHODS
- JOIN_SIDES
- JOIN_KINDS
- JOIN_HINTS
- LAMBDAS
- COLUMN_OPERATORS
- EXPRESSION_PARSERS
- UNARY_PARSERS
- STRING_PARSERS
- NUMERIC_PARSERS
- PRIMARY_PARSERS
- PLACEHOLDER_PARSERS
- PIPE_SYNTAX_TRANSFORM_PARSERS
- NO_PAREN_FUNCTION_PARSERS
- INVALID_FUNC_NAME_TOKENS
- FUNCTIONS_WITH_ALIASED_ARGS
- KEY_VALUE_DEFINITIONS
- QUERY_MODIFIER_PARSERS
- 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
740 class Generator(generator.Generator): 741 INTERVAL_ALLOWS_PLURAL_FORM = False 742 LOCKING_READS_SUPPORTED = True 743 NULL_ORDERING_SUPPORTED = None 744 JOIN_HINTS = False 745 TABLE_HINTS = True 746 DUPLICATE_KEY_UPDATE_WITH_SET = False 747 QUERY_HINT_SEP = " " 748 VALUES_AS_TABLE = False 749 NVL2_SUPPORTED = False 750 LAST_DAY_SUPPORTS_DATE_PART = False 751 JSON_TYPE_REQUIRED_FOR_EXTRACTION = True 752 JSON_PATH_BRACKETED_KEY_SUPPORTED = False 753 JSON_KEY_VALUE_PAIR_SEP = "," 754 SUPPORTS_TO_NUMBER = False 755 PARSE_JSON_NAME: t.Optional[str] = None 756 PAD_FILL_PATTERN_IS_REQUIRED = True 757 WRAP_DERIVED_VALUES = False 758 VARCHAR_REQUIRES_SIZE = True 759 SUPPORTS_MEDIAN = False 760 761 TRANSFORMS = { 762 **generator.Generator.TRANSFORMS, 763 exp.ArrayAgg: rename_func("GROUP_CONCAT"), 764 exp.CurrentDate: no_paren_current_date_sql, 765 exp.DateDiff: _remove_ts_or_ds_to_date( 766 lambda self, e: self.func("DATEDIFF", e.this, e.expression), ("this", "expression") 767 ), 768 exp.DateAdd: _remove_ts_or_ds_to_date(date_add_sql("ADD")), 769 exp.DateStrToDate: datestrtodate_sql, 770 exp.DateSub: _remove_ts_or_ds_to_date(date_add_sql("SUB")), 771 exp.DateTrunc: _date_trunc_sql, 772 exp.Day: _remove_ts_or_ds_to_date(), 773 exp.DayOfMonth: _remove_ts_or_ds_to_date(rename_func("DAYOFMONTH")), 774 exp.DayOfWeek: _remove_ts_or_ds_to_date(rename_func("DAYOFWEEK")), 775 exp.DayOfYear: _remove_ts_or_ds_to_date(rename_func("DAYOFYEAR")), 776 exp.GroupConcat: lambda self, 777 e: f"""GROUP_CONCAT({self.sql(e, "this")} SEPARATOR {self.sql(e, "separator") or "','"})""", 778 exp.ILike: no_ilike_sql, 779 exp.JSONExtractScalar: arrow_json_extract_sql, 780 exp.Length: length_or_char_length_sql, 781 exp.LogicalOr: rename_func("MAX"), 782 exp.LogicalAnd: rename_func("MIN"), 783 exp.Max: max_or_greatest, 784 exp.Min: min_or_least, 785 exp.Month: _remove_ts_or_ds_to_date(), 786 exp.NullSafeEQ: lambda self, e: self.binary(e, "<=>"), 787 exp.NullSafeNEQ: lambda self, e: f"NOT {self.binary(e, '<=>')}", 788 exp.NumberToStr: rename_func("FORMAT"), 789 exp.Pivot: no_pivot_sql, 790 exp.Select: transforms.preprocess( 791 [ 792 transforms.eliminate_distinct_on, 793 transforms.eliminate_semi_and_anti_joins, 794 transforms.eliminate_qualify, 795 transforms.eliminate_full_outer_join, 796 transforms.unnest_generate_date_array_using_recursive_cte, 797 ] 798 ), 799 exp.StrPosition: lambda self, e: strposition_sql( 800 self, e, func_name="LOCATE", supports_position=True 801 ), 802 exp.StrToDate: _str_to_date_sql, 803 exp.StrToTime: _str_to_date_sql, 804 exp.Stuff: rename_func("INSERT"), 805 exp.TableSample: no_tablesample_sql, 806 exp.TimeFromParts: rename_func("MAKETIME"), 807 exp.TimestampAdd: date_add_interval_sql("DATE", "ADD"), 808 exp.TimestampDiff: lambda self, e: self.func( 809 "TIMESTAMPDIFF", unit_to_var(e), e.expression, e.this 810 ), 811 exp.TimestampSub: date_add_interval_sql("DATE", "SUB"), 812 exp.TimeStrToUnix: rename_func("UNIX_TIMESTAMP"), 813 exp.TimeStrToTime: lambda self, e: timestrtotime_sql( 814 self, 815 e, 816 include_precision=not e.args.get("zone"), 817 ), 818 exp.TimeToStr: _remove_ts_or_ds_to_date( 819 lambda self, e: self.func("DATE_FORMAT", e.this, self.format_time(e)) 820 ), 821 exp.Trim: trim_sql, 822 exp.TryCast: no_trycast_sql, 823 exp.TsOrDsAdd: date_add_sql("ADD"), 824 exp.TsOrDsDiff: lambda self, e: self.func("DATEDIFF", e.this, e.expression), 825 exp.TsOrDsToDate: _ts_or_ds_to_date_sql, 826 exp.Unicode: lambda self, e: f"ORD(CONVERT({self.sql(e.this)} USING utf32))", 827 exp.UnixToTime: _unix_to_time_sql, 828 exp.Week: _remove_ts_or_ds_to_date(), 829 exp.WeekOfYear: _remove_ts_or_ds_to_date(rename_func("WEEKOFYEAR")), 830 exp.Year: _remove_ts_or_ds_to_date(), 831 } 832 833 UNSIGNED_TYPE_MAPPING = { 834 exp.DataType.Type.UBIGINT: "BIGINT", 835 exp.DataType.Type.UINT: "INT", 836 exp.DataType.Type.UMEDIUMINT: "MEDIUMINT", 837 exp.DataType.Type.USMALLINT: "SMALLINT", 838 exp.DataType.Type.UTINYINT: "TINYINT", 839 exp.DataType.Type.UDECIMAL: "DECIMAL", 840 exp.DataType.Type.UDOUBLE: "DOUBLE", 841 } 842 843 TIMESTAMP_TYPE_MAPPING = { 844 exp.DataType.Type.DATETIME2: "DATETIME", 845 exp.DataType.Type.SMALLDATETIME: "DATETIME", 846 exp.DataType.Type.TIMESTAMP: "DATETIME", 847 exp.DataType.Type.TIMESTAMPNTZ: "DATETIME", 848 exp.DataType.Type.TIMESTAMPTZ: "TIMESTAMP", 849 exp.DataType.Type.TIMESTAMPLTZ: "TIMESTAMP", 850 } 851 852 TYPE_MAPPING = { 853 **generator.Generator.TYPE_MAPPING, 854 **UNSIGNED_TYPE_MAPPING, 855 **TIMESTAMP_TYPE_MAPPING, 856 } 857 858 TYPE_MAPPING.pop(exp.DataType.Type.MEDIUMTEXT) 859 TYPE_MAPPING.pop(exp.DataType.Type.LONGTEXT) 860 TYPE_MAPPING.pop(exp.DataType.Type.TINYTEXT) 861 TYPE_MAPPING.pop(exp.DataType.Type.BLOB) 862 TYPE_MAPPING.pop(exp.DataType.Type.MEDIUMBLOB) 863 TYPE_MAPPING.pop(exp.DataType.Type.LONGBLOB) 864 TYPE_MAPPING.pop(exp.DataType.Type.TINYBLOB) 865 866 PROPERTIES_LOCATION = { 867 **generator.Generator.PROPERTIES_LOCATION, 868 exp.TransientProperty: exp.Properties.Location.UNSUPPORTED, 869 exp.VolatileProperty: exp.Properties.Location.UNSUPPORTED, 870 } 871 872 LIMIT_FETCH = "LIMIT" 873 874 LIMIT_ONLY_LITERALS = True 875 876 CHAR_CAST_MAPPING = dict.fromkeys( 877 ( 878 exp.DataType.Type.LONGTEXT, 879 exp.DataType.Type.LONGBLOB, 880 exp.DataType.Type.MEDIUMBLOB, 881 exp.DataType.Type.MEDIUMTEXT, 882 exp.DataType.Type.TEXT, 883 exp.DataType.Type.TINYBLOB, 884 exp.DataType.Type.TINYTEXT, 885 exp.DataType.Type.VARCHAR, 886 ), 887 "CHAR", 888 ) 889 SIGNED_CAST_MAPPING = dict.fromkeys( 890 ( 891 exp.DataType.Type.BIGINT, 892 exp.DataType.Type.BOOLEAN, 893 exp.DataType.Type.INT, 894 exp.DataType.Type.SMALLINT, 895 exp.DataType.Type.TINYINT, 896 exp.DataType.Type.MEDIUMINT, 897 ), 898 "SIGNED", 899 ) 900 901 # MySQL doesn't support many datatypes in cast. 902 # https://dev.mysql.com/doc/refman/8.0/en/cast-functions.html#function_cast 903 CAST_MAPPING = { 904 **CHAR_CAST_MAPPING, 905 **SIGNED_CAST_MAPPING, 906 exp.DataType.Type.UBIGINT: "UNSIGNED", 907 } 908 909 TIMESTAMP_FUNC_TYPES = { 910 exp.DataType.Type.TIMESTAMPTZ, 911 exp.DataType.Type.TIMESTAMPLTZ, 912 } 913 914 # https://dev.mysql.com/doc/refman/8.0/en/keywords.html 915 RESERVED_KEYWORDS = { 916 "accessible", 917 "add", 918 "all", 919 "alter", 920 "analyze", 921 "and", 922 "as", 923 "asc", 924 "asensitive", 925 "before", 926 "between", 927 "bigint", 928 "binary", 929 "blob", 930 "both", 931 "by", 932 "call", 933 "cascade", 934 "case", 935 "change", 936 "char", 937 "character", 938 "check", 939 "collate", 940 "column", 941 "condition", 942 "constraint", 943 "continue", 944 "convert", 945 "create", 946 "cross", 947 "cube", 948 "cume_dist", 949 "current_date", 950 "current_time", 951 "current_timestamp", 952 "current_user", 953 "cursor", 954 "database", 955 "databases", 956 "day_hour", 957 "day_microsecond", 958 "day_minute", 959 "day_second", 960 "dec", 961 "decimal", 962 "declare", 963 "default", 964 "delayed", 965 "delete", 966 "dense_rank", 967 "desc", 968 "describe", 969 "deterministic", 970 "distinct", 971 "distinctrow", 972 "div", 973 "double", 974 "drop", 975 "dual", 976 "each", 977 "else", 978 "elseif", 979 "empty", 980 "enclosed", 981 "escaped", 982 "except", 983 "exists", 984 "exit", 985 "explain", 986 "false", 987 "fetch", 988 "first_value", 989 "float", 990 "float4", 991 "float8", 992 "for", 993 "force", 994 "foreign", 995 "from", 996 "fulltext", 997 "function", 998 "generated", 999 "get", 1000 "grant", 1001 "group", 1002 "grouping", 1003 "groups", 1004 "having", 1005 "high_priority", 1006 "hour_microsecond", 1007 "hour_minute", 1008 "hour_second", 1009 "if", 1010 "ignore", 1011 "in", 1012 "index", 1013 "infile", 1014 "inner", 1015 "inout", 1016 "insensitive", 1017 "insert", 1018 "int", 1019 "int1", 1020 "int2", 1021 "int3", 1022 "int4", 1023 "int8", 1024 "integer", 1025 "intersect", 1026 "interval", 1027 "into", 1028 "io_after_gtids", 1029 "io_before_gtids", 1030 "is", 1031 "iterate", 1032 "join", 1033 "json_table", 1034 "key", 1035 "keys", 1036 "kill", 1037 "lag", 1038 "last_value", 1039 "lateral", 1040 "lead", 1041 "leading", 1042 "leave", 1043 "left", 1044 "like", 1045 "limit", 1046 "linear", 1047 "lines", 1048 "load", 1049 "localtime", 1050 "localtimestamp", 1051 "lock", 1052 "long", 1053 "longblob", 1054 "longtext", 1055 "loop", 1056 "low_priority", 1057 "master_bind", 1058 "master_ssl_verify_server_cert", 1059 "match", 1060 "maxvalue", 1061 "mediumblob", 1062 "mediumint", 1063 "mediumtext", 1064 "middleint", 1065 "minute_microsecond", 1066 "minute_second", 1067 "mod", 1068 "modifies", 1069 "natural", 1070 "not", 1071 "no_write_to_binlog", 1072 "nth_value", 1073 "ntile", 1074 "null", 1075 "numeric", 1076 "of", 1077 "on", 1078 "optimize", 1079 "optimizer_costs", 1080 "option", 1081 "optionally", 1082 "or", 1083 "order", 1084 "out", 1085 "outer", 1086 "outfile", 1087 "over", 1088 "partition", 1089 "percent_rank", 1090 "precision", 1091 "primary", 1092 "procedure", 1093 "purge", 1094 "range", 1095 "rank", 1096 "read", 1097 "reads", 1098 "read_write", 1099 "real", 1100 "recursive", 1101 "references", 1102 "regexp", 1103 "release", 1104 "rename", 1105 "repeat", 1106 "replace", 1107 "require", 1108 "resignal", 1109 "restrict", 1110 "return", 1111 "revoke", 1112 "right", 1113 "rlike", 1114 "row", 1115 "rows", 1116 "row_number", 1117 "schema", 1118 "schemas", 1119 "second_microsecond", 1120 "select", 1121 "sensitive", 1122 "separator", 1123 "set", 1124 "show", 1125 "signal", 1126 "smallint", 1127 "spatial", 1128 "specific", 1129 "sql", 1130 "sqlexception", 1131 "sqlstate", 1132 "sqlwarning", 1133 "sql_big_result", 1134 "sql_calc_found_rows", 1135 "sql_small_result", 1136 "ssl", 1137 "starting", 1138 "stored", 1139 "straight_join", 1140 "system", 1141 "table", 1142 "terminated", 1143 "then", 1144 "tinyblob", 1145 "tinyint", 1146 "tinytext", 1147 "to", 1148 "trailing", 1149 "trigger", 1150 "true", 1151 "undo", 1152 "union", 1153 "unique", 1154 "unlock", 1155 "unsigned", 1156 "update", 1157 "usage", 1158 "use", 1159 "using", 1160 "utc_date", 1161 "utc_time", 1162 "utc_timestamp", 1163 "values", 1164 "varbinary", 1165 "varchar", 1166 "varcharacter", 1167 "varying", 1168 "virtual", 1169 "when", 1170 "where", 1171 "while", 1172 "window", 1173 "with", 1174 "write", 1175 "xor", 1176 "year_month", 1177 "zerofill", 1178 } 1179 1180 def computedcolumnconstraint_sql(self, expression: exp.ComputedColumnConstraint) -> str: 1181 persisted = "STORED" if expression.args.get("persisted") else "VIRTUAL" 1182 return f"GENERATED ALWAYS AS ({self.sql(expression.this.unnest())}) {persisted}" 1183 1184 def array_sql(self, expression: exp.Array) -> str: 1185 self.unsupported("Arrays are not supported by MySQL") 1186 return self.function_fallback_sql(expression) 1187 1188 def arraycontainsall_sql(self, expression: exp.ArrayContainsAll) -> str: 1189 self.unsupported("Array operations are not supported by MySQL") 1190 return self.function_fallback_sql(expression) 1191 1192 def dpipe_sql(self, expression: exp.DPipe) -> str: 1193 return self.func("CONCAT", *expression.flatten()) 1194 1195 def extract_sql(self, expression: exp.Extract) -> str: 1196 unit = expression.name 1197 if unit and unit.lower() == "epoch": 1198 return self.func("UNIX_TIMESTAMP", expression.expression) 1199 1200 return super().extract_sql(expression) 1201 1202 def datatype_sql(self, expression: exp.DataType) -> str: 1203 if ( 1204 self.VARCHAR_REQUIRES_SIZE 1205 and expression.is_type(exp.DataType.Type.VARCHAR) 1206 and not expression.expressions 1207 ): 1208 # `VARCHAR` must always have a size - if it doesn't, we always generate `TEXT` 1209 return "TEXT" 1210 1211 # https://dev.mysql.com/doc/refman/8.0/en/numeric-type-syntax.html 1212 result = super().datatype_sql(expression) 1213 if expression.this in self.UNSIGNED_TYPE_MAPPING: 1214 result = f"{result} UNSIGNED" 1215 1216 return result 1217 1218 def jsonarraycontains_sql(self, expression: exp.JSONArrayContains) -> str: 1219 return f"{self.sql(expression, 'this')} MEMBER OF({self.sql(expression, 'expression')})" 1220 1221 def cast_sql(self, expression: exp.Cast, safe_prefix: t.Optional[str] = None) -> str: 1222 if expression.to.this in self.TIMESTAMP_FUNC_TYPES: 1223 return self.func("TIMESTAMP", expression.this) 1224 1225 to = self.CAST_MAPPING.get(expression.to.this) 1226 1227 if to: 1228 expression.to.set("this", to) 1229 return super().cast_sql(expression) 1230 1231 def show_sql(self, expression: exp.Show) -> str: 1232 this = f" {expression.name}" 1233 full = " FULL" if expression.args.get("full") else "" 1234 global_ = " GLOBAL" if expression.args.get("global") else "" 1235 1236 target = self.sql(expression, "target") 1237 target = f" {target}" if target else "" 1238 if expression.name in ("COLUMNS", "INDEX"): 1239 target = f" FROM{target}" 1240 elif expression.name == "GRANTS": 1241 target = f" FOR{target}" 1242 1243 db = self._prefixed_sql("FROM", expression, "db") 1244 1245 like = self._prefixed_sql("LIKE", expression, "like") 1246 where = self.sql(expression, "where") 1247 1248 types = self.expressions(expression, key="types") 1249 types = f" {types}" if types else types 1250 query = self._prefixed_sql("FOR QUERY", expression, "query") 1251 1252 if expression.name == "PROFILE": 1253 offset = self._prefixed_sql("OFFSET", expression, "offset") 1254 limit = self._prefixed_sql("LIMIT", expression, "limit") 1255 else: 1256 offset = "" 1257 limit = self._oldstyle_limit_sql(expression) 1258 1259 log = self._prefixed_sql("IN", expression, "log") 1260 position = self._prefixed_sql("FROM", expression, "position") 1261 1262 channel = self._prefixed_sql("FOR CHANNEL", expression, "channel") 1263 1264 if expression.name == "ENGINE": 1265 mutex_or_status = " MUTEX" if expression.args.get("mutex") else " STATUS" 1266 else: 1267 mutex_or_status = "" 1268 1269 return f"SHOW{full}{global_}{this}{target}{types}{db}{query}{log}{position}{channel}{mutex_or_status}{like}{where}{offset}{limit}" 1270 1271 def altercolumn_sql(self, expression: exp.AlterColumn) -> str: 1272 dtype = self.sql(expression, "dtype") 1273 if not dtype: 1274 return super().altercolumn_sql(expression) 1275 1276 this = self.sql(expression, "this") 1277 return f"MODIFY COLUMN {this} {dtype}" 1278 1279 def _prefixed_sql(self, prefix: str, expression: exp.Expression, arg: str) -> str: 1280 sql = self.sql(expression, arg) 1281 return f" {prefix} {sql}" if sql else "" 1282 1283 def _oldstyle_limit_sql(self, expression: exp.Show) -> str: 1284 limit = self.sql(expression, "limit") 1285 offset = self.sql(expression, "offset") 1286 if limit: 1287 limit_offset = f"{offset}, {limit}" if offset else limit 1288 return f" LIMIT {limit_offset}" 1289 return "" 1290 1291 def chr_sql(self, expression: exp.Chr) -> str: 1292 this = self.expressions(sqls=[expression.this] + expression.expressions) 1293 charset = expression.args.get("charset") 1294 using = f" USING {self.sql(charset)}" if charset else "" 1295 return f"CHAR({this}{using})" 1296 1297 def timestamptrunc_sql(self, expression: exp.TimestampTrunc) -> str: 1298 unit = expression.args.get("unit") 1299 1300 # Pick an old-enough date to avoid negative timestamp diffs 1301 start_ts = "'0000-01-01 00:00:00'" 1302 1303 # Source: https://stackoverflow.com/a/32955740 1304 timestamp_diff = build_date_delta(exp.TimestampDiff)([unit, start_ts, expression.this]) 1305 interval = exp.Interval(this=timestamp_diff, unit=unit) 1306 dateadd = build_date_delta_with_interval(exp.DateAdd)([start_ts, interval]) 1307 1308 return self.sql(dateadd) 1309 1310 def converttimezone_sql(self, expression: exp.ConvertTimezone) -> str: 1311 from_tz = expression.args.get("source_tz") 1312 to_tz = expression.args.get("target_tz") 1313 dt = expression.args.get("timestamp") 1314 1315 return self.func("CONVERT_TZ", dt, from_tz, to_tz) 1316 1317 def attimezone_sql(self, expression: exp.AtTimeZone) -> str: 1318 self.unsupported("AT TIME ZONE is not supported by MySQL") 1319 return self.sql(expression.this) 1320 1321 def isascii_sql(self, expression: exp.IsAscii) -> str: 1322 return f"REGEXP_LIKE({self.sql(expression.this)}, '^[[:ascii:]]*$')" 1323 1324 @unsupported_args("this") 1325 def currentschema_sql(self, expression: exp.CurrentSchema) -> str: 1326 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.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 =
{'from', 'asc', 'alter', 'float', 'trigger', 'second_microsecond', 'master_ssl_verify_server_cert', 'over', 'intersect', 'int8', 'signal', 'collate', 'decimal', 'middleint', 'repeat', 'varcharacter', 'or', 'as', 'hour_microsecond', 'dual', 'convert', 'if', 'xor', 'starting', 'limit', 'not', 'localtime', 'distinctrow', 'outer', 'declare', 'nth_value', 'utc_date', 'numeric', 'grant', 'revoke', 'precision', 'hour_second', 'restrict', 'window', 'terminated', 'order', 'cascade', 'rlike', 'values', 'in', 'current_date', 'lines', 'character', 'keys', 'int1', 'distinct', 'require', 'ssl', 'longblob', 'zerofill', 'bigint', 'separator', 'maxvalue', 'high_priority', 'insert', 'outfile', 'update', 'all', 'default', 'sqlwarning', 'loop', 'select', 'using', 'recursive', 'explain', 'modifies', 'left', 'tinyint', 'system', 'groups', 'spatial', 'replace', 'call', 'range', 'empty', 'purge', 'except', 'reads', 'rename', 'percent_rank', 'add', 'references', 'deterministic', 'undo', 'constraint', 'database', 'day_second', 'integer', 'mediumint', 'primary', 'first_value', 'while', 'grouping', 'day_microsecond', 'elseif', 'before', 'release', 'write', 'column', 'is', 'double', 'false', 'last_value', 'out', 'utc_time', 'day_minute', 'io_after_gtids', 'natural', 'force', 'cube', 'continue', 'else', 'condition', 'exists', 'partition', 'union', 'delayed', 'interval', 'minute_microsecond', 'create', 'rows', 'check', 'for', 'sqlexception', 'linear', 'asensitive', 'then', 'float8', 'infile', 'inout', 'procedure', 'between', 'rank', 'fulltext', 'unique', 'optimize', 'show', 'int2', 'iterate', 'longtext', 'virtual', 'resignal', 'join', 'mediumblob', 'lock', 'int4', 'like', 'current_user', 'group', 'desc', 'mod', 'return', 'long', 'ntile', 'no_write_to_binlog', 'null', 'escaped', 'int3', 'straight_join', 'both', 'to', 'sensitive', 'day_hour', 'optimizer_costs', 'on', 'stored', 'sql_small_result', 'hour_minute', 'trailing', 'use', 'binary', 'dense_rank', 'where', 'option', 'varying', 'json_table', 'set', 'blob', 'true', 'current_timestamp', 'float4', 'master_bind', 'and', 'lag', 'fetch', 'varchar', 'exit', 'analyze', 'div', 'row', 'kill', 'sql', 'io_before_gtids', 'delete', 'read_write', 'accessible', 'tinyblob', 'optionally', 'generated', 'drop', 'sqlstate', 'sql_big_result', 'leading', 'function', 'match', 'with', 'describe', 'cross', 'low_priority', 'sql_calc_found_rows', 'databases', 'leave', 'right', 'utc_timestamp', 'regexp', 'cume_dist', 'get', 'having', 'load', 'unsigned', 'usage', 'tinytext', 'foreign', 'ignore', 'into', 'each', 'schemas', 'change', 'read', 'table', 'year_month', 'insensitive', 'index', 'current_time', 'lead', 'unlock', 'specific', 'mediumtext', 'schema', 'when', 'cursor', 'int', 'dec', 'varbinary', 'smallint', 'by', 'localtimestamp', 'real', 'enclosed', 'inner', 'row_number', 'char', 'case', 'minute_second', 'lateral', 'of', 'key'}
def
computedcolumnconstraint_sql(self, expression: sqlglot.expressions.ComputedColumnConstraint) -> str:
1202 def datatype_sql(self, expression: exp.DataType) -> str: 1203 if ( 1204 self.VARCHAR_REQUIRES_SIZE 1205 and expression.is_type(exp.DataType.Type.VARCHAR) 1206 and not expression.expressions 1207 ): 1208 # `VARCHAR` must always have a size - if it doesn't, we always generate `TEXT` 1209 return "TEXT" 1210 1211 # https://dev.mysql.com/doc/refman/8.0/en/numeric-type-syntax.html 1212 result = super().datatype_sql(expression) 1213 if expression.this in self.UNSIGNED_TYPE_MAPPING: 1214 result = f"{result} UNSIGNED" 1215 1216 return result
def
cast_sql( self, expression: sqlglot.expressions.Cast, safe_prefix: Optional[str] = None) -> str:
1221 def cast_sql(self, expression: exp.Cast, safe_prefix: t.Optional[str] = None) -> str: 1222 if expression.to.this in self.TIMESTAMP_FUNC_TYPES: 1223 return self.func("TIMESTAMP", expression.this) 1224 1225 to = self.CAST_MAPPING.get(expression.to.this) 1226 1227 if to: 1228 expression.to.set("this", to) 1229 return super().cast_sql(expression)
1231 def show_sql(self, expression: exp.Show) -> str: 1232 this = f" {expression.name}" 1233 full = " FULL" if expression.args.get("full") else "" 1234 global_ = " GLOBAL" if expression.args.get("global") else "" 1235 1236 target = self.sql(expression, "target") 1237 target = f" {target}" if target else "" 1238 if expression.name in ("COLUMNS", "INDEX"): 1239 target = f" FROM{target}" 1240 elif expression.name == "GRANTS": 1241 target = f" FOR{target}" 1242 1243 db = self._prefixed_sql("FROM", expression, "db") 1244 1245 like = self._prefixed_sql("LIKE", expression, "like") 1246 where = self.sql(expression, "where") 1247 1248 types = self.expressions(expression, key="types") 1249 types = f" {types}" if types else types 1250 query = self._prefixed_sql("FOR QUERY", expression, "query") 1251 1252 if expression.name == "PROFILE": 1253 offset = self._prefixed_sql("OFFSET", expression, "offset") 1254 limit = self._prefixed_sql("LIMIT", expression, "limit") 1255 else: 1256 offset = "" 1257 limit = self._oldstyle_limit_sql(expression) 1258 1259 log = self._prefixed_sql("IN", expression, "log") 1260 position = self._prefixed_sql("FROM", expression, "position") 1261 1262 channel = self._prefixed_sql("FOR CHANNEL", expression, "channel") 1263 1264 if expression.name == "ENGINE": 1265 mutex_or_status = " MUTEX" if expression.args.get("mutex") else " STATUS" 1266 else: 1267 mutex_or_status = "" 1268 1269 return f"SHOW{full}{global_}{this}{target}{types}{db}{query}{log}{position}{channel}{mutex_or_status}{like}{where}{offset}{limit}"
1297 def timestamptrunc_sql(self, expression: exp.TimestampTrunc) -> str: 1298 unit = expression.args.get("unit") 1299 1300 # Pick an old-enough date to avoid negative timestamp diffs 1301 start_ts = "'0000-01-01 00:00:00'" 1302 1303 # Source: https://stackoverflow.com/a/32955740 1304 timestamp_diff = build_date_delta(exp.TimestampDiff)([unit, start_ts, expression.this]) 1305 interval = exp.Interval(this=timestamp_diff, unit=unit) 1306 dateadd = build_date_delta_with_interval(exp.DateAdd)([start_ts, interval]) 1307 1308 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
- SENTINEL_LINE_BREAK
- pretty
- identify
- normalize
- pad
- unsupported_level
- max_unsupported
- leading_comma
- max_text_width
- comments
- dialect
- normalize_functions
- unsupported_messages
- generate
- preprocess
- unsupported
- sep
- seg
- sanitize_comment
- maybe_comment
- wrap
- no_identify
- normalize_func
- indent
- sql
- uncache_sql
- cache_sql
- characterset_sql
- column_parts
- column_sql
- columnposition_sql
- columndef_sql
- columnconstraint_sql
- autoincrementcolumnconstraint_sql
- compresscolumnconstraint_sql
- generatedasidentitycolumnconstraint_sql
- generatedasrowcolumnconstraint_sql
- periodforsystemtimeconstraint_sql
- notnullcolumnconstraint_sql
- primarykeycolumnconstraint_sql
- uniquecolumnconstraint_sql
- createable_sql
- create_sql
- sequenceproperties_sql
- clone_sql
- describe_sql
- heredoc_sql
- prepend_ctes
- with_sql
- cte_sql
- tablealias_sql
- bitstring_sql
- hexstring_sql
- bytestring_sql
- unicodestring_sql
- rawstring_sql
- datatypeparam_sql
- directory_sql
- delete_sql
- drop_sql
- set_operation
- set_operations
- fetch_sql
- limitoptions_sql
- filter_sql
- hint_sql
- indexparameters_sql
- index_sql
- identifier_sql
- hex_sql
- lowerhex_sql
- inputoutputformat_sql
- national_sql
- partition_sql
- properties_sql
- root_properties
- properties
- with_properties
- locate_properties
- property_name
- property_sql
- likeproperty_sql
- fallbackproperty_sql
- journalproperty_sql
- freespaceproperty_sql
- checksumproperty_sql
- mergeblockratioproperty_sql
- datablocksizeproperty_sql
- blockcompressionproperty_sql
- isolatedloadingproperty_sql
- partitionboundspec_sql
- partitionedofproperty_sql
- lockingproperty_sql
- withdataproperty_sql
- withsystemversioningproperty_sql
- insert_sql
- introducer_sql
- kill_sql
- pseudotype_sql
- objectidentifier_sql
- onconflict_sql
- returning_sql
- rowformatdelimitedproperty_sql
- withtablehint_sql
- indextablehint_sql
- historicaldata_sql
- table_parts
- table_sql
- tablefromrows_sql
- tablesample_sql
- pivot_sql
- version_sql
- tuple_sql
- update_sql
- values_sql
- var_sql
- into_sql
- from_sql
- groupingsets_sql
- rollup_sql
- cube_sql
- group_sql
- having_sql
- connect_sql
- prior_sql
- join_sql
- lambda_sql
- lateral_op
- lateral_sql
- limit_sql
- offset_sql
- setitem_sql
- set_sql
- pragma_sql
- lock_sql
- literal_sql
- escape_str
- loaddata_sql
- null_sql
- boolean_sql
- order_sql
- withfill_sql
- cluster_sql
- distribute_sql
- sort_sql
- ordered_sql
- matchrecognizemeasure_sql
- matchrecognize_sql
- query_modifiers
- options_modifier
- for_modifiers
- queryoption_sql
- offset_limit_modifiers
- after_limit_modifiers
- select_sql
- schema_sql
- schema_columns_sql
- star_sql
- parameter_sql
- sessionparameter_sql
- placeholder_sql
- subquery_sql
- qualify_sql
- unnest_sql
- prewhere_sql
- where_sql
- window_sql
- partition_by_sql
- windowspec_sql
- withingroup_sql
- between_sql
- bracket_offset_expressions
- bracket_sql
- all_sql
- any_sql
- exists_sql
- case_sql
- constraint_sql
- nextvaluefor_sql
- trim_sql
- convert_concat_args
- concat_sql
- concatws_sql
- check_sql
- foreignkey_sql
- primarykey_sql
- if_sql
- matchagainst_sql
- jsonkeyvalue_sql
- jsonpath_sql
- json_path_part
- formatjson_sql
- 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