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 VALID_INTERVAL_UNITS = { 183 *Dialect.VALID_INTERVAL_UNITS, 184 "SECOND_MICROSECOND", 185 "MINUTE_MICROSECOND", 186 "MINUTE_SECOND", 187 "HOUR_MICROSECOND", 188 "HOUR_SECOND", 189 "HOUR_MINUTE", 190 "DAY_MICROSECOND", 191 "DAY_SECOND", 192 "DAY_MINUTE", 193 "DAY_HOUR", 194 "YEAR_MONTH", 195 } 196 197 class Tokenizer(tokens.Tokenizer): 198 QUOTES = ["'", '"'] 199 COMMENTS = ["--", "#", ("/*", "*/")] 200 IDENTIFIERS = ["`"] 201 STRING_ESCAPES = ["'", '"', "\\"] 202 BIT_STRINGS = [("b'", "'"), ("B'", "'"), ("0b", "")] 203 HEX_STRINGS = [("x'", "'"), ("X'", "'"), ("0x", "")] 204 205 NESTED_COMMENTS = False 206 207 KEYWORDS = { 208 **tokens.Tokenizer.KEYWORDS, 209 "BLOB": TokenType.BLOB, 210 "CHARSET": TokenType.CHARACTER_SET, 211 "DISTINCTROW": TokenType.DISTINCT, 212 "EXPLAIN": TokenType.DESCRIBE, 213 "FORCE": TokenType.FORCE, 214 "IGNORE": TokenType.IGNORE, 215 "KEY": TokenType.KEY, 216 "LOCK TABLES": TokenType.COMMAND, 217 "LONGBLOB": TokenType.LONGBLOB, 218 "LONGTEXT": TokenType.LONGTEXT, 219 "MEDIUMBLOB": TokenType.MEDIUMBLOB, 220 "MEDIUMINT": TokenType.MEDIUMINT, 221 "MEDIUMTEXT": TokenType.MEDIUMTEXT, 222 "MEMBER OF": TokenType.MEMBER_OF, 223 "MOD": TokenType.MOD, 224 "SEPARATOR": TokenType.SEPARATOR, 225 "SERIAL": TokenType.SERIAL, 226 "SIGNED": TokenType.BIGINT, 227 "SIGNED INTEGER": TokenType.BIGINT, 228 "SOUNDS LIKE": TokenType.SOUNDS_LIKE, 229 "START": TokenType.BEGIN, 230 "TIMESTAMP": TokenType.TIMESTAMPTZ, 231 "TINYBLOB": TokenType.TINYBLOB, 232 "TINYTEXT": TokenType.TINYTEXT, 233 "UNLOCK TABLES": TokenType.COMMAND, 234 "UNSIGNED": TokenType.UBIGINT, 235 "UNSIGNED INTEGER": TokenType.UBIGINT, 236 "YEAR": TokenType.YEAR, 237 "_ARMSCII8": TokenType.INTRODUCER, 238 "_ASCII": TokenType.INTRODUCER, 239 "_BIG5": TokenType.INTRODUCER, 240 "_BINARY": TokenType.INTRODUCER, 241 "_CP1250": TokenType.INTRODUCER, 242 "_CP1251": TokenType.INTRODUCER, 243 "_CP1256": TokenType.INTRODUCER, 244 "_CP1257": TokenType.INTRODUCER, 245 "_CP850": TokenType.INTRODUCER, 246 "_CP852": TokenType.INTRODUCER, 247 "_CP866": TokenType.INTRODUCER, 248 "_CP932": TokenType.INTRODUCER, 249 "_DEC8": TokenType.INTRODUCER, 250 "_EUCJPMS": TokenType.INTRODUCER, 251 "_EUCKR": TokenType.INTRODUCER, 252 "_GB18030": TokenType.INTRODUCER, 253 "_GB2312": TokenType.INTRODUCER, 254 "_GBK": TokenType.INTRODUCER, 255 "_GEOSTD8": TokenType.INTRODUCER, 256 "_GREEK": TokenType.INTRODUCER, 257 "_HEBREW": TokenType.INTRODUCER, 258 "_HP8": TokenType.INTRODUCER, 259 "_KEYBCS2": TokenType.INTRODUCER, 260 "_KOI8R": TokenType.INTRODUCER, 261 "_KOI8U": TokenType.INTRODUCER, 262 "_LATIN1": TokenType.INTRODUCER, 263 "_LATIN2": TokenType.INTRODUCER, 264 "_LATIN5": TokenType.INTRODUCER, 265 "_LATIN7": TokenType.INTRODUCER, 266 "_MACCE": TokenType.INTRODUCER, 267 "_MACROMAN": TokenType.INTRODUCER, 268 "_SJIS": TokenType.INTRODUCER, 269 "_SWE7": TokenType.INTRODUCER, 270 "_TIS620": TokenType.INTRODUCER, 271 "_UCS2": TokenType.INTRODUCER, 272 "_UJIS": TokenType.INTRODUCER, 273 # https://dev.mysql.com/doc/refman/8.0/en/string-literals.html 274 "_UTF8": TokenType.INTRODUCER, 275 "_UTF16": TokenType.INTRODUCER, 276 "_UTF16LE": TokenType.INTRODUCER, 277 "_UTF32": TokenType.INTRODUCER, 278 "_UTF8MB3": TokenType.INTRODUCER, 279 "_UTF8MB4": TokenType.INTRODUCER, 280 "@@": TokenType.SESSION_PARAMETER, 281 } 282 283 COMMANDS = {*tokens.Tokenizer.COMMANDS, TokenType.REPLACE} - {TokenType.SHOW} 284 285 class Parser(parser.Parser): 286 FUNC_TOKENS = { 287 *parser.Parser.FUNC_TOKENS, 288 TokenType.DATABASE, 289 TokenType.MOD, 290 TokenType.SCHEMA, 291 TokenType.VALUES, 292 } 293 294 CONJUNCTION = { 295 **parser.Parser.CONJUNCTION, 296 TokenType.DAMP: exp.And, 297 TokenType.XOR: exp.Xor, 298 } 299 300 DISJUNCTION = { 301 **parser.Parser.DISJUNCTION, 302 TokenType.DPIPE: exp.Or, 303 } 304 305 TABLE_ALIAS_TOKENS = ( 306 parser.Parser.TABLE_ALIAS_TOKENS - parser.Parser.TABLE_INDEX_HINT_TOKENS 307 ) 308 309 RANGE_PARSERS = { 310 **parser.Parser.RANGE_PARSERS, 311 TokenType.SOUNDS_LIKE: lambda self, this: self.expression( 312 exp.EQ, 313 this=self.expression(exp.Soundex, this=this), 314 expression=self.expression(exp.Soundex, this=self._parse_term()), 315 ), 316 TokenType.MEMBER_OF: lambda self, this: self.expression( 317 exp.JSONArrayContains, 318 this=this, 319 expression=self._parse_wrapped(self._parse_expression), 320 ), 321 } 322 323 FUNCTIONS = { 324 **parser.Parser.FUNCTIONS, 325 "BIT_AND": exp.BitwiseAndAgg.from_arg_list, 326 "BIT_OR": exp.BitwiseOrAgg.from_arg_list, 327 "BIT_XOR": exp.BitwiseXorAgg.from_arg_list, 328 "BIT_COUNT": exp.BitwiseCountAgg.from_arg_list, 329 "CONVERT_TZ": lambda args: exp.ConvertTimezone( 330 source_tz=seq_get(args, 1), target_tz=seq_get(args, 2), timestamp=seq_get(args, 0) 331 ), 332 "CURDATE": exp.CurrentDate.from_arg_list, 333 "DATE": lambda args: exp.TsOrDsToDate(this=seq_get(args, 0)), 334 "DATE_ADD": build_date_delta_with_interval(exp.DateAdd), 335 "DATE_FORMAT": build_formatted_time(exp.TimeToStr, "mysql"), 336 "DATE_SUB": build_date_delta_with_interval(exp.DateSub), 337 "DAY": lambda args: exp.Day(this=exp.TsOrDsToDate(this=seq_get(args, 0))), 338 "DAYOFMONTH": lambda args: exp.DayOfMonth(this=exp.TsOrDsToDate(this=seq_get(args, 0))), 339 "DAYOFWEEK": lambda args: exp.DayOfWeek(this=exp.TsOrDsToDate(this=seq_get(args, 0))), 340 "DAYOFYEAR": lambda args: exp.DayOfYear(this=exp.TsOrDsToDate(this=seq_get(args, 0))), 341 "FORMAT": exp.NumberToStr.from_arg_list, 342 "FROM_UNIXTIME": build_formatted_time(exp.UnixToTime, "mysql"), 343 "ISNULL": isnull_to_is_null, 344 "LENGTH": lambda args: exp.Length(this=seq_get(args, 0), binary=True), 345 "MAKETIME": exp.TimeFromParts.from_arg_list, 346 "MONTH": lambda args: exp.Month(this=exp.TsOrDsToDate(this=seq_get(args, 0))), 347 "MONTHNAME": lambda args: exp.TimeToStr( 348 this=exp.TsOrDsToDate(this=seq_get(args, 0)), 349 format=exp.Literal.string("%B"), 350 ), 351 "SCHEMA": exp.CurrentSchema.from_arg_list, 352 "DATABASE": exp.CurrentSchema.from_arg_list, 353 "STR_TO_DATE": _str_to_date, 354 "TIMESTAMPDIFF": build_date_delta(exp.TimestampDiff), 355 "TO_DAYS": lambda args: exp.paren( 356 exp.DateDiff( 357 this=exp.TsOrDsToDate(this=seq_get(args, 0)), 358 expression=exp.TsOrDsToDate(this=exp.Literal.string("0000-01-01")), 359 unit=exp.var("DAY"), 360 ) 361 + 1 362 ), 363 "WEEK": lambda args: exp.Week( 364 this=exp.TsOrDsToDate(this=seq_get(args, 0)), mode=seq_get(args, 1) 365 ), 366 "WEEKOFYEAR": lambda args: exp.WeekOfYear(this=exp.TsOrDsToDate(this=seq_get(args, 0))), 367 "YEAR": lambda args: exp.Year(this=exp.TsOrDsToDate(this=seq_get(args, 0))), 368 } 369 370 FUNCTION_PARSERS = { 371 **parser.Parser.FUNCTION_PARSERS, 372 "CHAR": lambda self: self.expression( 373 exp.Chr, 374 expressions=self._parse_csv(self._parse_assignment), 375 charset=self._match(TokenType.USING) and self._parse_var(), 376 ), 377 "GROUP_CONCAT": lambda self: self._parse_group_concat(), 378 # https://dev.mysql.com/doc/refman/5.7/en/miscellaneous-functions.html#function_values 379 "VALUES": lambda self: self.expression( 380 exp.Anonymous, this="VALUES", expressions=[self._parse_id_var()] 381 ), 382 "JSON_VALUE": lambda self: self._parse_json_value(), 383 "SUBSTR": lambda self: self._parse_substring(), 384 } 385 386 STATEMENT_PARSERS = { 387 **parser.Parser.STATEMENT_PARSERS, 388 TokenType.SHOW: lambda self: self._parse_show(), 389 } 390 391 SHOW_PARSERS = { 392 "BINARY LOGS": _show_parser("BINARY LOGS"), 393 "MASTER LOGS": _show_parser("BINARY LOGS"), 394 "BINLOG EVENTS": _show_parser("BINLOG EVENTS"), 395 "CHARACTER SET": _show_parser("CHARACTER SET"), 396 "CHARSET": _show_parser("CHARACTER SET"), 397 "COLLATION": _show_parser("COLLATION"), 398 "FULL COLUMNS": _show_parser("COLUMNS", target="FROM", full=True), 399 "COLUMNS": _show_parser("COLUMNS", target="FROM"), 400 "CREATE DATABASE": _show_parser("CREATE DATABASE", target=True), 401 "CREATE EVENT": _show_parser("CREATE EVENT", target=True), 402 "CREATE FUNCTION": _show_parser("CREATE FUNCTION", target=True), 403 "CREATE PROCEDURE": _show_parser("CREATE PROCEDURE", target=True), 404 "CREATE TABLE": _show_parser("CREATE TABLE", target=True), 405 "CREATE TRIGGER": _show_parser("CREATE TRIGGER", target=True), 406 "CREATE VIEW": _show_parser("CREATE VIEW", target=True), 407 "DATABASES": _show_parser("DATABASES"), 408 "SCHEMAS": _show_parser("DATABASES"), 409 "ENGINE": _show_parser("ENGINE", target=True), 410 "STORAGE ENGINES": _show_parser("ENGINES"), 411 "ENGINES": _show_parser("ENGINES"), 412 "ERRORS": _show_parser("ERRORS"), 413 "EVENTS": _show_parser("EVENTS"), 414 "FUNCTION CODE": _show_parser("FUNCTION CODE", target=True), 415 "FUNCTION STATUS": _show_parser("FUNCTION STATUS"), 416 "GRANTS": _show_parser("GRANTS", target="FOR"), 417 "INDEX": _show_parser("INDEX", target="FROM"), 418 "MASTER STATUS": _show_parser("MASTER STATUS"), 419 "OPEN TABLES": _show_parser("OPEN TABLES"), 420 "PLUGINS": _show_parser("PLUGINS"), 421 "PROCEDURE CODE": _show_parser("PROCEDURE CODE", target=True), 422 "PROCEDURE STATUS": _show_parser("PROCEDURE STATUS"), 423 "PRIVILEGES": _show_parser("PRIVILEGES"), 424 "FULL PROCESSLIST": _show_parser("PROCESSLIST", full=True), 425 "PROCESSLIST": _show_parser("PROCESSLIST"), 426 "PROFILE": _show_parser("PROFILE"), 427 "PROFILES": _show_parser("PROFILES"), 428 "RELAYLOG EVENTS": _show_parser("RELAYLOG EVENTS"), 429 "REPLICAS": _show_parser("REPLICAS"), 430 "SLAVE HOSTS": _show_parser("REPLICAS"), 431 "REPLICA STATUS": _show_parser("REPLICA STATUS"), 432 "SLAVE STATUS": _show_parser("REPLICA STATUS"), 433 "GLOBAL STATUS": _show_parser("STATUS", global_=True), 434 "SESSION STATUS": _show_parser("STATUS"), 435 "STATUS": _show_parser("STATUS"), 436 "TABLE STATUS": _show_parser("TABLE STATUS"), 437 "FULL TABLES": _show_parser("TABLES", full=True), 438 "TABLES": _show_parser("TABLES"), 439 "TRIGGERS": _show_parser("TRIGGERS"), 440 "GLOBAL VARIABLES": _show_parser("VARIABLES", global_=True), 441 "SESSION VARIABLES": _show_parser("VARIABLES"), 442 "VARIABLES": _show_parser("VARIABLES"), 443 "WARNINGS": _show_parser("WARNINGS"), 444 } 445 446 PROPERTY_PARSERS = { 447 **parser.Parser.PROPERTY_PARSERS, 448 "LOCK": lambda self: self._parse_property_assignment(exp.LockProperty), 449 } 450 451 SET_PARSERS = { 452 **parser.Parser.SET_PARSERS, 453 "PERSIST": lambda self: self._parse_set_item_assignment("PERSIST"), 454 "PERSIST_ONLY": lambda self: self._parse_set_item_assignment("PERSIST_ONLY"), 455 "CHARACTER SET": lambda self: self._parse_set_item_charset("CHARACTER SET"), 456 "CHARSET": lambda self: self._parse_set_item_charset("CHARACTER SET"), 457 "NAMES": lambda self: self._parse_set_item_names(), 458 } 459 460 CONSTRAINT_PARSERS = { 461 **parser.Parser.CONSTRAINT_PARSERS, 462 "FULLTEXT": lambda self: self._parse_index_constraint(kind="FULLTEXT"), 463 "INDEX": lambda self: self._parse_index_constraint(), 464 "KEY": lambda self: self._parse_index_constraint(), 465 "SPATIAL": lambda self: self._parse_index_constraint(kind="SPATIAL"), 466 } 467 468 ALTER_PARSERS = { 469 **parser.Parser.ALTER_PARSERS, 470 "MODIFY": lambda self: self._parse_alter_table_alter(), 471 } 472 473 ALTER_ALTER_PARSERS = { 474 **parser.Parser.ALTER_ALTER_PARSERS, 475 "INDEX": lambda self: self._parse_alter_table_alter_index(), 476 } 477 478 SCHEMA_UNNAMED_CONSTRAINTS = { 479 *parser.Parser.SCHEMA_UNNAMED_CONSTRAINTS, 480 "FULLTEXT", 481 "INDEX", 482 "KEY", 483 "SPATIAL", 484 } 485 486 PROFILE_TYPES: parser.OPTIONS_TYPE = { 487 **dict.fromkeys(("ALL", "CPU", "IPC", "MEMORY", "SOURCE", "SWAPS"), tuple()), 488 "BLOCK": ("IO",), 489 "CONTEXT": ("SWITCHES",), 490 "PAGE": ("FAULTS",), 491 } 492 493 TYPE_TOKENS = { 494 *parser.Parser.TYPE_TOKENS, 495 TokenType.SET, 496 } 497 498 ENUM_TYPE_TOKENS = { 499 *parser.Parser.ENUM_TYPE_TOKENS, 500 TokenType.SET, 501 } 502 503 # SELECT [ ALL | DISTINCT | DISTINCTROW ] [ <OPERATION_MODIFIERS> ] 504 OPERATION_MODIFIERS = { 505 "HIGH_PRIORITY", 506 "STRAIGHT_JOIN", 507 "SQL_SMALL_RESULT", 508 "SQL_BIG_RESULT", 509 "SQL_BUFFER_RESULT", 510 "SQL_NO_CACHE", 511 "SQL_CALC_FOUND_ROWS", 512 } 513 514 LOG_DEFAULTS_TO_LN = True 515 STRING_ALIASES = True 516 VALUES_FOLLOWED_BY_PAREN = False 517 SUPPORTS_PARTITION_SELECTION = True 518 519 def _parse_generated_as_identity( 520 self, 521 ) -> ( 522 exp.GeneratedAsIdentityColumnConstraint 523 | exp.ComputedColumnConstraint 524 | exp.GeneratedAsRowColumnConstraint 525 ): 526 this = super()._parse_generated_as_identity() 527 528 if self._match_texts(("STORED", "VIRTUAL")): 529 persisted = self._prev.text.upper() == "STORED" 530 531 if isinstance(this, exp.ComputedColumnConstraint): 532 this.set("persisted", persisted) 533 elif isinstance(this, exp.GeneratedAsIdentityColumnConstraint): 534 this = self.expression( 535 exp.ComputedColumnConstraint, this=this.expression, persisted=persisted 536 ) 537 538 return this 539 540 def _parse_primary_key_part(self) -> t.Optional[exp.Expression]: 541 this = self._parse_id_var() 542 if not self._match(TokenType.L_PAREN): 543 return this 544 545 expression = self._parse_number() 546 self._match_r_paren() 547 return self.expression(exp.ColumnPrefix, this=this, expression=expression) 548 549 def _parse_index_constraint( 550 self, kind: t.Optional[str] = None 551 ) -> exp.IndexColumnConstraint: 552 if kind: 553 self._match_texts(("INDEX", "KEY")) 554 555 this = self._parse_id_var(any_token=False) 556 index_type = self._match(TokenType.USING) and self._advance_any() and self._prev.text 557 expressions = self._parse_wrapped_csv(self._parse_ordered) 558 559 options = [] 560 while True: 561 if self._match_text_seq("KEY_BLOCK_SIZE"): 562 self._match(TokenType.EQ) 563 opt = exp.IndexConstraintOption(key_block_size=self._parse_number()) 564 elif self._match(TokenType.USING): 565 opt = exp.IndexConstraintOption(using=self._advance_any() and self._prev.text) 566 elif self._match_text_seq("WITH", "PARSER"): 567 opt = exp.IndexConstraintOption(parser=self._parse_var(any_token=True)) 568 elif self._match(TokenType.COMMENT): 569 opt = exp.IndexConstraintOption(comment=self._parse_string()) 570 elif self._match_text_seq("VISIBLE"): 571 opt = exp.IndexConstraintOption(visible=True) 572 elif self._match_text_seq("INVISIBLE"): 573 opt = exp.IndexConstraintOption(visible=False) 574 elif self._match_text_seq("ENGINE_ATTRIBUTE"): 575 self._match(TokenType.EQ) 576 opt = exp.IndexConstraintOption(engine_attr=self._parse_string()) 577 elif self._match_text_seq("SECONDARY_ENGINE_ATTRIBUTE"): 578 self._match(TokenType.EQ) 579 opt = exp.IndexConstraintOption(secondary_engine_attr=self._parse_string()) 580 else: 581 opt = None 582 583 if not opt: 584 break 585 586 options.append(opt) 587 588 return self.expression( 589 exp.IndexColumnConstraint, 590 this=this, 591 expressions=expressions, 592 kind=kind, 593 index_type=index_type, 594 options=options, 595 ) 596 597 def _parse_show_mysql( 598 self, 599 this: str, 600 target: bool | str = False, 601 full: t.Optional[bool] = None, 602 global_: t.Optional[bool] = None, 603 ) -> exp.Show: 604 json = self._match_text_seq("JSON") 605 606 if target: 607 if isinstance(target, str): 608 self._match_text_seq(*target.split(" ")) 609 target_id = self._parse_id_var() 610 else: 611 target_id = None 612 613 log = self._parse_string() if self._match_text_seq("IN") else None 614 615 if this in ("BINLOG EVENTS", "RELAYLOG EVENTS"): 616 position = self._parse_number() if self._match_text_seq("FROM") else None 617 db = None 618 else: 619 position = None 620 db = None 621 622 if self._match(TokenType.FROM): 623 db = self._parse_id_var() 624 elif self._match(TokenType.DOT): 625 db = target_id 626 target_id = self._parse_id_var() 627 628 channel = self._parse_id_var() if self._match_text_seq("FOR", "CHANNEL") else None 629 630 like = self._parse_string() if self._match_text_seq("LIKE") else None 631 where = self._parse_where() 632 633 if this == "PROFILE": 634 types = self._parse_csv(lambda: self._parse_var_from_options(self.PROFILE_TYPES)) 635 query = self._parse_number() if self._match_text_seq("FOR", "QUERY") else None 636 offset = self._parse_number() if self._match_text_seq("OFFSET") else None 637 limit = self._parse_number() if self._match_text_seq("LIMIT") else None 638 else: 639 types, query = None, None 640 offset, limit = self._parse_oldstyle_limit() 641 642 mutex = True if self._match_text_seq("MUTEX") else None 643 mutex = False if self._match_text_seq("STATUS") else mutex 644 645 for_table = self._parse_id_var() if self._match_text_seq("FOR", "TABLE") else None 646 for_group = self._parse_string() if self._match_text_seq("FOR", "GROUP") else None 647 for_user = self._parse_string() if self._match_text_seq("FOR", "USER") else None 648 for_role = self._parse_string() if self._match_text_seq("FOR", "ROLE") else None 649 into_outfile = self._parse_string() if self._match_text_seq("INTO", "OUTFILE") else None 650 651 return self.expression( 652 exp.Show, 653 this=this, 654 target=target_id, 655 full=full, 656 log=log, 657 position=position, 658 db=db, 659 channel=channel, 660 like=like, 661 where=where, 662 types=types, 663 query=query, 664 offset=offset, 665 limit=limit, 666 mutex=mutex, 667 for_table=for_table, 668 for_group=for_group, 669 for_user=for_user, 670 for_role=for_role, 671 into_outfile=into_outfile, 672 json=json, 673 **{"global": global_}, # type: ignore 674 ) 675 676 def _parse_oldstyle_limit( 677 self, 678 ) -> t.Tuple[t.Optional[exp.Expression], t.Optional[exp.Expression]]: 679 limit = None 680 offset = None 681 if self._match_text_seq("LIMIT"): 682 parts = self._parse_csv(self._parse_number) 683 if len(parts) == 1: 684 limit = parts[0] 685 elif len(parts) == 2: 686 limit = parts[1] 687 offset = parts[0] 688 689 return offset, limit 690 691 def _parse_set_item_charset(self, kind: str) -> exp.Expression: 692 this = self._parse_string() or self._parse_unquoted_field() 693 return self.expression(exp.SetItem, this=this, kind=kind) 694 695 def _parse_set_item_names(self) -> exp.Expression: 696 charset = self._parse_string() or self._parse_unquoted_field() 697 if self._match_text_seq("COLLATE"): 698 collate = self._parse_string() or self._parse_unquoted_field() 699 else: 700 collate = None 701 702 return self.expression(exp.SetItem, this=charset, collate=collate, kind="NAMES") 703 704 def _parse_type( 705 self, parse_interval: bool = True, fallback_to_identifier: bool = False 706 ) -> t.Optional[exp.Expression]: 707 # mysql binary is special and can work anywhere, even in order by operations 708 # it operates like a no paren func 709 if self._match(TokenType.BINARY, advance=False): 710 data_type = self._parse_types(check_func=True, allow_identifiers=False) 711 712 if isinstance(data_type, exp.DataType): 713 return self.expression(exp.Cast, this=self._parse_column(), to=data_type) 714 715 return super()._parse_type( 716 parse_interval=parse_interval, fallback_to_identifier=fallback_to_identifier 717 ) 718 719 def _parse_alter_table_alter_index(self) -> exp.AlterIndex: 720 index = self._parse_field(any_token=True) 721 722 if self._match_text_seq("VISIBLE"): 723 visible = True 724 elif self._match_text_seq("INVISIBLE"): 725 visible = False 726 else: 727 visible = None 728 729 return self.expression(exp.AlterIndex, this=index, visible=visible) 730 731 class Generator(generator.Generator): 732 INTERVAL_ALLOWS_PLURAL_FORM = False 733 LOCKING_READS_SUPPORTED = True 734 NULL_ORDERING_SUPPORTED: t.Optional[bool] = None 735 JOIN_HINTS = False 736 TABLE_HINTS = True 737 DUPLICATE_KEY_UPDATE_WITH_SET = False 738 QUERY_HINT_SEP = " " 739 VALUES_AS_TABLE = False 740 NVL2_SUPPORTED = False 741 LAST_DAY_SUPPORTS_DATE_PART = False 742 JSON_TYPE_REQUIRED_FOR_EXTRACTION = True 743 JSON_PATH_BRACKETED_KEY_SUPPORTED = False 744 JSON_KEY_VALUE_PAIR_SEP = "," 745 SUPPORTS_TO_NUMBER = False 746 PARSE_JSON_NAME: t.Optional[str] = None 747 PAD_FILL_PATTERN_IS_REQUIRED = True 748 WRAP_DERIVED_VALUES = False 749 VARCHAR_REQUIRES_SIZE = True 750 SUPPORTS_MEDIAN = False 751 752 TRANSFORMS = { 753 **generator.Generator.TRANSFORMS, 754 exp.ArrayAgg: rename_func("GROUP_CONCAT"), 755 exp.BitwiseAndAgg: rename_func("BIT_AND"), 756 exp.BitwiseOrAgg: rename_func("BIT_OR"), 757 exp.BitwiseXorAgg: rename_func("BIT_XOR"), 758 exp.BitwiseCountAgg: rename_func("BIT_COUNT"), 759 exp.CurrentDate: no_paren_current_date_sql, 760 exp.DateDiff: _remove_ts_or_ds_to_date( 761 lambda self, e: self.func("DATEDIFF", e.this, e.expression), ("this", "expression") 762 ), 763 exp.DateAdd: _remove_ts_or_ds_to_date(date_add_sql("ADD")), 764 exp.DateStrToDate: datestrtodate_sql, 765 exp.DateSub: _remove_ts_or_ds_to_date(date_add_sql("SUB")), 766 exp.DateTrunc: _date_trunc_sql, 767 exp.Day: _remove_ts_or_ds_to_date(), 768 exp.DayOfMonth: _remove_ts_or_ds_to_date(rename_func("DAYOFMONTH")), 769 exp.DayOfWeek: _remove_ts_or_ds_to_date(rename_func("DAYOFWEEK")), 770 exp.DayOfYear: _remove_ts_or_ds_to_date(rename_func("DAYOFYEAR")), 771 exp.GroupConcat: lambda self, 772 e: f"""GROUP_CONCAT({self.sql(e, "this")} SEPARATOR {self.sql(e, "separator") or "','"})""", 773 exp.ILike: no_ilike_sql, 774 exp.JSONExtractScalar: arrow_json_extract_sql, 775 exp.Length: length_or_char_length_sql, 776 exp.LogicalOr: rename_func("MAX"), 777 exp.LogicalAnd: rename_func("MIN"), 778 exp.Max: max_or_greatest, 779 exp.Min: min_or_least, 780 exp.Month: _remove_ts_or_ds_to_date(), 781 exp.NullSafeEQ: lambda self, e: self.binary(e, "<=>"), 782 exp.NullSafeNEQ: lambda self, e: f"NOT {self.binary(e, '<=>')}", 783 exp.NumberToStr: rename_func("FORMAT"), 784 exp.Pivot: no_pivot_sql, 785 exp.Select: transforms.preprocess( 786 [ 787 transforms.eliminate_distinct_on, 788 transforms.eliminate_semi_and_anti_joins, 789 transforms.eliminate_qualify, 790 transforms.eliminate_full_outer_join, 791 transforms.unnest_generate_date_array_using_recursive_cte, 792 ] 793 ), 794 exp.StrPosition: lambda self, e: strposition_sql( 795 self, e, func_name="LOCATE", supports_position=True 796 ), 797 exp.StrToDate: _str_to_date_sql, 798 exp.StrToTime: _str_to_date_sql, 799 exp.Stuff: rename_func("INSERT"), 800 exp.TableSample: no_tablesample_sql, 801 exp.TimeFromParts: rename_func("MAKETIME"), 802 exp.TimestampAdd: date_add_interval_sql("DATE", "ADD"), 803 exp.TimestampDiff: lambda self, e: self.func( 804 "TIMESTAMPDIFF", unit_to_var(e), e.expression, e.this 805 ), 806 exp.TimestampSub: date_add_interval_sql("DATE", "SUB"), 807 exp.TimeStrToUnix: rename_func("UNIX_TIMESTAMP"), 808 exp.TimeStrToTime: lambda self, e: timestrtotime_sql( 809 self, 810 e, 811 include_precision=not e.args.get("zone"), 812 ), 813 exp.TimeToStr: _remove_ts_or_ds_to_date( 814 lambda self, e: self.func("DATE_FORMAT", e.this, self.format_time(e)) 815 ), 816 exp.Trim: trim_sql, 817 exp.TryCast: no_trycast_sql, 818 exp.TsOrDsAdd: date_add_sql("ADD"), 819 exp.TsOrDsDiff: lambda self, e: self.func("DATEDIFF", e.this, e.expression), 820 exp.TsOrDsToDate: _ts_or_ds_to_date_sql, 821 exp.Unicode: lambda self, e: f"ORD(CONVERT({self.sql(e.this)} USING utf32))", 822 exp.UnixToTime: _unix_to_time_sql, 823 exp.Week: _remove_ts_or_ds_to_date(), 824 exp.WeekOfYear: _remove_ts_or_ds_to_date(rename_func("WEEKOFYEAR")), 825 exp.Year: _remove_ts_or_ds_to_date(), 826 exp.UtcTimestamp: rename_func("UTC_TIMESTAMP"), 827 exp.UtcTime: rename_func("UTC_TIME"), 828 } 829 830 UNSIGNED_TYPE_MAPPING = { 831 exp.DataType.Type.UBIGINT: "BIGINT", 832 exp.DataType.Type.UINT: "INT", 833 exp.DataType.Type.UMEDIUMINT: "MEDIUMINT", 834 exp.DataType.Type.USMALLINT: "SMALLINT", 835 exp.DataType.Type.UTINYINT: "TINYINT", 836 exp.DataType.Type.UDECIMAL: "DECIMAL", 837 exp.DataType.Type.UDOUBLE: "DOUBLE", 838 } 839 840 TIMESTAMP_TYPE_MAPPING = { 841 exp.DataType.Type.DATETIME2: "DATETIME", 842 exp.DataType.Type.SMALLDATETIME: "DATETIME", 843 exp.DataType.Type.TIMESTAMP: "DATETIME", 844 exp.DataType.Type.TIMESTAMPNTZ: "DATETIME", 845 exp.DataType.Type.TIMESTAMPTZ: "TIMESTAMP", 846 exp.DataType.Type.TIMESTAMPLTZ: "TIMESTAMP", 847 } 848 849 TYPE_MAPPING = { 850 **generator.Generator.TYPE_MAPPING, 851 **UNSIGNED_TYPE_MAPPING, 852 **TIMESTAMP_TYPE_MAPPING, 853 } 854 855 TYPE_MAPPING.pop(exp.DataType.Type.MEDIUMTEXT) 856 TYPE_MAPPING.pop(exp.DataType.Type.LONGTEXT) 857 TYPE_MAPPING.pop(exp.DataType.Type.TINYTEXT) 858 TYPE_MAPPING.pop(exp.DataType.Type.BLOB) 859 TYPE_MAPPING.pop(exp.DataType.Type.MEDIUMBLOB) 860 TYPE_MAPPING.pop(exp.DataType.Type.LONGBLOB) 861 TYPE_MAPPING.pop(exp.DataType.Type.TINYBLOB) 862 863 PROPERTIES_LOCATION = { 864 **generator.Generator.PROPERTIES_LOCATION, 865 exp.TransientProperty: exp.Properties.Location.UNSUPPORTED, 866 exp.VolatileProperty: exp.Properties.Location.UNSUPPORTED, 867 } 868 869 LIMIT_FETCH = "LIMIT" 870 871 LIMIT_ONLY_LITERALS = True 872 873 CHAR_CAST_MAPPING = dict.fromkeys( 874 ( 875 exp.DataType.Type.LONGTEXT, 876 exp.DataType.Type.LONGBLOB, 877 exp.DataType.Type.MEDIUMBLOB, 878 exp.DataType.Type.MEDIUMTEXT, 879 exp.DataType.Type.TEXT, 880 exp.DataType.Type.TINYBLOB, 881 exp.DataType.Type.TINYTEXT, 882 exp.DataType.Type.VARCHAR, 883 ), 884 "CHAR", 885 ) 886 SIGNED_CAST_MAPPING = dict.fromkeys( 887 ( 888 exp.DataType.Type.BIGINT, 889 exp.DataType.Type.BOOLEAN, 890 exp.DataType.Type.INT, 891 exp.DataType.Type.SMALLINT, 892 exp.DataType.Type.TINYINT, 893 exp.DataType.Type.MEDIUMINT, 894 ), 895 "SIGNED", 896 ) 897 898 # MySQL doesn't support many datatypes in cast. 899 # https://dev.mysql.com/doc/refman/8.0/en/cast-functions.html#function_cast 900 CAST_MAPPING = { 901 **CHAR_CAST_MAPPING, 902 **SIGNED_CAST_MAPPING, 903 exp.DataType.Type.UBIGINT: "UNSIGNED", 904 } 905 906 TIMESTAMP_FUNC_TYPES = { 907 exp.DataType.Type.TIMESTAMPTZ, 908 exp.DataType.Type.TIMESTAMPLTZ, 909 } 910 911 # https://dev.mysql.com/doc/refman/8.0/en/keywords.html 912 RESERVED_KEYWORDS = { 913 "accessible", 914 "add", 915 "all", 916 "alter", 917 "analyze", 918 "and", 919 "as", 920 "asc", 921 "asensitive", 922 "before", 923 "between", 924 "bigint", 925 "binary", 926 "blob", 927 "both", 928 "by", 929 "call", 930 "cascade", 931 "case", 932 "change", 933 "char", 934 "character", 935 "check", 936 "collate", 937 "column", 938 "condition", 939 "constraint", 940 "continue", 941 "convert", 942 "create", 943 "cross", 944 "cube", 945 "cume_dist", 946 "current_date", 947 "current_time", 948 "current_timestamp", 949 "current_user", 950 "cursor", 951 "database", 952 "databases", 953 "day_hour", 954 "day_microsecond", 955 "day_minute", 956 "day_second", 957 "dec", 958 "decimal", 959 "declare", 960 "default", 961 "delayed", 962 "delete", 963 "dense_rank", 964 "desc", 965 "describe", 966 "deterministic", 967 "distinct", 968 "distinctrow", 969 "div", 970 "double", 971 "drop", 972 "dual", 973 "each", 974 "else", 975 "elseif", 976 "empty", 977 "enclosed", 978 "escaped", 979 "except", 980 "exists", 981 "exit", 982 "explain", 983 "false", 984 "fetch", 985 "first_value", 986 "float", 987 "float4", 988 "float8", 989 "for", 990 "force", 991 "foreign", 992 "from", 993 "fulltext", 994 "function", 995 "generated", 996 "get", 997 "grant", 998 "group", 999 "grouping", 1000 "groups", 1001 "having", 1002 "high_priority", 1003 "hour_microsecond", 1004 "hour_minute", 1005 "hour_second", 1006 "if", 1007 "ignore", 1008 "in", 1009 "index", 1010 "infile", 1011 "inner", 1012 "inout", 1013 "insensitive", 1014 "insert", 1015 "int", 1016 "int1", 1017 "int2", 1018 "int3", 1019 "int4", 1020 "int8", 1021 "integer", 1022 "intersect", 1023 "interval", 1024 "into", 1025 "io_after_gtids", 1026 "io_before_gtids", 1027 "is", 1028 "iterate", 1029 "join", 1030 "json_table", 1031 "key", 1032 "keys", 1033 "kill", 1034 "lag", 1035 "last_value", 1036 "lateral", 1037 "lead", 1038 "leading", 1039 "leave", 1040 "left", 1041 "like", 1042 "limit", 1043 "linear", 1044 "lines", 1045 "load", 1046 "localtime", 1047 "localtimestamp", 1048 "lock", 1049 "long", 1050 "longblob", 1051 "longtext", 1052 "loop", 1053 "low_priority", 1054 "master_bind", 1055 "master_ssl_verify_server_cert", 1056 "match", 1057 "maxvalue", 1058 "mediumblob", 1059 "mediumint", 1060 "mediumtext", 1061 "middleint", 1062 "minute_microsecond", 1063 "minute_second", 1064 "mod", 1065 "modifies", 1066 "natural", 1067 "not", 1068 "no_write_to_binlog", 1069 "nth_value", 1070 "ntile", 1071 "null", 1072 "numeric", 1073 "of", 1074 "on", 1075 "optimize", 1076 "optimizer_costs", 1077 "option", 1078 "optionally", 1079 "or", 1080 "order", 1081 "out", 1082 "outer", 1083 "outfile", 1084 "over", 1085 "partition", 1086 "percent_rank", 1087 "precision", 1088 "primary", 1089 "procedure", 1090 "purge", 1091 "range", 1092 "rank", 1093 "read", 1094 "reads", 1095 "read_write", 1096 "real", 1097 "recursive", 1098 "references", 1099 "regexp", 1100 "release", 1101 "rename", 1102 "repeat", 1103 "replace", 1104 "require", 1105 "resignal", 1106 "restrict", 1107 "return", 1108 "revoke", 1109 "right", 1110 "rlike", 1111 "row", 1112 "rows", 1113 "row_number", 1114 "schema", 1115 "schemas", 1116 "second_microsecond", 1117 "select", 1118 "sensitive", 1119 "separator", 1120 "set", 1121 "show", 1122 "signal", 1123 "smallint", 1124 "spatial", 1125 "specific", 1126 "sql", 1127 "sqlexception", 1128 "sqlstate", 1129 "sqlwarning", 1130 "sql_big_result", 1131 "sql_calc_found_rows", 1132 "sql_small_result", 1133 "ssl", 1134 "starting", 1135 "stored", 1136 "straight_join", 1137 "system", 1138 "table", 1139 "terminated", 1140 "then", 1141 "tinyblob", 1142 "tinyint", 1143 "tinytext", 1144 "to", 1145 "trailing", 1146 "trigger", 1147 "true", 1148 "undo", 1149 "union", 1150 "unique", 1151 "unlock", 1152 "unsigned", 1153 "update", 1154 "usage", 1155 "use", 1156 "using", 1157 "utc_date", 1158 "utc_time", 1159 "utc_timestamp", 1160 "values", 1161 "varbinary", 1162 "varchar", 1163 "varcharacter", 1164 "varying", 1165 "virtual", 1166 "when", 1167 "where", 1168 "while", 1169 "window", 1170 "with", 1171 "write", 1172 "xor", 1173 "year_month", 1174 "zerofill", 1175 } 1176 1177 def computedcolumnconstraint_sql(self, expression: exp.ComputedColumnConstraint) -> str: 1178 persisted = "STORED" if expression.args.get("persisted") else "VIRTUAL" 1179 return f"GENERATED ALWAYS AS ({self.sql(expression.this.unnest())}) {persisted}" 1180 1181 def array_sql(self, expression: exp.Array) -> str: 1182 self.unsupported("Arrays are not supported by MySQL") 1183 return self.function_fallback_sql(expression) 1184 1185 def arraycontainsall_sql(self, expression: exp.ArrayContainsAll) -> str: 1186 self.unsupported("Array operations are not supported by MySQL") 1187 return self.function_fallback_sql(expression) 1188 1189 def dpipe_sql(self, expression: exp.DPipe) -> str: 1190 return self.func("CONCAT", *expression.flatten()) 1191 1192 def extract_sql(self, expression: exp.Extract) -> str: 1193 unit = expression.name 1194 if unit and unit.lower() == "epoch": 1195 return self.func("UNIX_TIMESTAMP", expression.expression) 1196 1197 return super().extract_sql(expression) 1198 1199 def datatype_sql(self, expression: exp.DataType) -> str: 1200 if ( 1201 self.VARCHAR_REQUIRES_SIZE 1202 and expression.is_type(exp.DataType.Type.VARCHAR) 1203 and not expression.expressions 1204 ): 1205 # `VARCHAR` must always have a size - if it doesn't, we always generate `TEXT` 1206 return "TEXT" 1207 1208 # https://dev.mysql.com/doc/refman/8.0/en/numeric-type-syntax.html 1209 result = super().datatype_sql(expression) 1210 if expression.this in self.UNSIGNED_TYPE_MAPPING: 1211 result = f"{result} UNSIGNED" 1212 1213 return result 1214 1215 def jsonarraycontains_sql(self, expression: exp.JSONArrayContains) -> str: 1216 return f"{self.sql(expression, 'this')} MEMBER OF({self.sql(expression, 'expression')})" 1217 1218 def cast_sql(self, expression: exp.Cast, safe_prefix: t.Optional[str] = None) -> str: 1219 if expression.to.this in self.TIMESTAMP_FUNC_TYPES: 1220 return self.func("TIMESTAMP", expression.this) 1221 1222 to = self.CAST_MAPPING.get(expression.to.this) 1223 1224 if to: 1225 expression.to.set("this", to) 1226 return super().cast_sql(expression) 1227 1228 def show_sql(self, expression: exp.Show) -> str: 1229 this = f" {expression.name}" 1230 full = " FULL" if expression.args.get("full") else "" 1231 global_ = " GLOBAL" if expression.args.get("global") else "" 1232 1233 target = self.sql(expression, "target") 1234 target = f" {target}" if target else "" 1235 if expression.name in ("COLUMNS", "INDEX"): 1236 target = f" FROM{target}" 1237 elif expression.name == "GRANTS": 1238 target = f" FOR{target}" 1239 elif expression.name in ("LINKS", "PARTITIONS"): 1240 target = f" ON{target}" if target else "" 1241 elif expression.name == "PROJECTIONS": 1242 target = f" ON TABLE{target}" if target else "" 1243 1244 db = self._prefixed_sql("FROM", expression, "db") 1245 1246 like = self._prefixed_sql("LIKE", expression, "like") 1247 where = self.sql(expression, "where") 1248 1249 types = self.expressions(expression, key="types") 1250 types = f" {types}" if types else types 1251 query = self._prefixed_sql("FOR QUERY", expression, "query") 1252 1253 if expression.name == "PROFILE": 1254 offset = self._prefixed_sql("OFFSET", expression, "offset") 1255 limit = self._prefixed_sql("LIMIT", expression, "limit") 1256 else: 1257 offset = "" 1258 limit = self._oldstyle_limit_sql(expression) 1259 1260 log = self._prefixed_sql("IN", expression, "log") 1261 position = self._prefixed_sql("FROM", expression, "position") 1262 1263 channel = self._prefixed_sql("FOR CHANNEL", expression, "channel") 1264 1265 if expression.name == "ENGINE": 1266 mutex_or_status = " MUTEX" if expression.args.get("mutex") else " STATUS" 1267 else: 1268 mutex_or_status = "" 1269 1270 for_table = self._prefixed_sql("FOR TABLE", expression, "for_table") 1271 for_group = self._prefixed_sql("FOR GROUP", expression, "for_group") 1272 for_user = self._prefixed_sql("FOR USER", expression, "for_user") 1273 for_role = self._prefixed_sql("FOR ROLE", expression, "for_role") 1274 into_outfile = self._prefixed_sql("INTO OUTFILE", expression, "into_outfile") 1275 json = " JSON" if expression.args.get("json") else "" 1276 1277 return f"SHOW{full}{global_}{this}{json}{target}{for_table}{types}{db}{query}{log}{position}{channel}{mutex_or_status}{like}{where}{offset}{limit}{for_group}{for_user}{for_role}{into_outfile}" 1278 1279 def altercolumn_sql(self, expression: exp.AlterColumn) -> str: 1280 dtype = self.sql(expression, "dtype") 1281 if not dtype: 1282 return super().altercolumn_sql(expression) 1283 1284 this = self.sql(expression, "this") 1285 return f"MODIFY COLUMN {this} {dtype}" 1286 1287 def _prefixed_sql(self, prefix: str, expression: exp.Expression, arg: str) -> str: 1288 sql = self.sql(expression, arg) 1289 return f" {prefix} {sql}" if sql else "" 1290 1291 def _oldstyle_limit_sql(self, expression: exp.Show) -> str: 1292 limit = self.sql(expression, "limit") 1293 offset = self.sql(expression, "offset") 1294 if limit: 1295 limit_offset = f"{offset}, {limit}" if offset else limit 1296 return f" LIMIT {limit_offset}" 1297 return "" 1298 1299 def chr_sql(self, expression: exp.Chr) -> str: 1300 this = self.expressions(sqls=[expression.this] + expression.expressions) 1301 charset = expression.args.get("charset") 1302 using = f" USING {self.sql(charset)}" if charset else "" 1303 return f"CHAR({this}{using})" 1304 1305 def timestamptrunc_sql(self, expression: exp.TimestampTrunc) -> str: 1306 unit = expression.args.get("unit") 1307 1308 # Pick an old-enough date to avoid negative timestamp diffs 1309 start_ts = "'0000-01-01 00:00:00'" 1310 1311 # Source: https://stackoverflow.com/a/32955740 1312 timestamp_diff = build_date_delta(exp.TimestampDiff)([unit, start_ts, expression.this]) 1313 interval = exp.Interval(this=timestamp_diff, unit=unit) 1314 dateadd = build_date_delta_with_interval(exp.DateAdd)([start_ts, interval]) 1315 1316 return self.sql(dateadd) 1317 1318 def converttimezone_sql(self, expression: exp.ConvertTimezone) -> str: 1319 from_tz = expression.args.get("source_tz") 1320 to_tz = expression.args.get("target_tz") 1321 dt = expression.args.get("timestamp") 1322 1323 return self.func("CONVERT_TZ", dt, from_tz, to_tz) 1324 1325 def attimezone_sql(self, expression: exp.AtTimeZone) -> str: 1326 self.unsupported("AT TIME ZONE is not supported by MySQL") 1327 return self.sql(expression.this) 1328 1329 def isascii_sql(self, expression: exp.IsAscii) -> str: 1330 return f"REGEXP_LIKE({self.sql(expression.this)}, '^[[:ascii:]]*$')" 1331 1332 @unsupported_args("this") 1333 def currentschema_sql(self, expression: exp.CurrentSchema) -> str: 1334 return self.func("SCHEMA")
TIME_SPECIFIERS =
{'k', 's', 'l', 'f', 'I', 'h', 'H', 'p', 'S', 'r', 'T', 'i'}
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 VALID_INTERVAL_UNITS = { 184 *Dialect.VALID_INTERVAL_UNITS, 185 "SECOND_MICROSECOND", 186 "MINUTE_MICROSECOND", 187 "MINUTE_SECOND", 188 "HOUR_MICROSECOND", 189 "HOUR_SECOND", 190 "HOUR_MINUTE", 191 "DAY_MICROSECOND", 192 "DAY_SECOND", 193 "DAY_MINUTE", 194 "DAY_HOUR", 195 "YEAR_MONTH", 196 } 197 198 class Tokenizer(tokens.Tokenizer): 199 QUOTES = ["'", '"'] 200 COMMENTS = ["--", "#", ("/*", "*/")] 201 IDENTIFIERS = ["`"] 202 STRING_ESCAPES = ["'", '"', "\\"] 203 BIT_STRINGS = [("b'", "'"), ("B'", "'"), ("0b", "")] 204 HEX_STRINGS = [("x'", "'"), ("X'", "'"), ("0x", "")] 205 206 NESTED_COMMENTS = False 207 208 KEYWORDS = { 209 **tokens.Tokenizer.KEYWORDS, 210 "BLOB": TokenType.BLOB, 211 "CHARSET": TokenType.CHARACTER_SET, 212 "DISTINCTROW": TokenType.DISTINCT, 213 "EXPLAIN": TokenType.DESCRIBE, 214 "FORCE": TokenType.FORCE, 215 "IGNORE": TokenType.IGNORE, 216 "KEY": TokenType.KEY, 217 "LOCK TABLES": TokenType.COMMAND, 218 "LONGBLOB": TokenType.LONGBLOB, 219 "LONGTEXT": TokenType.LONGTEXT, 220 "MEDIUMBLOB": TokenType.MEDIUMBLOB, 221 "MEDIUMINT": TokenType.MEDIUMINT, 222 "MEDIUMTEXT": TokenType.MEDIUMTEXT, 223 "MEMBER OF": TokenType.MEMBER_OF, 224 "MOD": TokenType.MOD, 225 "SEPARATOR": TokenType.SEPARATOR, 226 "SERIAL": TokenType.SERIAL, 227 "SIGNED": TokenType.BIGINT, 228 "SIGNED INTEGER": TokenType.BIGINT, 229 "SOUNDS LIKE": TokenType.SOUNDS_LIKE, 230 "START": TokenType.BEGIN, 231 "TIMESTAMP": TokenType.TIMESTAMPTZ, 232 "TINYBLOB": TokenType.TINYBLOB, 233 "TINYTEXT": TokenType.TINYTEXT, 234 "UNLOCK TABLES": TokenType.COMMAND, 235 "UNSIGNED": TokenType.UBIGINT, 236 "UNSIGNED INTEGER": TokenType.UBIGINT, 237 "YEAR": TokenType.YEAR, 238 "_ARMSCII8": TokenType.INTRODUCER, 239 "_ASCII": TokenType.INTRODUCER, 240 "_BIG5": TokenType.INTRODUCER, 241 "_BINARY": TokenType.INTRODUCER, 242 "_CP1250": TokenType.INTRODUCER, 243 "_CP1251": TokenType.INTRODUCER, 244 "_CP1256": TokenType.INTRODUCER, 245 "_CP1257": TokenType.INTRODUCER, 246 "_CP850": TokenType.INTRODUCER, 247 "_CP852": TokenType.INTRODUCER, 248 "_CP866": TokenType.INTRODUCER, 249 "_CP932": TokenType.INTRODUCER, 250 "_DEC8": TokenType.INTRODUCER, 251 "_EUCJPMS": TokenType.INTRODUCER, 252 "_EUCKR": TokenType.INTRODUCER, 253 "_GB18030": TokenType.INTRODUCER, 254 "_GB2312": TokenType.INTRODUCER, 255 "_GBK": TokenType.INTRODUCER, 256 "_GEOSTD8": TokenType.INTRODUCER, 257 "_GREEK": TokenType.INTRODUCER, 258 "_HEBREW": TokenType.INTRODUCER, 259 "_HP8": TokenType.INTRODUCER, 260 "_KEYBCS2": TokenType.INTRODUCER, 261 "_KOI8R": TokenType.INTRODUCER, 262 "_KOI8U": TokenType.INTRODUCER, 263 "_LATIN1": TokenType.INTRODUCER, 264 "_LATIN2": TokenType.INTRODUCER, 265 "_LATIN5": TokenType.INTRODUCER, 266 "_LATIN7": TokenType.INTRODUCER, 267 "_MACCE": TokenType.INTRODUCER, 268 "_MACROMAN": TokenType.INTRODUCER, 269 "_SJIS": TokenType.INTRODUCER, 270 "_SWE7": TokenType.INTRODUCER, 271 "_TIS620": TokenType.INTRODUCER, 272 "_UCS2": TokenType.INTRODUCER, 273 "_UJIS": TokenType.INTRODUCER, 274 # https://dev.mysql.com/doc/refman/8.0/en/string-literals.html 275 "_UTF8": TokenType.INTRODUCER, 276 "_UTF16": TokenType.INTRODUCER, 277 "_UTF16LE": TokenType.INTRODUCER, 278 "_UTF32": TokenType.INTRODUCER, 279 "_UTF8MB3": TokenType.INTRODUCER, 280 "_UTF8MB4": TokenType.INTRODUCER, 281 "@@": TokenType.SESSION_PARAMETER, 282 } 283 284 COMMANDS = {*tokens.Tokenizer.COMMANDS, TokenType.REPLACE} - {TokenType.SHOW} 285 286 class Parser(parser.Parser): 287 FUNC_TOKENS = { 288 *parser.Parser.FUNC_TOKENS, 289 TokenType.DATABASE, 290 TokenType.MOD, 291 TokenType.SCHEMA, 292 TokenType.VALUES, 293 } 294 295 CONJUNCTION = { 296 **parser.Parser.CONJUNCTION, 297 TokenType.DAMP: exp.And, 298 TokenType.XOR: exp.Xor, 299 } 300 301 DISJUNCTION = { 302 **parser.Parser.DISJUNCTION, 303 TokenType.DPIPE: exp.Or, 304 } 305 306 TABLE_ALIAS_TOKENS = ( 307 parser.Parser.TABLE_ALIAS_TOKENS - parser.Parser.TABLE_INDEX_HINT_TOKENS 308 ) 309 310 RANGE_PARSERS = { 311 **parser.Parser.RANGE_PARSERS, 312 TokenType.SOUNDS_LIKE: lambda self, this: self.expression( 313 exp.EQ, 314 this=self.expression(exp.Soundex, this=this), 315 expression=self.expression(exp.Soundex, this=self._parse_term()), 316 ), 317 TokenType.MEMBER_OF: lambda self, this: self.expression( 318 exp.JSONArrayContains, 319 this=this, 320 expression=self._parse_wrapped(self._parse_expression), 321 ), 322 } 323 324 FUNCTIONS = { 325 **parser.Parser.FUNCTIONS, 326 "BIT_AND": exp.BitwiseAndAgg.from_arg_list, 327 "BIT_OR": exp.BitwiseOrAgg.from_arg_list, 328 "BIT_XOR": exp.BitwiseXorAgg.from_arg_list, 329 "BIT_COUNT": exp.BitwiseCountAgg.from_arg_list, 330 "CONVERT_TZ": lambda args: exp.ConvertTimezone( 331 source_tz=seq_get(args, 1), target_tz=seq_get(args, 2), timestamp=seq_get(args, 0) 332 ), 333 "CURDATE": exp.CurrentDate.from_arg_list, 334 "DATE": lambda args: exp.TsOrDsToDate(this=seq_get(args, 0)), 335 "DATE_ADD": build_date_delta_with_interval(exp.DateAdd), 336 "DATE_FORMAT": build_formatted_time(exp.TimeToStr, "mysql"), 337 "DATE_SUB": build_date_delta_with_interval(exp.DateSub), 338 "DAY": lambda args: exp.Day(this=exp.TsOrDsToDate(this=seq_get(args, 0))), 339 "DAYOFMONTH": lambda args: exp.DayOfMonth(this=exp.TsOrDsToDate(this=seq_get(args, 0))), 340 "DAYOFWEEK": lambda args: exp.DayOfWeek(this=exp.TsOrDsToDate(this=seq_get(args, 0))), 341 "DAYOFYEAR": lambda args: exp.DayOfYear(this=exp.TsOrDsToDate(this=seq_get(args, 0))), 342 "FORMAT": exp.NumberToStr.from_arg_list, 343 "FROM_UNIXTIME": build_formatted_time(exp.UnixToTime, "mysql"), 344 "ISNULL": isnull_to_is_null, 345 "LENGTH": lambda args: exp.Length(this=seq_get(args, 0), binary=True), 346 "MAKETIME": exp.TimeFromParts.from_arg_list, 347 "MONTH": lambda args: exp.Month(this=exp.TsOrDsToDate(this=seq_get(args, 0))), 348 "MONTHNAME": lambda args: exp.TimeToStr( 349 this=exp.TsOrDsToDate(this=seq_get(args, 0)), 350 format=exp.Literal.string("%B"), 351 ), 352 "SCHEMA": exp.CurrentSchema.from_arg_list, 353 "DATABASE": exp.CurrentSchema.from_arg_list, 354 "STR_TO_DATE": _str_to_date, 355 "TIMESTAMPDIFF": build_date_delta(exp.TimestampDiff), 356 "TO_DAYS": lambda args: exp.paren( 357 exp.DateDiff( 358 this=exp.TsOrDsToDate(this=seq_get(args, 0)), 359 expression=exp.TsOrDsToDate(this=exp.Literal.string("0000-01-01")), 360 unit=exp.var("DAY"), 361 ) 362 + 1 363 ), 364 "WEEK": lambda args: exp.Week( 365 this=exp.TsOrDsToDate(this=seq_get(args, 0)), mode=seq_get(args, 1) 366 ), 367 "WEEKOFYEAR": lambda args: exp.WeekOfYear(this=exp.TsOrDsToDate(this=seq_get(args, 0))), 368 "YEAR": lambda args: exp.Year(this=exp.TsOrDsToDate(this=seq_get(args, 0))), 369 } 370 371 FUNCTION_PARSERS = { 372 **parser.Parser.FUNCTION_PARSERS, 373 "CHAR": lambda self: self.expression( 374 exp.Chr, 375 expressions=self._parse_csv(self._parse_assignment), 376 charset=self._match(TokenType.USING) and self._parse_var(), 377 ), 378 "GROUP_CONCAT": lambda self: self._parse_group_concat(), 379 # https://dev.mysql.com/doc/refman/5.7/en/miscellaneous-functions.html#function_values 380 "VALUES": lambda self: self.expression( 381 exp.Anonymous, this="VALUES", expressions=[self._parse_id_var()] 382 ), 383 "JSON_VALUE": lambda self: self._parse_json_value(), 384 "SUBSTR": lambda self: self._parse_substring(), 385 } 386 387 STATEMENT_PARSERS = { 388 **parser.Parser.STATEMENT_PARSERS, 389 TokenType.SHOW: lambda self: self._parse_show(), 390 } 391 392 SHOW_PARSERS = { 393 "BINARY LOGS": _show_parser("BINARY LOGS"), 394 "MASTER LOGS": _show_parser("BINARY LOGS"), 395 "BINLOG EVENTS": _show_parser("BINLOG EVENTS"), 396 "CHARACTER SET": _show_parser("CHARACTER SET"), 397 "CHARSET": _show_parser("CHARACTER SET"), 398 "COLLATION": _show_parser("COLLATION"), 399 "FULL COLUMNS": _show_parser("COLUMNS", target="FROM", full=True), 400 "COLUMNS": _show_parser("COLUMNS", target="FROM"), 401 "CREATE DATABASE": _show_parser("CREATE DATABASE", target=True), 402 "CREATE EVENT": _show_parser("CREATE EVENT", target=True), 403 "CREATE FUNCTION": _show_parser("CREATE FUNCTION", target=True), 404 "CREATE PROCEDURE": _show_parser("CREATE PROCEDURE", target=True), 405 "CREATE TABLE": _show_parser("CREATE TABLE", target=True), 406 "CREATE TRIGGER": _show_parser("CREATE TRIGGER", target=True), 407 "CREATE VIEW": _show_parser("CREATE VIEW", target=True), 408 "DATABASES": _show_parser("DATABASES"), 409 "SCHEMAS": _show_parser("DATABASES"), 410 "ENGINE": _show_parser("ENGINE", target=True), 411 "STORAGE ENGINES": _show_parser("ENGINES"), 412 "ENGINES": _show_parser("ENGINES"), 413 "ERRORS": _show_parser("ERRORS"), 414 "EVENTS": _show_parser("EVENTS"), 415 "FUNCTION CODE": _show_parser("FUNCTION CODE", target=True), 416 "FUNCTION STATUS": _show_parser("FUNCTION STATUS"), 417 "GRANTS": _show_parser("GRANTS", target="FOR"), 418 "INDEX": _show_parser("INDEX", target="FROM"), 419 "MASTER STATUS": _show_parser("MASTER STATUS"), 420 "OPEN TABLES": _show_parser("OPEN TABLES"), 421 "PLUGINS": _show_parser("PLUGINS"), 422 "PROCEDURE CODE": _show_parser("PROCEDURE CODE", target=True), 423 "PROCEDURE STATUS": _show_parser("PROCEDURE STATUS"), 424 "PRIVILEGES": _show_parser("PRIVILEGES"), 425 "FULL PROCESSLIST": _show_parser("PROCESSLIST", full=True), 426 "PROCESSLIST": _show_parser("PROCESSLIST"), 427 "PROFILE": _show_parser("PROFILE"), 428 "PROFILES": _show_parser("PROFILES"), 429 "RELAYLOG EVENTS": _show_parser("RELAYLOG EVENTS"), 430 "REPLICAS": _show_parser("REPLICAS"), 431 "SLAVE HOSTS": _show_parser("REPLICAS"), 432 "REPLICA STATUS": _show_parser("REPLICA STATUS"), 433 "SLAVE STATUS": _show_parser("REPLICA STATUS"), 434 "GLOBAL STATUS": _show_parser("STATUS", global_=True), 435 "SESSION STATUS": _show_parser("STATUS"), 436 "STATUS": _show_parser("STATUS"), 437 "TABLE STATUS": _show_parser("TABLE STATUS"), 438 "FULL TABLES": _show_parser("TABLES", full=True), 439 "TABLES": _show_parser("TABLES"), 440 "TRIGGERS": _show_parser("TRIGGERS"), 441 "GLOBAL VARIABLES": _show_parser("VARIABLES", global_=True), 442 "SESSION VARIABLES": _show_parser("VARIABLES"), 443 "VARIABLES": _show_parser("VARIABLES"), 444 "WARNINGS": _show_parser("WARNINGS"), 445 } 446 447 PROPERTY_PARSERS = { 448 **parser.Parser.PROPERTY_PARSERS, 449 "LOCK": lambda self: self._parse_property_assignment(exp.LockProperty), 450 } 451 452 SET_PARSERS = { 453 **parser.Parser.SET_PARSERS, 454 "PERSIST": lambda self: self._parse_set_item_assignment("PERSIST"), 455 "PERSIST_ONLY": lambda self: self._parse_set_item_assignment("PERSIST_ONLY"), 456 "CHARACTER SET": lambda self: self._parse_set_item_charset("CHARACTER SET"), 457 "CHARSET": lambda self: self._parse_set_item_charset("CHARACTER SET"), 458 "NAMES": lambda self: self._parse_set_item_names(), 459 } 460 461 CONSTRAINT_PARSERS = { 462 **parser.Parser.CONSTRAINT_PARSERS, 463 "FULLTEXT": lambda self: self._parse_index_constraint(kind="FULLTEXT"), 464 "INDEX": lambda self: self._parse_index_constraint(), 465 "KEY": lambda self: self._parse_index_constraint(), 466 "SPATIAL": lambda self: self._parse_index_constraint(kind="SPATIAL"), 467 } 468 469 ALTER_PARSERS = { 470 **parser.Parser.ALTER_PARSERS, 471 "MODIFY": lambda self: self._parse_alter_table_alter(), 472 } 473 474 ALTER_ALTER_PARSERS = { 475 **parser.Parser.ALTER_ALTER_PARSERS, 476 "INDEX": lambda self: self._parse_alter_table_alter_index(), 477 } 478 479 SCHEMA_UNNAMED_CONSTRAINTS = { 480 *parser.Parser.SCHEMA_UNNAMED_CONSTRAINTS, 481 "FULLTEXT", 482 "INDEX", 483 "KEY", 484 "SPATIAL", 485 } 486 487 PROFILE_TYPES: parser.OPTIONS_TYPE = { 488 **dict.fromkeys(("ALL", "CPU", "IPC", "MEMORY", "SOURCE", "SWAPS"), tuple()), 489 "BLOCK": ("IO",), 490 "CONTEXT": ("SWITCHES",), 491 "PAGE": ("FAULTS",), 492 } 493 494 TYPE_TOKENS = { 495 *parser.Parser.TYPE_TOKENS, 496 TokenType.SET, 497 } 498 499 ENUM_TYPE_TOKENS = { 500 *parser.Parser.ENUM_TYPE_TOKENS, 501 TokenType.SET, 502 } 503 504 # SELECT [ ALL | DISTINCT | DISTINCTROW ] [ <OPERATION_MODIFIERS> ] 505 OPERATION_MODIFIERS = { 506 "HIGH_PRIORITY", 507 "STRAIGHT_JOIN", 508 "SQL_SMALL_RESULT", 509 "SQL_BIG_RESULT", 510 "SQL_BUFFER_RESULT", 511 "SQL_NO_CACHE", 512 "SQL_CALC_FOUND_ROWS", 513 } 514 515 LOG_DEFAULTS_TO_LN = True 516 STRING_ALIASES = True 517 VALUES_FOLLOWED_BY_PAREN = False 518 SUPPORTS_PARTITION_SELECTION = True 519 520 def _parse_generated_as_identity( 521 self, 522 ) -> ( 523 exp.GeneratedAsIdentityColumnConstraint 524 | exp.ComputedColumnConstraint 525 | exp.GeneratedAsRowColumnConstraint 526 ): 527 this = super()._parse_generated_as_identity() 528 529 if self._match_texts(("STORED", "VIRTUAL")): 530 persisted = self._prev.text.upper() == "STORED" 531 532 if isinstance(this, exp.ComputedColumnConstraint): 533 this.set("persisted", persisted) 534 elif isinstance(this, exp.GeneratedAsIdentityColumnConstraint): 535 this = self.expression( 536 exp.ComputedColumnConstraint, this=this.expression, persisted=persisted 537 ) 538 539 return this 540 541 def _parse_primary_key_part(self) -> t.Optional[exp.Expression]: 542 this = self._parse_id_var() 543 if not self._match(TokenType.L_PAREN): 544 return this 545 546 expression = self._parse_number() 547 self._match_r_paren() 548 return self.expression(exp.ColumnPrefix, this=this, expression=expression) 549 550 def _parse_index_constraint( 551 self, kind: t.Optional[str] = None 552 ) -> exp.IndexColumnConstraint: 553 if kind: 554 self._match_texts(("INDEX", "KEY")) 555 556 this = self._parse_id_var(any_token=False) 557 index_type = self._match(TokenType.USING) and self._advance_any() and self._prev.text 558 expressions = self._parse_wrapped_csv(self._parse_ordered) 559 560 options = [] 561 while True: 562 if self._match_text_seq("KEY_BLOCK_SIZE"): 563 self._match(TokenType.EQ) 564 opt = exp.IndexConstraintOption(key_block_size=self._parse_number()) 565 elif self._match(TokenType.USING): 566 opt = exp.IndexConstraintOption(using=self._advance_any() and self._prev.text) 567 elif self._match_text_seq("WITH", "PARSER"): 568 opt = exp.IndexConstraintOption(parser=self._parse_var(any_token=True)) 569 elif self._match(TokenType.COMMENT): 570 opt = exp.IndexConstraintOption(comment=self._parse_string()) 571 elif self._match_text_seq("VISIBLE"): 572 opt = exp.IndexConstraintOption(visible=True) 573 elif self._match_text_seq("INVISIBLE"): 574 opt = exp.IndexConstraintOption(visible=False) 575 elif self._match_text_seq("ENGINE_ATTRIBUTE"): 576 self._match(TokenType.EQ) 577 opt = exp.IndexConstraintOption(engine_attr=self._parse_string()) 578 elif self._match_text_seq("SECONDARY_ENGINE_ATTRIBUTE"): 579 self._match(TokenType.EQ) 580 opt = exp.IndexConstraintOption(secondary_engine_attr=self._parse_string()) 581 else: 582 opt = None 583 584 if not opt: 585 break 586 587 options.append(opt) 588 589 return self.expression( 590 exp.IndexColumnConstraint, 591 this=this, 592 expressions=expressions, 593 kind=kind, 594 index_type=index_type, 595 options=options, 596 ) 597 598 def _parse_show_mysql( 599 self, 600 this: str, 601 target: bool | str = False, 602 full: t.Optional[bool] = None, 603 global_: t.Optional[bool] = None, 604 ) -> exp.Show: 605 json = self._match_text_seq("JSON") 606 607 if target: 608 if isinstance(target, str): 609 self._match_text_seq(*target.split(" ")) 610 target_id = self._parse_id_var() 611 else: 612 target_id = None 613 614 log = self._parse_string() if self._match_text_seq("IN") else None 615 616 if this in ("BINLOG EVENTS", "RELAYLOG EVENTS"): 617 position = self._parse_number() if self._match_text_seq("FROM") else None 618 db = None 619 else: 620 position = None 621 db = None 622 623 if self._match(TokenType.FROM): 624 db = self._parse_id_var() 625 elif self._match(TokenType.DOT): 626 db = target_id 627 target_id = self._parse_id_var() 628 629 channel = self._parse_id_var() if self._match_text_seq("FOR", "CHANNEL") else None 630 631 like = self._parse_string() if self._match_text_seq("LIKE") else None 632 where = self._parse_where() 633 634 if this == "PROFILE": 635 types = self._parse_csv(lambda: self._parse_var_from_options(self.PROFILE_TYPES)) 636 query = self._parse_number() if self._match_text_seq("FOR", "QUERY") else None 637 offset = self._parse_number() if self._match_text_seq("OFFSET") else None 638 limit = self._parse_number() if self._match_text_seq("LIMIT") else None 639 else: 640 types, query = None, None 641 offset, limit = self._parse_oldstyle_limit() 642 643 mutex = True if self._match_text_seq("MUTEX") else None 644 mutex = False if self._match_text_seq("STATUS") else mutex 645 646 for_table = self._parse_id_var() if self._match_text_seq("FOR", "TABLE") else None 647 for_group = self._parse_string() if self._match_text_seq("FOR", "GROUP") else None 648 for_user = self._parse_string() if self._match_text_seq("FOR", "USER") else None 649 for_role = self._parse_string() if self._match_text_seq("FOR", "ROLE") else None 650 into_outfile = self._parse_string() if self._match_text_seq("INTO", "OUTFILE") else None 651 652 return self.expression( 653 exp.Show, 654 this=this, 655 target=target_id, 656 full=full, 657 log=log, 658 position=position, 659 db=db, 660 channel=channel, 661 like=like, 662 where=where, 663 types=types, 664 query=query, 665 offset=offset, 666 limit=limit, 667 mutex=mutex, 668 for_table=for_table, 669 for_group=for_group, 670 for_user=for_user, 671 for_role=for_role, 672 into_outfile=into_outfile, 673 json=json, 674 **{"global": global_}, # type: ignore 675 ) 676 677 def _parse_oldstyle_limit( 678 self, 679 ) -> t.Tuple[t.Optional[exp.Expression], t.Optional[exp.Expression]]: 680 limit = None 681 offset = None 682 if self._match_text_seq("LIMIT"): 683 parts = self._parse_csv(self._parse_number) 684 if len(parts) == 1: 685 limit = parts[0] 686 elif len(parts) == 2: 687 limit = parts[1] 688 offset = parts[0] 689 690 return offset, limit 691 692 def _parse_set_item_charset(self, kind: str) -> exp.Expression: 693 this = self._parse_string() or self._parse_unquoted_field() 694 return self.expression(exp.SetItem, this=this, kind=kind) 695 696 def _parse_set_item_names(self) -> exp.Expression: 697 charset = self._parse_string() or self._parse_unquoted_field() 698 if self._match_text_seq("COLLATE"): 699 collate = self._parse_string() or self._parse_unquoted_field() 700 else: 701 collate = None 702 703 return self.expression(exp.SetItem, this=charset, collate=collate, kind="NAMES") 704 705 def _parse_type( 706 self, parse_interval: bool = True, fallback_to_identifier: bool = False 707 ) -> t.Optional[exp.Expression]: 708 # mysql binary is special and can work anywhere, even in order by operations 709 # it operates like a no paren func 710 if self._match(TokenType.BINARY, advance=False): 711 data_type = self._parse_types(check_func=True, allow_identifiers=False) 712 713 if isinstance(data_type, exp.DataType): 714 return self.expression(exp.Cast, this=self._parse_column(), to=data_type) 715 716 return super()._parse_type( 717 parse_interval=parse_interval, fallback_to_identifier=fallback_to_identifier 718 ) 719 720 def _parse_alter_table_alter_index(self) -> exp.AlterIndex: 721 index = self._parse_field(any_token=True) 722 723 if self._match_text_seq("VISIBLE"): 724 visible = True 725 elif self._match_text_seq("INVISIBLE"): 726 visible = False 727 else: 728 visible = None 729 730 return self.expression(exp.AlterIndex, this=index, visible=visible) 731 732 class Generator(generator.Generator): 733 INTERVAL_ALLOWS_PLURAL_FORM = False 734 LOCKING_READS_SUPPORTED = True 735 NULL_ORDERING_SUPPORTED: t.Optional[bool] = None 736 JOIN_HINTS = False 737 TABLE_HINTS = True 738 DUPLICATE_KEY_UPDATE_WITH_SET = False 739 QUERY_HINT_SEP = " " 740 VALUES_AS_TABLE = False 741 NVL2_SUPPORTED = False 742 LAST_DAY_SUPPORTS_DATE_PART = False 743 JSON_TYPE_REQUIRED_FOR_EXTRACTION = True 744 JSON_PATH_BRACKETED_KEY_SUPPORTED = False 745 JSON_KEY_VALUE_PAIR_SEP = "," 746 SUPPORTS_TO_NUMBER = False 747 PARSE_JSON_NAME: t.Optional[str] = None 748 PAD_FILL_PATTERN_IS_REQUIRED = True 749 WRAP_DERIVED_VALUES = False 750 VARCHAR_REQUIRES_SIZE = True 751 SUPPORTS_MEDIAN = False 752 753 TRANSFORMS = { 754 **generator.Generator.TRANSFORMS, 755 exp.ArrayAgg: rename_func("GROUP_CONCAT"), 756 exp.BitwiseAndAgg: rename_func("BIT_AND"), 757 exp.BitwiseOrAgg: rename_func("BIT_OR"), 758 exp.BitwiseXorAgg: rename_func("BIT_XOR"), 759 exp.BitwiseCountAgg: rename_func("BIT_COUNT"), 760 exp.CurrentDate: no_paren_current_date_sql, 761 exp.DateDiff: _remove_ts_or_ds_to_date( 762 lambda self, e: self.func("DATEDIFF", e.this, e.expression), ("this", "expression") 763 ), 764 exp.DateAdd: _remove_ts_or_ds_to_date(date_add_sql("ADD")), 765 exp.DateStrToDate: datestrtodate_sql, 766 exp.DateSub: _remove_ts_or_ds_to_date(date_add_sql("SUB")), 767 exp.DateTrunc: _date_trunc_sql, 768 exp.Day: _remove_ts_or_ds_to_date(), 769 exp.DayOfMonth: _remove_ts_or_ds_to_date(rename_func("DAYOFMONTH")), 770 exp.DayOfWeek: _remove_ts_or_ds_to_date(rename_func("DAYOFWEEK")), 771 exp.DayOfYear: _remove_ts_or_ds_to_date(rename_func("DAYOFYEAR")), 772 exp.GroupConcat: lambda self, 773 e: f"""GROUP_CONCAT({self.sql(e, "this")} SEPARATOR {self.sql(e, "separator") or "','"})""", 774 exp.ILike: no_ilike_sql, 775 exp.JSONExtractScalar: arrow_json_extract_sql, 776 exp.Length: length_or_char_length_sql, 777 exp.LogicalOr: rename_func("MAX"), 778 exp.LogicalAnd: rename_func("MIN"), 779 exp.Max: max_or_greatest, 780 exp.Min: min_or_least, 781 exp.Month: _remove_ts_or_ds_to_date(), 782 exp.NullSafeEQ: lambda self, e: self.binary(e, "<=>"), 783 exp.NullSafeNEQ: lambda self, e: f"NOT {self.binary(e, '<=>')}", 784 exp.NumberToStr: rename_func("FORMAT"), 785 exp.Pivot: no_pivot_sql, 786 exp.Select: transforms.preprocess( 787 [ 788 transforms.eliminate_distinct_on, 789 transforms.eliminate_semi_and_anti_joins, 790 transforms.eliminate_qualify, 791 transforms.eliminate_full_outer_join, 792 transforms.unnest_generate_date_array_using_recursive_cte, 793 ] 794 ), 795 exp.StrPosition: lambda self, e: strposition_sql( 796 self, e, func_name="LOCATE", supports_position=True 797 ), 798 exp.StrToDate: _str_to_date_sql, 799 exp.StrToTime: _str_to_date_sql, 800 exp.Stuff: rename_func("INSERT"), 801 exp.TableSample: no_tablesample_sql, 802 exp.TimeFromParts: rename_func("MAKETIME"), 803 exp.TimestampAdd: date_add_interval_sql("DATE", "ADD"), 804 exp.TimestampDiff: lambda self, e: self.func( 805 "TIMESTAMPDIFF", unit_to_var(e), e.expression, e.this 806 ), 807 exp.TimestampSub: date_add_interval_sql("DATE", "SUB"), 808 exp.TimeStrToUnix: rename_func("UNIX_TIMESTAMP"), 809 exp.TimeStrToTime: lambda self, e: timestrtotime_sql( 810 self, 811 e, 812 include_precision=not e.args.get("zone"), 813 ), 814 exp.TimeToStr: _remove_ts_or_ds_to_date( 815 lambda self, e: self.func("DATE_FORMAT", e.this, self.format_time(e)) 816 ), 817 exp.Trim: trim_sql, 818 exp.TryCast: no_trycast_sql, 819 exp.TsOrDsAdd: date_add_sql("ADD"), 820 exp.TsOrDsDiff: lambda self, e: self.func("DATEDIFF", e.this, e.expression), 821 exp.TsOrDsToDate: _ts_or_ds_to_date_sql, 822 exp.Unicode: lambda self, e: f"ORD(CONVERT({self.sql(e.this)} USING utf32))", 823 exp.UnixToTime: _unix_to_time_sql, 824 exp.Week: _remove_ts_or_ds_to_date(), 825 exp.WeekOfYear: _remove_ts_or_ds_to_date(rename_func("WEEKOFYEAR")), 826 exp.Year: _remove_ts_or_ds_to_date(), 827 exp.UtcTimestamp: rename_func("UTC_TIMESTAMP"), 828 exp.UtcTime: rename_func("UTC_TIME"), 829 } 830 831 UNSIGNED_TYPE_MAPPING = { 832 exp.DataType.Type.UBIGINT: "BIGINT", 833 exp.DataType.Type.UINT: "INT", 834 exp.DataType.Type.UMEDIUMINT: "MEDIUMINT", 835 exp.DataType.Type.USMALLINT: "SMALLINT", 836 exp.DataType.Type.UTINYINT: "TINYINT", 837 exp.DataType.Type.UDECIMAL: "DECIMAL", 838 exp.DataType.Type.UDOUBLE: "DOUBLE", 839 } 840 841 TIMESTAMP_TYPE_MAPPING = { 842 exp.DataType.Type.DATETIME2: "DATETIME", 843 exp.DataType.Type.SMALLDATETIME: "DATETIME", 844 exp.DataType.Type.TIMESTAMP: "DATETIME", 845 exp.DataType.Type.TIMESTAMPNTZ: "DATETIME", 846 exp.DataType.Type.TIMESTAMPTZ: "TIMESTAMP", 847 exp.DataType.Type.TIMESTAMPLTZ: "TIMESTAMP", 848 } 849 850 TYPE_MAPPING = { 851 **generator.Generator.TYPE_MAPPING, 852 **UNSIGNED_TYPE_MAPPING, 853 **TIMESTAMP_TYPE_MAPPING, 854 } 855 856 TYPE_MAPPING.pop(exp.DataType.Type.MEDIUMTEXT) 857 TYPE_MAPPING.pop(exp.DataType.Type.LONGTEXT) 858 TYPE_MAPPING.pop(exp.DataType.Type.TINYTEXT) 859 TYPE_MAPPING.pop(exp.DataType.Type.BLOB) 860 TYPE_MAPPING.pop(exp.DataType.Type.MEDIUMBLOB) 861 TYPE_MAPPING.pop(exp.DataType.Type.LONGBLOB) 862 TYPE_MAPPING.pop(exp.DataType.Type.TINYBLOB) 863 864 PROPERTIES_LOCATION = { 865 **generator.Generator.PROPERTIES_LOCATION, 866 exp.TransientProperty: exp.Properties.Location.UNSUPPORTED, 867 exp.VolatileProperty: exp.Properties.Location.UNSUPPORTED, 868 } 869 870 LIMIT_FETCH = "LIMIT" 871 872 LIMIT_ONLY_LITERALS = True 873 874 CHAR_CAST_MAPPING = dict.fromkeys( 875 ( 876 exp.DataType.Type.LONGTEXT, 877 exp.DataType.Type.LONGBLOB, 878 exp.DataType.Type.MEDIUMBLOB, 879 exp.DataType.Type.MEDIUMTEXT, 880 exp.DataType.Type.TEXT, 881 exp.DataType.Type.TINYBLOB, 882 exp.DataType.Type.TINYTEXT, 883 exp.DataType.Type.VARCHAR, 884 ), 885 "CHAR", 886 ) 887 SIGNED_CAST_MAPPING = dict.fromkeys( 888 ( 889 exp.DataType.Type.BIGINT, 890 exp.DataType.Type.BOOLEAN, 891 exp.DataType.Type.INT, 892 exp.DataType.Type.SMALLINT, 893 exp.DataType.Type.TINYINT, 894 exp.DataType.Type.MEDIUMINT, 895 ), 896 "SIGNED", 897 ) 898 899 # MySQL doesn't support many datatypes in cast. 900 # https://dev.mysql.com/doc/refman/8.0/en/cast-functions.html#function_cast 901 CAST_MAPPING = { 902 **CHAR_CAST_MAPPING, 903 **SIGNED_CAST_MAPPING, 904 exp.DataType.Type.UBIGINT: "UNSIGNED", 905 } 906 907 TIMESTAMP_FUNC_TYPES = { 908 exp.DataType.Type.TIMESTAMPTZ, 909 exp.DataType.Type.TIMESTAMPLTZ, 910 } 911 912 # https://dev.mysql.com/doc/refman/8.0/en/keywords.html 913 RESERVED_KEYWORDS = { 914 "accessible", 915 "add", 916 "all", 917 "alter", 918 "analyze", 919 "and", 920 "as", 921 "asc", 922 "asensitive", 923 "before", 924 "between", 925 "bigint", 926 "binary", 927 "blob", 928 "both", 929 "by", 930 "call", 931 "cascade", 932 "case", 933 "change", 934 "char", 935 "character", 936 "check", 937 "collate", 938 "column", 939 "condition", 940 "constraint", 941 "continue", 942 "convert", 943 "create", 944 "cross", 945 "cube", 946 "cume_dist", 947 "current_date", 948 "current_time", 949 "current_timestamp", 950 "current_user", 951 "cursor", 952 "database", 953 "databases", 954 "day_hour", 955 "day_microsecond", 956 "day_minute", 957 "day_second", 958 "dec", 959 "decimal", 960 "declare", 961 "default", 962 "delayed", 963 "delete", 964 "dense_rank", 965 "desc", 966 "describe", 967 "deterministic", 968 "distinct", 969 "distinctrow", 970 "div", 971 "double", 972 "drop", 973 "dual", 974 "each", 975 "else", 976 "elseif", 977 "empty", 978 "enclosed", 979 "escaped", 980 "except", 981 "exists", 982 "exit", 983 "explain", 984 "false", 985 "fetch", 986 "first_value", 987 "float", 988 "float4", 989 "float8", 990 "for", 991 "force", 992 "foreign", 993 "from", 994 "fulltext", 995 "function", 996 "generated", 997 "get", 998 "grant", 999 "group", 1000 "grouping", 1001 "groups", 1002 "having", 1003 "high_priority", 1004 "hour_microsecond", 1005 "hour_minute", 1006 "hour_second", 1007 "if", 1008 "ignore", 1009 "in", 1010 "index", 1011 "infile", 1012 "inner", 1013 "inout", 1014 "insensitive", 1015 "insert", 1016 "int", 1017 "int1", 1018 "int2", 1019 "int3", 1020 "int4", 1021 "int8", 1022 "integer", 1023 "intersect", 1024 "interval", 1025 "into", 1026 "io_after_gtids", 1027 "io_before_gtids", 1028 "is", 1029 "iterate", 1030 "join", 1031 "json_table", 1032 "key", 1033 "keys", 1034 "kill", 1035 "lag", 1036 "last_value", 1037 "lateral", 1038 "lead", 1039 "leading", 1040 "leave", 1041 "left", 1042 "like", 1043 "limit", 1044 "linear", 1045 "lines", 1046 "load", 1047 "localtime", 1048 "localtimestamp", 1049 "lock", 1050 "long", 1051 "longblob", 1052 "longtext", 1053 "loop", 1054 "low_priority", 1055 "master_bind", 1056 "master_ssl_verify_server_cert", 1057 "match", 1058 "maxvalue", 1059 "mediumblob", 1060 "mediumint", 1061 "mediumtext", 1062 "middleint", 1063 "minute_microsecond", 1064 "minute_second", 1065 "mod", 1066 "modifies", 1067 "natural", 1068 "not", 1069 "no_write_to_binlog", 1070 "nth_value", 1071 "ntile", 1072 "null", 1073 "numeric", 1074 "of", 1075 "on", 1076 "optimize", 1077 "optimizer_costs", 1078 "option", 1079 "optionally", 1080 "or", 1081 "order", 1082 "out", 1083 "outer", 1084 "outfile", 1085 "over", 1086 "partition", 1087 "percent_rank", 1088 "precision", 1089 "primary", 1090 "procedure", 1091 "purge", 1092 "range", 1093 "rank", 1094 "read", 1095 "reads", 1096 "read_write", 1097 "real", 1098 "recursive", 1099 "references", 1100 "regexp", 1101 "release", 1102 "rename", 1103 "repeat", 1104 "replace", 1105 "require", 1106 "resignal", 1107 "restrict", 1108 "return", 1109 "revoke", 1110 "right", 1111 "rlike", 1112 "row", 1113 "rows", 1114 "row_number", 1115 "schema", 1116 "schemas", 1117 "second_microsecond", 1118 "select", 1119 "sensitive", 1120 "separator", 1121 "set", 1122 "show", 1123 "signal", 1124 "smallint", 1125 "spatial", 1126 "specific", 1127 "sql", 1128 "sqlexception", 1129 "sqlstate", 1130 "sqlwarning", 1131 "sql_big_result", 1132 "sql_calc_found_rows", 1133 "sql_small_result", 1134 "ssl", 1135 "starting", 1136 "stored", 1137 "straight_join", 1138 "system", 1139 "table", 1140 "terminated", 1141 "then", 1142 "tinyblob", 1143 "tinyint", 1144 "tinytext", 1145 "to", 1146 "trailing", 1147 "trigger", 1148 "true", 1149 "undo", 1150 "union", 1151 "unique", 1152 "unlock", 1153 "unsigned", 1154 "update", 1155 "usage", 1156 "use", 1157 "using", 1158 "utc_date", 1159 "utc_time", 1160 "utc_timestamp", 1161 "values", 1162 "varbinary", 1163 "varchar", 1164 "varcharacter", 1165 "varying", 1166 "virtual", 1167 "when", 1168 "where", 1169 "while", 1170 "window", 1171 "with", 1172 "write", 1173 "xor", 1174 "year_month", 1175 "zerofill", 1176 } 1177 1178 def computedcolumnconstraint_sql(self, expression: exp.ComputedColumnConstraint) -> str: 1179 persisted = "STORED" if expression.args.get("persisted") else "VIRTUAL" 1180 return f"GENERATED ALWAYS AS ({self.sql(expression.this.unnest())}) {persisted}" 1181 1182 def array_sql(self, expression: exp.Array) -> str: 1183 self.unsupported("Arrays are not supported by MySQL") 1184 return self.function_fallback_sql(expression) 1185 1186 def arraycontainsall_sql(self, expression: exp.ArrayContainsAll) -> str: 1187 self.unsupported("Array operations are not supported by MySQL") 1188 return self.function_fallback_sql(expression) 1189 1190 def dpipe_sql(self, expression: exp.DPipe) -> str: 1191 return self.func("CONCAT", *expression.flatten()) 1192 1193 def extract_sql(self, expression: exp.Extract) -> str: 1194 unit = expression.name 1195 if unit and unit.lower() == "epoch": 1196 return self.func("UNIX_TIMESTAMP", expression.expression) 1197 1198 return super().extract_sql(expression) 1199 1200 def datatype_sql(self, expression: exp.DataType) -> str: 1201 if ( 1202 self.VARCHAR_REQUIRES_SIZE 1203 and expression.is_type(exp.DataType.Type.VARCHAR) 1204 and not expression.expressions 1205 ): 1206 # `VARCHAR` must always have a size - if it doesn't, we always generate `TEXT` 1207 return "TEXT" 1208 1209 # https://dev.mysql.com/doc/refman/8.0/en/numeric-type-syntax.html 1210 result = super().datatype_sql(expression) 1211 if expression.this in self.UNSIGNED_TYPE_MAPPING: 1212 result = f"{result} UNSIGNED" 1213 1214 return result 1215 1216 def jsonarraycontains_sql(self, expression: exp.JSONArrayContains) -> str: 1217 return f"{self.sql(expression, 'this')} MEMBER OF({self.sql(expression, 'expression')})" 1218 1219 def cast_sql(self, expression: exp.Cast, safe_prefix: t.Optional[str] = None) -> str: 1220 if expression.to.this in self.TIMESTAMP_FUNC_TYPES: 1221 return self.func("TIMESTAMP", expression.this) 1222 1223 to = self.CAST_MAPPING.get(expression.to.this) 1224 1225 if to: 1226 expression.to.set("this", to) 1227 return super().cast_sql(expression) 1228 1229 def show_sql(self, expression: exp.Show) -> str: 1230 this = f" {expression.name}" 1231 full = " FULL" if expression.args.get("full") else "" 1232 global_ = " GLOBAL" if expression.args.get("global") else "" 1233 1234 target = self.sql(expression, "target") 1235 target = f" {target}" if target else "" 1236 if expression.name in ("COLUMNS", "INDEX"): 1237 target = f" FROM{target}" 1238 elif expression.name == "GRANTS": 1239 target = f" FOR{target}" 1240 elif expression.name in ("LINKS", "PARTITIONS"): 1241 target = f" ON{target}" if target else "" 1242 elif expression.name == "PROJECTIONS": 1243 target = f" ON TABLE{target}" if target else "" 1244 1245 db = self._prefixed_sql("FROM", expression, "db") 1246 1247 like = self._prefixed_sql("LIKE", expression, "like") 1248 where = self.sql(expression, "where") 1249 1250 types = self.expressions(expression, key="types") 1251 types = f" {types}" if types else types 1252 query = self._prefixed_sql("FOR QUERY", expression, "query") 1253 1254 if expression.name == "PROFILE": 1255 offset = self._prefixed_sql("OFFSET", expression, "offset") 1256 limit = self._prefixed_sql("LIMIT", expression, "limit") 1257 else: 1258 offset = "" 1259 limit = self._oldstyle_limit_sql(expression) 1260 1261 log = self._prefixed_sql("IN", expression, "log") 1262 position = self._prefixed_sql("FROM", expression, "position") 1263 1264 channel = self._prefixed_sql("FOR CHANNEL", expression, "channel") 1265 1266 if expression.name == "ENGINE": 1267 mutex_or_status = " MUTEX" if expression.args.get("mutex") else " STATUS" 1268 else: 1269 mutex_or_status = "" 1270 1271 for_table = self._prefixed_sql("FOR TABLE", expression, "for_table") 1272 for_group = self._prefixed_sql("FOR GROUP", expression, "for_group") 1273 for_user = self._prefixed_sql("FOR USER", expression, "for_user") 1274 for_role = self._prefixed_sql("FOR ROLE", expression, "for_role") 1275 into_outfile = self._prefixed_sql("INTO OUTFILE", expression, "into_outfile") 1276 json = " JSON" if expression.args.get("json") else "" 1277 1278 return f"SHOW{full}{global_}{this}{json}{target}{for_table}{types}{db}{query}{log}{position}{channel}{mutex_or_status}{like}{where}{offset}{limit}{for_group}{for_user}{for_role}{into_outfile}" 1279 1280 def altercolumn_sql(self, expression: exp.AlterColumn) -> str: 1281 dtype = self.sql(expression, "dtype") 1282 if not dtype: 1283 return super().altercolumn_sql(expression) 1284 1285 this = self.sql(expression, "this") 1286 return f"MODIFY COLUMN {this} {dtype}" 1287 1288 def _prefixed_sql(self, prefix: str, expression: exp.Expression, arg: str) -> str: 1289 sql = self.sql(expression, arg) 1290 return f" {prefix} {sql}" if sql else "" 1291 1292 def _oldstyle_limit_sql(self, expression: exp.Show) -> str: 1293 limit = self.sql(expression, "limit") 1294 offset = self.sql(expression, "offset") 1295 if limit: 1296 limit_offset = f"{offset}, {limit}" if offset else limit 1297 return f" LIMIT {limit_offset}" 1298 return "" 1299 1300 def chr_sql(self, expression: exp.Chr) -> str: 1301 this = self.expressions(sqls=[expression.this] + expression.expressions) 1302 charset = expression.args.get("charset") 1303 using = f" USING {self.sql(charset)}" if charset else "" 1304 return f"CHAR({this}{using})" 1305 1306 def timestamptrunc_sql(self, expression: exp.TimestampTrunc) -> str: 1307 unit = expression.args.get("unit") 1308 1309 # Pick an old-enough date to avoid negative timestamp diffs 1310 start_ts = "'0000-01-01 00:00:00'" 1311 1312 # Source: https://stackoverflow.com/a/32955740 1313 timestamp_diff = build_date_delta(exp.TimestampDiff)([unit, start_ts, expression.this]) 1314 interval = exp.Interval(this=timestamp_diff, unit=unit) 1315 dateadd = build_date_delta_with_interval(exp.DateAdd)([start_ts, interval]) 1316 1317 return self.sql(dateadd) 1318 1319 def converttimezone_sql(self, expression: exp.ConvertTimezone) -> str: 1320 from_tz = expression.args.get("source_tz") 1321 to_tz = expression.args.get("target_tz") 1322 dt = expression.args.get("timestamp") 1323 1324 return self.func("CONVERT_TZ", dt, from_tz, to_tz) 1325 1326 def attimezone_sql(self, expression: exp.AtTimeZone) -> str: 1327 self.unsupported("AT TIME ZONE is not supported by MySQL") 1328 return self.sql(expression.this) 1329 1330 def isascii_sql(self, expression: exp.IsAscii) -> str: 1331 return f"REGEXP_LIKE({self.sql(expression.this)}, '^[[:ascii:]]*$')" 1332 1333 @unsupported_args("this") 1334 def currentschema_sql(self, expression: exp.CurrentSchema) -> str: 1335 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.
VALID_INTERVAL_UNITS: Set[str] =
{'MONTH', 'MICROSECS', 'MONTHS', 'QUARTERS', 'WEEKOFYEAR', 'TIMEZONE_MINUTE', 'D', 'MON', 'MSECOND', 'YEAR', 'DW', 'MILLISECON', 'TIMEZONE_HOUR', 'YEAR_MONTH', 'HOUR_MICROSECOND', 'DOY', 'MS', 'C', 'MILLENIUM', 'NSEC', 'YEARS', 'WEEKOFYEAR_ISO', 'HOURS', 'NS', 'MICROSECOND', 'DECADES', 'M', 'SECONDS', 'EPOCH_SECONDS', 'MILLISECS', 'EPOCH_MILLISECONDS', 'EPOCH_SECOND', 'QUARTER', 'NANOSECS', 'WEEKOFYEARISO', 'YY', 'MSECONDS', 'YRS', 'WK', 'SECS', 'MILLISECONDS', 'WOY', 'WEEKDAY', 'TZH', 'YYY', 'WEEK_ISO', 'MINUTES', 'MSEC', 'HOUR_MINUTE', 'DAYOFMONTH', 'NANOSEC', 'DEC', 'HR', 'MILLISECOND', 'MIN', 'MONS', 'QTRS', 'EPOCH_MICROSECONDS', 'H', 'DAY', 'SECOND', 'CENTS', 'EPOCH_MILLISECOND', 'US', 'MIL', 'HOUR_SECOND', 'MINUTE', 'DECADE', 'DAYOFYEAR', 'EPOCH_NANOSECOND', 'DAY_HOUR', 'TZM', 'WEEKISO', 'DECS', 'S', 'DAY_SECOND', 'WEEK', 'MICROSEC', 'MINS', 'YYYY', 'CENTURY', 'YR', 'USEC', 'CENTURIES', 'DAYOFWEEKISO', 'DAYOFWEEK', 'MINUTE_SECOND', 'DAYS', 'MINUTE_MICROSECOND', 'WEEKDAY_ISO', 'Y', 'MM', 'SEC', 'DY', 'DOW', 'MI', 'CENT', 'USECS', 'EPOCH_MICROSECOND', 'Q', 'SECOND_MICROSECOND', 'MILLISEC', 'EPOCH', 'QTR', 'DD', 'DAY_MINUTE', 'MILLENIA', 'DW_ISO', 'NSECOND', 'DAY_MICROSECOND', 'MICROSECONDS', 'W', 'USECONDS', 'DOW_ISO', 'EPOCH_NANOSECONDS', 'DAY OF YEAR', 'HOUR', 'NSECONDS', 'USECOND', 'MSECS', 'HH', 'HRS', 'NANOSECOND', 'WY', 'DAY OF WEEK', 'MILS'}
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}}}
198 class Tokenizer(tokens.Tokenizer): 199 QUOTES = ["'", '"'] 200 COMMENTS = ["--", "#", ("/*", "*/")] 201 IDENTIFIERS = ["`"] 202 STRING_ESCAPES = ["'", '"', "\\"] 203 BIT_STRINGS = [("b'", "'"), ("B'", "'"), ("0b", "")] 204 HEX_STRINGS = [("x'", "'"), ("X'", "'"), ("0x", "")] 205 206 NESTED_COMMENTS = False 207 208 KEYWORDS = { 209 **tokens.Tokenizer.KEYWORDS, 210 "BLOB": TokenType.BLOB, 211 "CHARSET": TokenType.CHARACTER_SET, 212 "DISTINCTROW": TokenType.DISTINCT, 213 "EXPLAIN": TokenType.DESCRIBE, 214 "FORCE": TokenType.FORCE, 215 "IGNORE": TokenType.IGNORE, 216 "KEY": TokenType.KEY, 217 "LOCK TABLES": TokenType.COMMAND, 218 "LONGBLOB": TokenType.LONGBLOB, 219 "LONGTEXT": TokenType.LONGTEXT, 220 "MEDIUMBLOB": TokenType.MEDIUMBLOB, 221 "MEDIUMINT": TokenType.MEDIUMINT, 222 "MEDIUMTEXT": TokenType.MEDIUMTEXT, 223 "MEMBER OF": TokenType.MEMBER_OF, 224 "MOD": TokenType.MOD, 225 "SEPARATOR": TokenType.SEPARATOR, 226 "SERIAL": TokenType.SERIAL, 227 "SIGNED": TokenType.BIGINT, 228 "SIGNED INTEGER": TokenType.BIGINT, 229 "SOUNDS LIKE": TokenType.SOUNDS_LIKE, 230 "START": TokenType.BEGIN, 231 "TIMESTAMP": TokenType.TIMESTAMPTZ, 232 "TINYBLOB": TokenType.TINYBLOB, 233 "TINYTEXT": TokenType.TINYTEXT, 234 "UNLOCK TABLES": TokenType.COMMAND, 235 "UNSIGNED": TokenType.UBIGINT, 236 "UNSIGNED INTEGER": TokenType.UBIGINT, 237 "YEAR": TokenType.YEAR, 238 "_ARMSCII8": TokenType.INTRODUCER, 239 "_ASCII": TokenType.INTRODUCER, 240 "_BIG5": TokenType.INTRODUCER, 241 "_BINARY": TokenType.INTRODUCER, 242 "_CP1250": TokenType.INTRODUCER, 243 "_CP1251": TokenType.INTRODUCER, 244 "_CP1256": TokenType.INTRODUCER, 245 "_CP1257": TokenType.INTRODUCER, 246 "_CP850": TokenType.INTRODUCER, 247 "_CP852": TokenType.INTRODUCER, 248 "_CP866": TokenType.INTRODUCER, 249 "_CP932": TokenType.INTRODUCER, 250 "_DEC8": TokenType.INTRODUCER, 251 "_EUCJPMS": TokenType.INTRODUCER, 252 "_EUCKR": TokenType.INTRODUCER, 253 "_GB18030": TokenType.INTRODUCER, 254 "_GB2312": TokenType.INTRODUCER, 255 "_GBK": TokenType.INTRODUCER, 256 "_GEOSTD8": TokenType.INTRODUCER, 257 "_GREEK": TokenType.INTRODUCER, 258 "_HEBREW": TokenType.INTRODUCER, 259 "_HP8": TokenType.INTRODUCER, 260 "_KEYBCS2": TokenType.INTRODUCER, 261 "_KOI8R": TokenType.INTRODUCER, 262 "_KOI8U": TokenType.INTRODUCER, 263 "_LATIN1": TokenType.INTRODUCER, 264 "_LATIN2": TokenType.INTRODUCER, 265 "_LATIN5": TokenType.INTRODUCER, 266 "_LATIN7": TokenType.INTRODUCER, 267 "_MACCE": TokenType.INTRODUCER, 268 "_MACROMAN": TokenType.INTRODUCER, 269 "_SJIS": TokenType.INTRODUCER, 270 "_SWE7": TokenType.INTRODUCER, 271 "_TIS620": TokenType.INTRODUCER, 272 "_UCS2": TokenType.INTRODUCER, 273 "_UJIS": TokenType.INTRODUCER, 274 # https://dev.mysql.com/doc/refman/8.0/en/string-literals.html 275 "_UTF8": TokenType.INTRODUCER, 276 "_UTF16": TokenType.INTRODUCER, 277 "_UTF16LE": TokenType.INTRODUCER, 278 "_UTF32": TokenType.INTRODUCER, 279 "_UTF8MB3": TokenType.INTRODUCER, 280 "_UTF8MB4": TokenType.INTRODUCER, 281 "@@": TokenType.SESSION_PARAMETER, 282 } 283 284 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'>, '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'>, 'SESSION': <TokenType.SESSION: 'SESSION'>, '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'>, 'REVOKE': <TokenType.REVOKE: 'REVOKE'>, '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'>, 'MOD': <TokenType.MOD: 'MOD'>, 'SEPARATOR': <TokenType.SEPARATOR: 'SEPARATOR'>, 'SERIAL': <TokenType.SERIAL: 'SERIAL'>, 'SIGNED': <TokenType.BIGINT: 'BIGINT'>, 'SIGNED INTEGER': <TokenType.BIGINT: 'BIGINT'>, 'SOUNDS LIKE': <TokenType.SOUNDS_LIKE: 'SOUNDS_LIKE'>, 'START': <TokenType.BEGIN: 'BEGIN'>, '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.RENAME: 'RENAME'>, <TokenType.EXECUTE: 'EXECUTE'>, <TokenType.REPLACE: 'REPLACE'>, <TokenType.FETCH: 'FETCH'>, <TokenType.COMMAND: 'COMMAND'>}
Inherited Members
- sqlglot.tokens.Tokenizer
- Tokenizer
- SINGLE_TOKENS
- BYTE_STRINGS
- RAW_STRINGS
- HEREDOC_STRINGS
- UNICODE_STRINGS
- VAR_SINGLE_TOKENS
- IDENTIFIER_ESCAPES
- HEREDOC_TAG_IS_IDENTIFIER
- HEREDOC_STRING_ALTERNATIVE
- STRING_ESCAPES_ALLOWED_IN_RAW_STRINGS
- HINT_START
- TOKENS_PRECEDING_HINT
- WHITE_SPACE
- COMMAND_PREFIX_TOKENS
- NUMERIC_LITERALS
- dialect
- use_rs_tokenizer
- reset
- tokenize
- tokenize_rs
- size
- sql
- tokens
286 class Parser(parser.Parser): 287 FUNC_TOKENS = { 288 *parser.Parser.FUNC_TOKENS, 289 TokenType.DATABASE, 290 TokenType.MOD, 291 TokenType.SCHEMA, 292 TokenType.VALUES, 293 } 294 295 CONJUNCTION = { 296 **parser.Parser.CONJUNCTION, 297 TokenType.DAMP: exp.And, 298 TokenType.XOR: exp.Xor, 299 } 300 301 DISJUNCTION = { 302 **parser.Parser.DISJUNCTION, 303 TokenType.DPIPE: exp.Or, 304 } 305 306 TABLE_ALIAS_TOKENS = ( 307 parser.Parser.TABLE_ALIAS_TOKENS - parser.Parser.TABLE_INDEX_HINT_TOKENS 308 ) 309 310 RANGE_PARSERS = { 311 **parser.Parser.RANGE_PARSERS, 312 TokenType.SOUNDS_LIKE: lambda self, this: self.expression( 313 exp.EQ, 314 this=self.expression(exp.Soundex, this=this), 315 expression=self.expression(exp.Soundex, this=self._parse_term()), 316 ), 317 TokenType.MEMBER_OF: lambda self, this: self.expression( 318 exp.JSONArrayContains, 319 this=this, 320 expression=self._parse_wrapped(self._parse_expression), 321 ), 322 } 323 324 FUNCTIONS = { 325 **parser.Parser.FUNCTIONS, 326 "BIT_AND": exp.BitwiseAndAgg.from_arg_list, 327 "BIT_OR": exp.BitwiseOrAgg.from_arg_list, 328 "BIT_XOR": exp.BitwiseXorAgg.from_arg_list, 329 "BIT_COUNT": exp.BitwiseCountAgg.from_arg_list, 330 "CONVERT_TZ": lambda args: exp.ConvertTimezone( 331 source_tz=seq_get(args, 1), target_tz=seq_get(args, 2), timestamp=seq_get(args, 0) 332 ), 333 "CURDATE": exp.CurrentDate.from_arg_list, 334 "DATE": lambda args: exp.TsOrDsToDate(this=seq_get(args, 0)), 335 "DATE_ADD": build_date_delta_with_interval(exp.DateAdd), 336 "DATE_FORMAT": build_formatted_time(exp.TimeToStr, "mysql"), 337 "DATE_SUB": build_date_delta_with_interval(exp.DateSub), 338 "DAY": lambda args: exp.Day(this=exp.TsOrDsToDate(this=seq_get(args, 0))), 339 "DAYOFMONTH": lambda args: exp.DayOfMonth(this=exp.TsOrDsToDate(this=seq_get(args, 0))), 340 "DAYOFWEEK": lambda args: exp.DayOfWeek(this=exp.TsOrDsToDate(this=seq_get(args, 0))), 341 "DAYOFYEAR": lambda args: exp.DayOfYear(this=exp.TsOrDsToDate(this=seq_get(args, 0))), 342 "FORMAT": exp.NumberToStr.from_arg_list, 343 "FROM_UNIXTIME": build_formatted_time(exp.UnixToTime, "mysql"), 344 "ISNULL": isnull_to_is_null, 345 "LENGTH": lambda args: exp.Length(this=seq_get(args, 0), binary=True), 346 "MAKETIME": exp.TimeFromParts.from_arg_list, 347 "MONTH": lambda args: exp.Month(this=exp.TsOrDsToDate(this=seq_get(args, 0))), 348 "MONTHNAME": lambda args: exp.TimeToStr( 349 this=exp.TsOrDsToDate(this=seq_get(args, 0)), 350 format=exp.Literal.string("%B"), 351 ), 352 "SCHEMA": exp.CurrentSchema.from_arg_list, 353 "DATABASE": exp.CurrentSchema.from_arg_list, 354 "STR_TO_DATE": _str_to_date, 355 "TIMESTAMPDIFF": build_date_delta(exp.TimestampDiff), 356 "TO_DAYS": lambda args: exp.paren( 357 exp.DateDiff( 358 this=exp.TsOrDsToDate(this=seq_get(args, 0)), 359 expression=exp.TsOrDsToDate(this=exp.Literal.string("0000-01-01")), 360 unit=exp.var("DAY"), 361 ) 362 + 1 363 ), 364 "WEEK": lambda args: exp.Week( 365 this=exp.TsOrDsToDate(this=seq_get(args, 0)), mode=seq_get(args, 1) 366 ), 367 "WEEKOFYEAR": lambda args: exp.WeekOfYear(this=exp.TsOrDsToDate(this=seq_get(args, 0))), 368 "YEAR": lambda args: exp.Year(this=exp.TsOrDsToDate(this=seq_get(args, 0))), 369 } 370 371 FUNCTION_PARSERS = { 372 **parser.Parser.FUNCTION_PARSERS, 373 "CHAR": lambda self: self.expression( 374 exp.Chr, 375 expressions=self._parse_csv(self._parse_assignment), 376 charset=self._match(TokenType.USING) and self._parse_var(), 377 ), 378 "GROUP_CONCAT": lambda self: self._parse_group_concat(), 379 # https://dev.mysql.com/doc/refman/5.7/en/miscellaneous-functions.html#function_values 380 "VALUES": lambda self: self.expression( 381 exp.Anonymous, this="VALUES", expressions=[self._parse_id_var()] 382 ), 383 "JSON_VALUE": lambda self: self._parse_json_value(), 384 "SUBSTR": lambda self: self._parse_substring(), 385 } 386 387 STATEMENT_PARSERS = { 388 **parser.Parser.STATEMENT_PARSERS, 389 TokenType.SHOW: lambda self: self._parse_show(), 390 } 391 392 SHOW_PARSERS = { 393 "BINARY LOGS": _show_parser("BINARY LOGS"), 394 "MASTER LOGS": _show_parser("BINARY LOGS"), 395 "BINLOG EVENTS": _show_parser("BINLOG EVENTS"), 396 "CHARACTER SET": _show_parser("CHARACTER SET"), 397 "CHARSET": _show_parser("CHARACTER SET"), 398 "COLLATION": _show_parser("COLLATION"), 399 "FULL COLUMNS": _show_parser("COLUMNS", target="FROM", full=True), 400 "COLUMNS": _show_parser("COLUMNS", target="FROM"), 401 "CREATE DATABASE": _show_parser("CREATE DATABASE", target=True), 402 "CREATE EVENT": _show_parser("CREATE EVENT", target=True), 403 "CREATE FUNCTION": _show_parser("CREATE FUNCTION", target=True), 404 "CREATE PROCEDURE": _show_parser("CREATE PROCEDURE", target=True), 405 "CREATE TABLE": _show_parser("CREATE TABLE", target=True), 406 "CREATE TRIGGER": _show_parser("CREATE TRIGGER", target=True), 407 "CREATE VIEW": _show_parser("CREATE VIEW", target=True), 408 "DATABASES": _show_parser("DATABASES"), 409 "SCHEMAS": _show_parser("DATABASES"), 410 "ENGINE": _show_parser("ENGINE", target=True), 411 "STORAGE ENGINES": _show_parser("ENGINES"), 412 "ENGINES": _show_parser("ENGINES"), 413 "ERRORS": _show_parser("ERRORS"), 414 "EVENTS": _show_parser("EVENTS"), 415 "FUNCTION CODE": _show_parser("FUNCTION CODE", target=True), 416 "FUNCTION STATUS": _show_parser("FUNCTION STATUS"), 417 "GRANTS": _show_parser("GRANTS", target="FOR"), 418 "INDEX": _show_parser("INDEX", target="FROM"), 419 "MASTER STATUS": _show_parser("MASTER STATUS"), 420 "OPEN TABLES": _show_parser("OPEN TABLES"), 421 "PLUGINS": _show_parser("PLUGINS"), 422 "PROCEDURE CODE": _show_parser("PROCEDURE CODE", target=True), 423 "PROCEDURE STATUS": _show_parser("PROCEDURE STATUS"), 424 "PRIVILEGES": _show_parser("PRIVILEGES"), 425 "FULL PROCESSLIST": _show_parser("PROCESSLIST", full=True), 426 "PROCESSLIST": _show_parser("PROCESSLIST"), 427 "PROFILE": _show_parser("PROFILE"), 428 "PROFILES": _show_parser("PROFILES"), 429 "RELAYLOG EVENTS": _show_parser("RELAYLOG EVENTS"), 430 "REPLICAS": _show_parser("REPLICAS"), 431 "SLAVE HOSTS": _show_parser("REPLICAS"), 432 "REPLICA STATUS": _show_parser("REPLICA STATUS"), 433 "SLAVE STATUS": _show_parser("REPLICA STATUS"), 434 "GLOBAL STATUS": _show_parser("STATUS", global_=True), 435 "SESSION STATUS": _show_parser("STATUS"), 436 "STATUS": _show_parser("STATUS"), 437 "TABLE STATUS": _show_parser("TABLE STATUS"), 438 "FULL TABLES": _show_parser("TABLES", full=True), 439 "TABLES": _show_parser("TABLES"), 440 "TRIGGERS": _show_parser("TRIGGERS"), 441 "GLOBAL VARIABLES": _show_parser("VARIABLES", global_=True), 442 "SESSION VARIABLES": _show_parser("VARIABLES"), 443 "VARIABLES": _show_parser("VARIABLES"), 444 "WARNINGS": _show_parser("WARNINGS"), 445 } 446 447 PROPERTY_PARSERS = { 448 **parser.Parser.PROPERTY_PARSERS, 449 "LOCK": lambda self: self._parse_property_assignment(exp.LockProperty), 450 } 451 452 SET_PARSERS = { 453 **parser.Parser.SET_PARSERS, 454 "PERSIST": lambda self: self._parse_set_item_assignment("PERSIST"), 455 "PERSIST_ONLY": lambda self: self._parse_set_item_assignment("PERSIST_ONLY"), 456 "CHARACTER SET": lambda self: self._parse_set_item_charset("CHARACTER SET"), 457 "CHARSET": lambda self: self._parse_set_item_charset("CHARACTER SET"), 458 "NAMES": lambda self: self._parse_set_item_names(), 459 } 460 461 CONSTRAINT_PARSERS = { 462 **parser.Parser.CONSTRAINT_PARSERS, 463 "FULLTEXT": lambda self: self._parse_index_constraint(kind="FULLTEXT"), 464 "INDEX": lambda self: self._parse_index_constraint(), 465 "KEY": lambda self: self._parse_index_constraint(), 466 "SPATIAL": lambda self: self._parse_index_constraint(kind="SPATIAL"), 467 } 468 469 ALTER_PARSERS = { 470 **parser.Parser.ALTER_PARSERS, 471 "MODIFY": lambda self: self._parse_alter_table_alter(), 472 } 473 474 ALTER_ALTER_PARSERS = { 475 **parser.Parser.ALTER_ALTER_PARSERS, 476 "INDEX": lambda self: self._parse_alter_table_alter_index(), 477 } 478 479 SCHEMA_UNNAMED_CONSTRAINTS = { 480 *parser.Parser.SCHEMA_UNNAMED_CONSTRAINTS, 481 "FULLTEXT", 482 "INDEX", 483 "KEY", 484 "SPATIAL", 485 } 486 487 PROFILE_TYPES: parser.OPTIONS_TYPE = { 488 **dict.fromkeys(("ALL", "CPU", "IPC", "MEMORY", "SOURCE", "SWAPS"), tuple()), 489 "BLOCK": ("IO",), 490 "CONTEXT": ("SWITCHES",), 491 "PAGE": ("FAULTS",), 492 } 493 494 TYPE_TOKENS = { 495 *parser.Parser.TYPE_TOKENS, 496 TokenType.SET, 497 } 498 499 ENUM_TYPE_TOKENS = { 500 *parser.Parser.ENUM_TYPE_TOKENS, 501 TokenType.SET, 502 } 503 504 # SELECT [ ALL | DISTINCT | DISTINCTROW ] [ <OPERATION_MODIFIERS> ] 505 OPERATION_MODIFIERS = { 506 "HIGH_PRIORITY", 507 "STRAIGHT_JOIN", 508 "SQL_SMALL_RESULT", 509 "SQL_BIG_RESULT", 510 "SQL_BUFFER_RESULT", 511 "SQL_NO_CACHE", 512 "SQL_CALC_FOUND_ROWS", 513 } 514 515 LOG_DEFAULTS_TO_LN = True 516 STRING_ALIASES = True 517 VALUES_FOLLOWED_BY_PAREN = False 518 SUPPORTS_PARTITION_SELECTION = True 519 520 def _parse_generated_as_identity( 521 self, 522 ) -> ( 523 exp.GeneratedAsIdentityColumnConstraint 524 | exp.ComputedColumnConstraint 525 | exp.GeneratedAsRowColumnConstraint 526 ): 527 this = super()._parse_generated_as_identity() 528 529 if self._match_texts(("STORED", "VIRTUAL")): 530 persisted = self._prev.text.upper() == "STORED" 531 532 if isinstance(this, exp.ComputedColumnConstraint): 533 this.set("persisted", persisted) 534 elif isinstance(this, exp.GeneratedAsIdentityColumnConstraint): 535 this = self.expression( 536 exp.ComputedColumnConstraint, this=this.expression, persisted=persisted 537 ) 538 539 return this 540 541 def _parse_primary_key_part(self) -> t.Optional[exp.Expression]: 542 this = self._parse_id_var() 543 if not self._match(TokenType.L_PAREN): 544 return this 545 546 expression = self._parse_number() 547 self._match_r_paren() 548 return self.expression(exp.ColumnPrefix, this=this, expression=expression) 549 550 def _parse_index_constraint( 551 self, kind: t.Optional[str] = None 552 ) -> exp.IndexColumnConstraint: 553 if kind: 554 self._match_texts(("INDEX", "KEY")) 555 556 this = self._parse_id_var(any_token=False) 557 index_type = self._match(TokenType.USING) and self._advance_any() and self._prev.text 558 expressions = self._parse_wrapped_csv(self._parse_ordered) 559 560 options = [] 561 while True: 562 if self._match_text_seq("KEY_BLOCK_SIZE"): 563 self._match(TokenType.EQ) 564 opt = exp.IndexConstraintOption(key_block_size=self._parse_number()) 565 elif self._match(TokenType.USING): 566 opt = exp.IndexConstraintOption(using=self._advance_any() and self._prev.text) 567 elif self._match_text_seq("WITH", "PARSER"): 568 opt = exp.IndexConstraintOption(parser=self._parse_var(any_token=True)) 569 elif self._match(TokenType.COMMENT): 570 opt = exp.IndexConstraintOption(comment=self._parse_string()) 571 elif self._match_text_seq("VISIBLE"): 572 opt = exp.IndexConstraintOption(visible=True) 573 elif self._match_text_seq("INVISIBLE"): 574 opt = exp.IndexConstraintOption(visible=False) 575 elif self._match_text_seq("ENGINE_ATTRIBUTE"): 576 self._match(TokenType.EQ) 577 opt = exp.IndexConstraintOption(engine_attr=self._parse_string()) 578 elif self._match_text_seq("SECONDARY_ENGINE_ATTRIBUTE"): 579 self._match(TokenType.EQ) 580 opt = exp.IndexConstraintOption(secondary_engine_attr=self._parse_string()) 581 else: 582 opt = None 583 584 if not opt: 585 break 586 587 options.append(opt) 588 589 return self.expression( 590 exp.IndexColumnConstraint, 591 this=this, 592 expressions=expressions, 593 kind=kind, 594 index_type=index_type, 595 options=options, 596 ) 597 598 def _parse_show_mysql( 599 self, 600 this: str, 601 target: bool | str = False, 602 full: t.Optional[bool] = None, 603 global_: t.Optional[bool] = None, 604 ) -> exp.Show: 605 json = self._match_text_seq("JSON") 606 607 if target: 608 if isinstance(target, str): 609 self._match_text_seq(*target.split(" ")) 610 target_id = self._parse_id_var() 611 else: 612 target_id = None 613 614 log = self._parse_string() if self._match_text_seq("IN") else None 615 616 if this in ("BINLOG EVENTS", "RELAYLOG EVENTS"): 617 position = self._parse_number() if self._match_text_seq("FROM") else None 618 db = None 619 else: 620 position = None 621 db = None 622 623 if self._match(TokenType.FROM): 624 db = self._parse_id_var() 625 elif self._match(TokenType.DOT): 626 db = target_id 627 target_id = self._parse_id_var() 628 629 channel = self._parse_id_var() if self._match_text_seq("FOR", "CHANNEL") else None 630 631 like = self._parse_string() if self._match_text_seq("LIKE") else None 632 where = self._parse_where() 633 634 if this == "PROFILE": 635 types = self._parse_csv(lambda: self._parse_var_from_options(self.PROFILE_TYPES)) 636 query = self._parse_number() if self._match_text_seq("FOR", "QUERY") else None 637 offset = self._parse_number() if self._match_text_seq("OFFSET") else None 638 limit = self._parse_number() if self._match_text_seq("LIMIT") else None 639 else: 640 types, query = None, None 641 offset, limit = self._parse_oldstyle_limit() 642 643 mutex = True if self._match_text_seq("MUTEX") else None 644 mutex = False if self._match_text_seq("STATUS") else mutex 645 646 for_table = self._parse_id_var() if self._match_text_seq("FOR", "TABLE") else None 647 for_group = self._parse_string() if self._match_text_seq("FOR", "GROUP") else None 648 for_user = self._parse_string() if self._match_text_seq("FOR", "USER") else None 649 for_role = self._parse_string() if self._match_text_seq("FOR", "ROLE") else None 650 into_outfile = self._parse_string() if self._match_text_seq("INTO", "OUTFILE") else None 651 652 return self.expression( 653 exp.Show, 654 this=this, 655 target=target_id, 656 full=full, 657 log=log, 658 position=position, 659 db=db, 660 channel=channel, 661 like=like, 662 where=where, 663 types=types, 664 query=query, 665 offset=offset, 666 limit=limit, 667 mutex=mutex, 668 for_table=for_table, 669 for_group=for_group, 670 for_user=for_user, 671 for_role=for_role, 672 into_outfile=into_outfile, 673 json=json, 674 **{"global": global_}, # type: ignore 675 ) 676 677 def _parse_oldstyle_limit( 678 self, 679 ) -> t.Tuple[t.Optional[exp.Expression], t.Optional[exp.Expression]]: 680 limit = None 681 offset = None 682 if self._match_text_seq("LIMIT"): 683 parts = self._parse_csv(self._parse_number) 684 if len(parts) == 1: 685 limit = parts[0] 686 elif len(parts) == 2: 687 limit = parts[1] 688 offset = parts[0] 689 690 return offset, limit 691 692 def _parse_set_item_charset(self, kind: str) -> exp.Expression: 693 this = self._parse_string() or self._parse_unquoted_field() 694 return self.expression(exp.SetItem, this=this, kind=kind) 695 696 def _parse_set_item_names(self) -> exp.Expression: 697 charset = self._parse_string() or self._parse_unquoted_field() 698 if self._match_text_seq("COLLATE"): 699 collate = self._parse_string() or self._parse_unquoted_field() 700 else: 701 collate = None 702 703 return self.expression(exp.SetItem, this=charset, collate=collate, kind="NAMES") 704 705 def _parse_type( 706 self, parse_interval: bool = True, fallback_to_identifier: bool = False 707 ) -> t.Optional[exp.Expression]: 708 # mysql binary is special and can work anywhere, even in order by operations 709 # it operates like a no paren func 710 if self._match(TokenType.BINARY, advance=False): 711 data_type = self._parse_types(check_func=True, allow_identifiers=False) 712 713 if isinstance(data_type, exp.DataType): 714 return self.expression(exp.Cast, this=self._parse_column(), to=data_type) 715 716 return super()._parse_type( 717 parse_interval=parse_interval, fallback_to_identifier=fallback_to_identifier 718 ) 719 720 def _parse_alter_table_alter_index(self) -> exp.AlterIndex: 721 index = self._parse_field(any_token=True) 722 723 if self._match_text_seq("VISIBLE"): 724 visible = True 725 elif self._match_text_seq("INVISIBLE"): 726 visible = False 727 else: 728 visible = None 729 730 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.RIGHT: 'RIGHT'>, <TokenType.INDEX: 'INDEX'>, <TokenType.LIKE: 'LIKE'>, <TokenType.POINT: 'POINT'>, <TokenType.INT256: 'INT256'>, <TokenType.IDENTIFIER: 'IDENTIFIER'>, <TokenType.ISNULL: 'ISNULL'>, <TokenType.DECIMAL64: 'DECIMAL64'>, <TokenType.SMALLINT: 'SMALLINT'>, <TokenType.BIGDECIMAL: 'BIGDECIMAL'>, <TokenType.LONGBLOB: 'LONGBLOB'>, <TokenType.DATE32: 'DATE32'>, <TokenType.TABLE: 'TABLE'>, <TokenType.DYNAMIC: 'DYNAMIC'>, <TokenType.YEAR: 'YEAR'>, <TokenType.DOUBLE: 'DOUBLE'>, <TokenType.CHAR: 'CHAR'>, <TokenType.COLLATE: 'COLLATE'>, <TokenType.MEDIUMTEXT: 'MEDIUMTEXT'>, <TokenType.TIMESTAMPNTZ: 'TIMESTAMPNTZ'>, <TokenType.VARCHAR: 'VARCHAR'>, <TokenType.SEQUENCE: 'SEQUENCE'>, <TokenType.TDIGEST: 'TDIGEST'>, <TokenType.NOTHING: 'NOTHING'>, <TokenType.ENUM: 'ENUM'>, <TokenType.NESTED: 'NESTED'>, <TokenType.FIXEDSTRING: 'FIXEDSTRING'>, <TokenType.BOOLEAN: 'BOOLEAN'>, <TokenType.FILTER: 'FILTER'>, <TokenType.IPV6: 'IPV6'>, <TokenType.DATEMULTIRANGE: 'DATEMULTIRANGE'>, <TokenType.TSMULTIRANGE: 'TSMULTIRANGE'>, <TokenType.MONEY: 'MONEY'>, <TokenType.RANGE: 'RANGE'>, <TokenType.PRIMARY_KEY: 'PRIMARY_KEY'>, <TokenType.CURRENT_DATE: 'CURRENT_DATE'>, <TokenType.ARRAY: 'ARRAY'>, <TokenType.NVARCHAR: 'NVARCHAR'>, <TokenType.INT4MULTIRANGE: 'INT4MULTIRANGE'>, <TokenType.FORMAT: 'FORMAT'>, <TokenType.FLOAT: 'FLOAT'>, <TokenType.ENUM16: 'ENUM16'>, <TokenType.MULTILINESTRING: 'MULTILINESTRING'>, <TokenType.NUMMULTIRANGE: 'NUMMULTIRANGE'>, <TokenType.UTC_TIME: 'UTC_TIME'>, <TokenType.DECIMAL32: 'DECIMAL32'>, <TokenType.OFFSET: 'OFFSET'>, <TokenType.DATABASE: 'DATABASE'>, <TokenType.LEFT: 'LEFT'>, <TokenType.INT128: 'INT128'>, <TokenType.IPV4: 'IPV4'>, <TokenType.MAP: 'MAP'>, <TokenType.MOD: 'MOD'>, <TokenType.GEOMETRY: 'GEOMETRY'>, <TokenType.UNNEST: 'UNNEST'>, <TokenType.UMEDIUMINT: 'UMEDIUMINT'>, <TokenType.DECIMAL256: 'DECIMAL256'>, <TokenType.IPPREFIX: 'IPPREFIX'>, <TokenType.HLLSKETCH: 'HLLSKETCH'>, <TokenType.DECIMAL: 'DECIMAL'>, <TokenType.UTC_DATE: 'UTC_DATE'>, <TokenType.TSTZRANGE: 'TSTZRANGE'>, <TokenType.GEOGRAPHY: 'GEOGRAPHY'>, <TokenType.DATERANGE: 'DATERANGE'>, <TokenType.TINYTEXT: 'TINYTEXT'>, <TokenType.TIME: 'TIME'>, <TokenType.RLIKE: 'RLIKE'>, <TokenType.ENUM8: 'ENUM8'>, <TokenType.GLOB: 'GLOB'>, <TokenType.SIMPLEAGGREGATEFUNCTION: 'SIMPLEAGGREGATEFUNCTION'>, <TokenType.DATE: 'DATE'>, <TokenType.CURRENT_TIME: 'CURRENT_TIME'>, <TokenType.TIMESTAMP: 'TIMESTAMP'>, <TokenType.GEOGRAPHYPOINT: 'GEOGRAPHYPOINT'>, <TokenType.LIST: 'LIST'>, <TokenType.RING: 'RING'>, <TokenType.VOID: 'VOID'>, <TokenType.DATETIME: 'DATETIME'>, <TokenType.EXISTS: 'EXISTS'>, <TokenType.SUPER: 'SUPER'>, <TokenType.MULTIPOLYGON: 'MULTIPOLYGON'>, <TokenType.VALUES: 'VALUES'>, <TokenType.NULLABLE: 'NULLABLE'>, <TokenType.DECIMAL128: 'DECIMAL128'>, <TokenType.VARBINARY: 'VARBINARY'>, <TokenType.CURRENT_USER: 'CURRENT_USER'>, <TokenType.INT: 'INT'>, <TokenType.UTINYINT: 'UTINYINT'>, <TokenType.OBJECT_IDENTIFIER: 'OBJECT_IDENTIFIER'>, <TokenType.ALL: 'ALL'>, <TokenType.WINDOW: 'WINDOW'>, <TokenType.TIMESTAMPTZ: 'TIMESTAMPTZ'>, <TokenType.IPADDRESS: 'IPADDRESS'>, <TokenType.BPCHAR: 'BPCHAR'>, <TokenType.INT8RANGE: 'INT8RANGE'>, <TokenType.MERGE: 'MERGE'>, <TokenType.NAME: 'NAME'>, <TokenType.NULL: 'NULL'>, <TokenType.NUMRANGE: 'NUMRANGE'>, <TokenType.USERDEFINED: 'USERDEFINED'>, <TokenType.NEXT: 'NEXT'>, <TokenType.AGGREGATEFUNCTION: 'AGGREGATEFUNCTION'>, <TokenType.STRUCT: 'STRUCT'>, <TokenType.JSON: 'JSON'>, <TokenType.UTC_TIMESTAMP: 'UTC_TIMESTAMP'>, <TokenType.CURRENT_DATETIME: 'CURRENT_DATETIME'>, <TokenType.CURRENT_TIMESTAMP: 'CURRENT_TIMESTAMP'>, <TokenType.TEXT: 'TEXT'>, <TokenType.PSEUDO_TYPE: 'PSEUDO_TYPE'>, <TokenType.SOME: 'SOME'>, <TokenType.UDOUBLE: 'UDOUBLE'>, <TokenType.TIMESTAMP_MS: 'TIMESTAMP_MS'>, <TokenType.LONGTEXT: 'LONGTEXT'>, <TokenType.DATETIME2: 'DATETIME2'>, <TokenType.UINT128: 'UINT128'>, <TokenType.USMALLINT: 'USMALLINT'>, <TokenType.VAR: 'VAR'>, <TokenType.SMALLMONEY: 'SMALLMONEY'>, <TokenType.TINYBLOB: 'TINYBLOB'>, <TokenType.SMALLDATETIME: 'SMALLDATETIME'>, <TokenType.ANY: 'ANY'>, <TokenType.COMMAND: 'COMMAND'>, <TokenType.BIT: 'BIT'>, <TokenType.UINT: 'UINT'>, <TokenType.TSTZMULTIRANGE: 'TSTZMULTIRANGE'>, <TokenType.TINYINT: 'TINYINT'>, <TokenType.JSONB: 'JSONB'>, <TokenType.REPLACE: 'REPLACE'>, <TokenType.BIGSERIAL: 'BIGSERIAL'>, <TokenType.SERIAL: 'SERIAL'>, <TokenType.ROWVERSION: 'ROWVERSION'>, <TokenType.UBIGINT: 'UBIGINT'>, <TokenType.INTERVAL: 'INTERVAL'>, <TokenType.UINT256: 'UINT256'>, <TokenType.TSRANGE: 'TSRANGE'>, <TokenType.ROW: 'ROW'>, <TokenType.INT4RANGE: 'INT4RANGE'>, <TokenType.FIRST: 'FIRST'>, <TokenType.HSTORE: 'HSTORE'>, <TokenType.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, <TokenType.XOR: 'XOR'>, <TokenType.INET: 'INET'>, <TokenType.GET: 'GET'>, <TokenType.UNION: 'UNION'>, <TokenType.POLYGON: 'POLYGON'>, <TokenType.LINESTRING: 'LINESTRING'>, <TokenType.DATETIME64: 'DATETIME64'>, <TokenType.XML: 'XML'>, <TokenType.UNKNOWN: 'UNKNOWN'>, <TokenType.ILIKE: 'ILIKE'>, <TokenType.TIMESTAMP_NS: 'TIMESTAMP_NS'>, <TokenType.OBJECT: 'OBJECT'>, <TokenType.SCHEMA: 'SCHEMA'>, <TokenType.UUID: 'UUID'>, <TokenType.INSERT: 'INSERT'>, <TokenType.TIMESTAMP_S: 'TIMESTAMP_S'>, <TokenType.MEDIUMBLOB: 'MEDIUMBLOB'>, <TokenType.VECTOR: 'VECTOR'>, <TokenType.BLOB: 'BLOB'>, <TokenType.NCHAR: 'NCHAR'>, <TokenType.UDECIMAL: 'UDECIMAL'>, <TokenType.SMALLSERIAL: 'SMALLSERIAL'>, <TokenType.LOWCARDINALITY: 'LOWCARDINALITY'>, <TokenType.CURRENT_SCHEMA: 'CURRENT_SCHEMA'>, <TokenType.TIMETZ: 'TIMETZ'>, <TokenType.BINARY: 'BINARY'>, <TokenType.INT8MULTIRANGE: 'INT8MULTIRANGE'>, <TokenType.BIGINT: 'BIGINT'>, <TokenType.IMAGE: 'IMAGE'>, <TokenType.MEDIUMINT: 'MEDIUMINT'>, <TokenType.VARIANT: 'VARIANT'>, <TokenType.TRUNCATE: 'TRUNCATE'>}
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.INDEX: 'INDEX'>, <TokenType.POINT: 'POINT'>, <TokenType.INT256: 'INT256'>, <TokenType.IDENTIFIER: 'IDENTIFIER'>, <TokenType.ISNULL: 'ISNULL'>, <TokenType.DECIMAL64: 'DECIMAL64'>, <TokenType.SMALLINT: 'SMALLINT'>, <TokenType.BIGDECIMAL: 'BIGDECIMAL'>, <TokenType.LONGBLOB: 'LONGBLOB'>, <TokenType.DATE32: 'DATE32'>, <TokenType.TABLE: 'TABLE'>, <TokenType.DYNAMIC: 'DYNAMIC'>, <TokenType.EXECUTE: 'EXECUTE'>, <TokenType.YEAR: 'YEAR'>, <TokenType.DOUBLE: 'DOUBLE'>, <TokenType.CHAR: 'CHAR'>, <TokenType.COPY: 'COPY'>, <TokenType.COLLATE: 'COLLATE'>, <TokenType.MEDIUMTEXT: 'MEDIUMTEXT'>, <TokenType.TIMESTAMPNTZ: 'TIMESTAMPNTZ'>, <TokenType.VARCHAR: 'VARCHAR'>, <TokenType.SEQUENCE: 'SEQUENCE'>, <TokenType.TDIGEST: 'TDIGEST'>, <TokenType.NOTHING: 'NOTHING'>, <TokenType.ENUM: 'ENUM'>, <TokenType.NESTED: 'NESTED'>, <TokenType.FIXEDSTRING: 'FIXEDSTRING'>, <TokenType.BOOLEAN: 'BOOLEAN'>, <TokenType.FILTER: 'FILTER'>, <TokenType.IPV6: 'IPV6'>, <TokenType.DATEMULTIRANGE: 'DATEMULTIRANGE'>, <TokenType.TSMULTIRANGE: 'TSMULTIRANGE'>, <TokenType.MONEY: 'MONEY'>, <TokenType.RANGE: 'RANGE'>, <TokenType.LOAD: 'LOAD'>, <TokenType.DEFAULT: 'DEFAULT'>, <TokenType.MODEL: 'MODEL'>, <TokenType.CURRENT_DATE: 'CURRENT_DATE'>, <TokenType.CACHE: 'CACHE'>, <TokenType.ARRAY: 'ARRAY'>, <TokenType.NVARCHAR: 'NVARCHAR'>, <TokenType.PROCEDURE: 'PROCEDURE'>, <TokenType.INT4MULTIRANGE: 'INT4MULTIRANGE'>, <TokenType.FORMAT: 'FORMAT'>, <TokenType.FLOAT: 'FLOAT'>, <TokenType.EXPORT: 'EXPORT'>, <TokenType.ENUM16: 'ENUM16'>, <TokenType.MULTILINESTRING: 'MULTILINESTRING'>, <TokenType.NUMMULTIRANGE: 'NUMMULTIRANGE'>, <TokenType.DECIMAL32: 'DECIMAL32'>, <TokenType.OFFSET: 'OFFSET'>, <TokenType.DATABASE: 'DATABASE'>, <TokenType.INT128: 'INT128'>, <TokenType.UPDATE: 'UPDATE'>, <TokenType.IPV4: 'IPV4'>, <TokenType.MAP: 'MAP'>, <TokenType.COLUMN: 'COLUMN'>, <TokenType.GEOMETRY: 'GEOMETRY'>, <TokenType.ATTACH: 'ATTACH'>, <TokenType.UNNEST: 'UNNEST'>, <TokenType.APPLY: 'APPLY'>, <TokenType.UMEDIUMINT: 'UMEDIUMINT'>, <TokenType.DECIMAL256: 'DECIMAL256'>, <TokenType.IPPREFIX: 'IPPREFIX'>, <TokenType.AUTO_INCREMENT: 'AUTO_INCREMENT'>, <TokenType.HLLSKETCH: 'HLLSKETCH'>, <TokenType.DECIMAL: 'DECIMAL'>, <TokenType.TSTZRANGE: 'TSTZRANGE'>, <TokenType.LIMIT: 'LIMIT'>, <TokenType.GEOGRAPHY: 'GEOGRAPHY'>, <TokenType.DATERANGE: 'DATERANGE'>, <TokenType.TINYTEXT: 'TINYTEXT'>, <TokenType.TIME: 'TIME'>, <TokenType.RECURSIVE: 'RECURSIVE'>, <TokenType.ENUM8: 'ENUM8'>, <TokenType.SIMPLEAGGREGATEFUNCTION: 'SIMPLEAGGREGATEFUNCTION'>, <TokenType.KEEP: 'KEEP'>, <TokenType.TOP: 'TOP'>, <TokenType.DATE: 'DATE'>, <TokenType.CURRENT_TIME: 'CURRENT_TIME'>, <TokenType.TIMESTAMP: 'TIMESTAMP'>, <TokenType.GEOGRAPHYPOINT: 'GEOGRAPHYPOINT'>, <TokenType.BEGIN: 'BEGIN'>, <TokenType.LIST: 'LIST'>, <TokenType.RING: 'RING'>, <TokenType.COMMIT: 'COMMIT'>, <TokenType.SHOW: 'SHOW'>, <TokenType.OPERATOR: 'OPERATOR'>, <TokenType.RENAME: 'RENAME'>, <TokenType.EXISTS: 'EXISTS'>, <TokenType.PERCENT: 'PERCENT'>, <TokenType.VOID: 'VOID'>, <TokenType.DATETIME: 'DATETIME'>, <TokenType.SUPER: 'SUPER'>, <TokenType.MULTIPOLYGON: 'MULTIPOLYGON'>, <TokenType.OVERWRITE: 'OVERWRITE'>, <TokenType.NULLABLE: 'NULLABLE'>, <TokenType.DECIMAL128: 'DECIMAL128'>, <TokenType.SEMI: 'SEMI'>, <TokenType.END: 'END'>, <TokenType.VARBINARY: 'VARBINARY'>, <TokenType.UNPIVOT: 'UNPIVOT'>, <TokenType.CURRENT_USER: 'CURRENT_USER'>, <TokenType.INT: 'INT'>, <TokenType.STAGE: 'STAGE'>, <TokenType.UTINYINT: 'UTINYINT'>, <TokenType.FUNCTION: 'FUNCTION'>, <TokenType.REFRESH: 'REFRESH'>, <TokenType.OBJECT_IDENTIFIER: 'OBJECT_IDENTIFIER'>, <TokenType.ALL: 'ALL'>, <TokenType.DIV: 'DIV'>, <TokenType.WAREHOUSE: 'WAREHOUSE'>, <TokenType.TIMESTAMPTZ: 'TIMESTAMPTZ'>, <TokenType.IPADDRESS: 'IPADDRESS'>, <TokenType.BPCHAR: 'BPCHAR'>, <TokenType.INT8RANGE: 'INT8RANGE'>, <TokenType.MERGE: 'MERGE'>, <TokenType.FALSE: 'FALSE'>, <TokenType.TEMPORARY: 'TEMPORARY'>, <TokenType.TRUE: 'TRUE'>, <TokenType.NAME: 'NAME'>, <TokenType.NULL: 'NULL'>, <TokenType.STORAGE_INTEGRATION: 'STORAGE_INTEGRATION'>, <TokenType.NUMRANGE: 'NUMRANGE'>, <TokenType.USERDEFINED: 'USERDEFINED'>, <TokenType.NEXT: 'NEXT'>, <TokenType.REFERENCES: 'REFERENCES'>, <TokenType.AGGREGATEFUNCTION: 'AGGREGATEFUNCTION'>, <TokenType.STRUCT: 'STRUCT'>, <TokenType.JSON: 'JSON'>, <TokenType.SINK: 'SINK'>, <TokenType.TEXT: 'TEXT'>, <TokenType.CURRENT_DATETIME: 'CURRENT_DATETIME'>, <TokenType.PSEUDO_TYPE: 'PSEUDO_TYPE'>, <TokenType.CURRENT_TIMESTAMP: 'CURRENT_TIMESTAMP'>, <TokenType.SOME: 'SOME'>, <TokenType.ORDINALITY: 'ORDINALITY'>, <TokenType.NAMESPACE: 'NAMESPACE'>, <TokenType.UNIQUE: 'UNIQUE'>, <TokenType.DICTIONARY: 'DICTIONARY'>, <TokenType.UDOUBLE: 'UDOUBLE'>, <TokenType.KILL: 'KILL'>, <TokenType.SESSION: 'SESSION'>, <TokenType.TIMESTAMP_MS: 'TIMESTAMP_MS'>, <TokenType.LONGTEXT: 'LONGTEXT'>, <TokenType.ASC: 'ASC'>, <TokenType.DATETIME2: 'DATETIME2'>, <TokenType.UINT128: 'UINT128'>, <TokenType.USMALLINT: 'USMALLINT'>, <TokenType.VAR: 'VAR'>, <TokenType.PRAGMA: 'PRAGMA'>, <TokenType.SMALLMONEY: 'SMALLMONEY'>, <TokenType.CONSTRAINT: 'CONSTRAINT'>, <TokenType.ROWS: 'ROWS'>, <TokenType.SET: 'SET'>, <TokenType.TINYBLOB: 'TINYBLOB'>, <TokenType.SMALLDATETIME: 'SMALLDATETIME'>, <TokenType.PIVOT: 'PIVOT'>, <TokenType.ANY: 'ANY'>, <TokenType.COMMAND: 'COMMAND'>, <TokenType.BIT: 'BIT'>, <TokenType.OVERLAPS: 'OVERLAPS'>, <TokenType.UINT: 'UINT'>, <TokenType.TSTZMULTIRANGE: 'TSTZMULTIRANGE'>, <TokenType.SEMANTIC_VIEW: 'SEMANTIC_VIEW'>, <TokenType.TINYINT: 'TINYINT'>, <TokenType.JSONB: 'JSONB'>, <TokenType.REPLACE: 'REPLACE'>, <TokenType.BIGSERIAL: 'BIGSERIAL'>, <TokenType.ANTI: 'ANTI'>, <TokenType.PARTITION: 'PARTITION'>, <TokenType.SERIAL: 'SERIAL'>, <TokenType.ROWVERSION: 'ROWVERSION'>, <TokenType.DESC: 'DESC'>, <TokenType.UBIGINT: 'UBIGINT'>, <TokenType.INTERVAL: 'INTERVAL'>, <TokenType.FOREIGN_KEY: 'FOREIGN_KEY'>, <TokenType.DESCRIBE: 'DESCRIBE'>, <TokenType.UINT256: 'UINT256'>, <TokenType.IS: 'IS'>, <TokenType.TAG: 'TAG'>, <TokenType.ROW: 'ROW'>, <TokenType.TSRANGE: 'TSRANGE'>, <TokenType.CASE: 'CASE'>, <TokenType.INT4RANGE: 'INT4RANGE'>, <TokenType.SOURCE: 'SOURCE'>, <TokenType.DELETE: 'DELETE'>, <TokenType.FIRST: 'FIRST'>, <TokenType.HSTORE: 'HSTORE'>, <TokenType.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, <TokenType.FINAL: 'FINAL'>, <TokenType.INET: 'INET'>, <TokenType.GET: 'GET'>, <TokenType.DETACH: 'DETACH'>, <TokenType.POLYGON: 'POLYGON'>, <TokenType.ROLLUP: 'ROLLUP'>, <TokenType.VIEW: 'VIEW'>, <TokenType.LINESTRING: 'LINESTRING'>, <TokenType.DATETIME64: 'DATETIME64'>, <TokenType.XML: 'XML'>, <TokenType.UNKNOWN: 'UNKNOWN'>, <TokenType.STREAMLIT: 'STREAMLIT'>, <TokenType.CUBE: 'CUBE'>, <TokenType.TIMESTAMP_NS: 'TIMESTAMP_NS'>, <TokenType.SCHEMA: 'SCHEMA'>, <TokenType.OBJECT: 'OBJECT'>, <TokenType.UUID: 'UUID'>, <TokenType.VOLATILE: 'VOLATILE'>, <TokenType.TIMESTAMP_S: 'TIMESTAMP_S'>, <TokenType.ESCAPE: 'ESCAPE'>, <TokenType.MEDIUMBLOB: 'MEDIUMBLOB'>, <TokenType.VECTOR: 'VECTOR'>, <TokenType.FILE_FORMAT: 'FILE_FORMAT'>, <TokenType.BLOB: 'BLOB'>, <TokenType.NCHAR: 'NCHAR'>, <TokenType.UDECIMAL: 'UDECIMAL'>, <TokenType.SMALLSERIAL: 'SMALLSERIAL'>, <TokenType.LOWCARDINALITY: 'LOWCARDINALITY'>, <TokenType.CURRENT_SCHEMA: 'CURRENT_SCHEMA'>, <TokenType.TIMETZ: 'TIMETZ'>, <TokenType.BINARY: 'BINARY'>, <TokenType.INT8MULTIRANGE: 'INT8MULTIRANGE'>, <TokenType.BIGINT: 'BIGINT'>, <TokenType.IMAGE: 'IMAGE'>, <TokenType.MEDIUMINT: 'MEDIUMINT'>, <TokenType.PUT: 'PUT'>, <TokenType.SETTINGS: 'SETTINGS'>, <TokenType.VARIANT: 'VARIANT'>, <TokenType.TRUNCATE: 'TRUNCATE'>, <TokenType.COMMENT: 'COMMENT'>}
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.QMARK_AMP: 'QMARK_AMP'>: <function binary_range_parser.<locals>._parse_binary_range>, <TokenType.QMARK_PIPE: 'QMARK_PIPE'>: <function binary_range_parser.<locals>._parse_binary_range>, <TokenType.HASH_DASH: 'HASH_DASH'>: <function binary_range_parser.<locals>._parse_binary_range>, <TokenType.SOUNDS_LIKE: 'SOUNDS_LIKE'>: <function MySQL.Parser.<lambda>>, <TokenType.MEMBER_OF: 'MEMBER_OF'>: <function MySQL.Parser.<lambda>>}
FUNCTIONS =
{'AI_AGG': <bound method Func.from_arg_list of <class 'sqlglot.expressions.AIAgg'>>, 'AI_CLASSIFY': <bound method Func.from_arg_list of <class 'sqlglot.expressions.AIClassify'>>, 'AI_SUMMARIZE_AGG': <bound method Func.from_arg_list of <class 'sqlglot.expressions.AISummarizeAgg'>>, 'ABS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Abs'>>, 'ACOS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Acos'>>, 'ACOSH': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Acosh'>>, '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_QUANTILES': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ApproxQuantiles'>>, 'APPROX_TOP_K': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ApproxTopK'>>, 'APPROX_TOP_SUM': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ApproxTopSum'>>, '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'>>, 'ASIN': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Asin'>>, 'ASINH': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Asinh'>>, 'ATAN': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Atan'>>, 'ATAN2': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Atan2'>>, 'ATANH': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Atanh'>>, 'AVG': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Avg'>>, 'BASE64_DECODE_BINARY': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Base64DecodeBinary'>>, 'BASE64_DECODE_STRING': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Base64DecodeString'>>, 'BASE64_ENCODE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Base64Encode'>>, 'BIT_LENGTH': <bound method Func.from_arg_list of <class 'sqlglot.expressions.BitLength'>>, 'BITWISE_AND_AGG': <bound method Func.from_arg_list of <class 'sqlglot.expressions.BitwiseAndAgg'>>, 'BITWISE_COUNT_AGG': <bound method Func.from_arg_list of <class 'sqlglot.expressions.BitwiseCountAgg'>>, 'BITWISE_OR_AGG': <bound method Func.from_arg_list of <class 'sqlglot.expressions.BitwiseOrAgg'>>, 'BITWISE_XOR_AGG': <bound method Func.from_arg_list of <class 'sqlglot.expressions.BitwiseXorAgg'>>, 'BYTE_LENGTH': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ByteLength'>>, 'CASE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Case'>>, 'CAST': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Cast'>>, 'CAST_TO_STR_TYPE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CastToStrType'>>, 'CBRT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Cbrt'>>, 'CEIL': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Ceil'>>, 'CEILING': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Ceil'>>, 'CHR': <function Parser.<lambda>>, 'CHAR': <function Parser.<lambda>>, 'COALESCE': <function build_coalesce>, 'IFNULL': <function build_coalesce>, 'NVL': <function build_coalesce>, 'CODE_POINTS_TO_BYTES': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CodePointsToBytes'>>, 'CODE_POINTS_TO_STRING': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CodePointsToString'>>, 'COLLATE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Collate'>>, 'COLLATION': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Collation'>>, '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'>>, 'COMPRESS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Compress'>>, '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'>>, 'COS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Cos'>>, 'COSH': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Cosh'>>, 'COSINE_DISTANCE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CosineDistance'>>, 'COT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Cot'>>, 'COTH': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Coth'>>, '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'>>, 'CSC': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Csc'>>, 'CSCH': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Csch'>>, 'CUME_DIST': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CumeDist'>>, 'CURRENT_DATE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CurrentDate'>>, 'CURRENT_DATETIME': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CurrentDatetime'>>, 'CURRENT_SCHEMA': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CurrentSchema'>>, 'CURRENT_TIME': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CurrentTime'>>, 'CURRENT_TIMESTAMP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CurrentTimestamp'>>, 'CURRENT_TIMESTAMP_L_T_Z': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CurrentTimestampLTZ'>>, 'CURRENT_USER': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CurrentUser'>>, 'DATE': <function MySQL.Parser.<lambda>>, 'DATE_ADD': <function build_date_delta_with_interval.<locals>._builder>, 'DATE_BIN': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DateBin'>>, 'DATEDIFF': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DateDiff'>>, 'DATE_DIFF': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DateDiff'>>, 'DATE_FROM_PARTS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DateFromParts'>>, 'DATEFROMPARTS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DateFromParts'>>, 'DATE_FROM_UNIX_DATE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DateFromUnixDate'>>, 'DATE_STR_TO_DATE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DateStrToDate'>>, 'DATE_SUB': <function build_date_delta_with_interval.<locals>._builder>, 'DATE_TO_DATE_STR': <function Parser.<lambda>>, 'DATE_TO_DI': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DateToDi'>>, 'DATE_TRUNC': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DateTrunc'>>, 'DATETIME': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Datetime'>>, 'DATETIME_ADD': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DatetimeAdd'>>, 'DATETIME_DIFF': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DatetimeDiff'>>, 'DATETIME_SUB': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DatetimeSub'>>, 'DATETIME_TRUNC': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DatetimeTrunc'>>, 'DAY': <function MySQL.Parser.<lambda>>, 'DAY_OF_MONTH': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DayOfMonth'>>, 'DAYOFMONTH': <function MySQL.Parser.<lambda>>, 'DAY_OF_WEEK': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DayOfWeek'>>, 'DAYOFWEEK': <function MySQL.Parser.<lambda>>, 'DAYOFWEEK_ISO': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DayOfWeekIso'>>, 'ISODOW': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DayOfWeekIso'>>, 'DAY_OF_YEAR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DayOfYear'>>, 'DAYOFYEAR': <function MySQL.Parser.<lambda>>, 'DECODE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Decode'>>, 'DECODE_CASE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DecodeCase'>>, 'DECOMPRESS_BINARY': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DecompressBinary'>>, 'DECOMPRESS_STRING': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DecompressString'>>, 'DEGREES': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Degrees'>>, 'DENSE_RANK': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DenseRank'>>, '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'>>, 'EUCLIDEAN_DISTANCE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.EuclideanDistance'>>, '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'>>, 'FACTORIAL': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Factorial'>>, 'FARM_FINGERPRINT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.FarmFingerprint'>>, 'FARMFINGERPRINT64': <bound method Func.from_arg_list of <class 'sqlglot.expressions.FarmFingerprint'>>, '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'>>, 'FLOAT64': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Float64'>>, 'FLOOR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Floor'>>, 'FORMAT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.NumberToStr'>>, 'FROM_BASE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.FromBase'>>, 'FROM_BASE32': <bound method Func.from_arg_list of <class 'sqlglot.expressions.FromBase32'>>, '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_EMBEDDING': <bound method Func.from_arg_list of <class 'sqlglot.expressions.GenerateEmbedding'>>, 'GENERATE_SERIES': <bound method Func.from_arg_list of <class 'sqlglot.expressions.GenerateSeries'>>, 'GENERATE_TIMESTAMP_ARRAY': <bound method Func.from_arg_list of <class 'sqlglot.expressions.GenerateTimestampArray'>>, 'GET_EXTRACT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.GetExtract'>>, 'GREATEST': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Greatest'>>, 'GROUP_CONCAT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.GroupConcat'>>, 'GROUPING': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Grouping'>>, 'HEX': <function build_hex>, 'HEX_DECODE_STRING': <bound method Func.from_arg_list of <class 'sqlglot.expressions.HexDecodeString'>>, 'HEX_ENCODE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.HexEncode'>>, '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_APPEND': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONArrayAppend'>>, 'JSON_ARRAY_CONTAINS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONArrayContains'>>, 'JSON_ARRAY_INSERT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONArrayInsert'>>, 'JSONB_CONTAINS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONBContains'>>, 'J_S_O_N_B_CONTAINS_ALL_TOP_KEYS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONBContainsAllTopKeys'>>, 'J_S_O_N_B_CONTAINS_ANY_TOP_KEYS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONBContainsAnyTopKeys'>>, 'J_S_O_N_B_DELETE_AT_PATH': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONBDeleteAtPath'>>, '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_BOOL': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONBool'>>, '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_KEYS_AT_DEPTH': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONKeysAtDepth'>>, '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'>>, 'JSON_REMOVE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONRemove'>>, 'JSON_SET': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONSet'>>, 'JSON_STRIP_NULLS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONStripNulls'>>, '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'>>, 'JAROWINKLER_SIMILARITY': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JarowinklerSimilarity'>>, 'JUSTIFY_DAYS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JustifyDays'>>, 'JUSTIFY_HOURS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JustifyHours'>>, 'JUSTIFY_INTERVAL': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JustifyInterval'>>, 'LAG': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Lag'>>, 'LAST': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Last'>>, 'LAST_DAY': <bound method Func.from_arg_list of <class 'sqlglot.expressions.LastDay'>>, 'LAST_DAY_OF_MONTH': <bound method Func.from_arg_list of <class 'sqlglot.expressions.LastDay'>>, 'LAST_VALUE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.LastValue'>>, 'LAX_BOOL': <bound method Func.from_arg_list of <class 'sqlglot.expressions.LaxBool'>>, 'LAX_FLOAT64': <bound method Func.from_arg_list of <class 'sqlglot.expressions.LaxFloat64'>>, 'LAX_INT64': <bound method Func.from_arg_list of <class 'sqlglot.expressions.LaxInt64'>>, 'LAX_STRING': <bound method Func.from_arg_list of <class 'sqlglot.expressions.LaxString'>>, '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'>>, 'M_D5_NUMBER_LOWER64': <bound method Func.from_arg_list of <class 'sqlglot.expressions.MD5NumberLower64'>>, 'M_D5_NUMBER_UPPER64': <bound method Func.from_arg_list of <class 'sqlglot.expressions.MD5NumberUpper64'>>, 'M_L_FORECAST': <bound method Func.from_arg_list of <class 'sqlglot.expressions.MLForecast'>>, 'M_L_TRANSLATE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.MLTranslate'>>, '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'>>, 'NTILE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Ntile'>>, '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_BIGNUMERIC': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ParseBignumeric'>>, 'PARSE_DATETIME': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ParseDatetime'>>, 'PARSE_IP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ParseIp'>>, 'PARSE_JSON': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ParseJSON'>>, 'JSON_PARSE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ParseJSON'>>, 'PARSE_NUMERIC': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ParseNumeric'>>, 'PARSE_TIME': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ParseTime'>>, 'PARSE_URL': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ParseUrl'>>, 'PERCENT_RANK': <bound method Func.from_arg_list of <class 'sqlglot.expressions.PercentRank'>>, '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_BUCKET': <bound method Func.from_arg_list of <class 'sqlglot.expressions.RangeBucket'>>, 'RANGE_N': <bound method Func.from_arg_list of <class 'sqlglot.expressions.RangeN'>>, 'RANK': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Rank'>>, '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_COUNT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.RegexpCount'>>, '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_FULL_MATCH': <bound method Func.from_arg_list of <class 'sqlglot.expressions.RegexpFullMatch'>>, 'REGEXP_I_LIKE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.RegexpILike'>>, 'REGEXP_INSTR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.RegexpInstr'>>, 'REGEXP_LIKE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.RegexpLike'>>, 'REGEXP_REPLACE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.RegexpReplace'>>, 'REGEXP_SPLIT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.RegexpSplit'>>, 'REPEAT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Repeat'>>, 'REPLACE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Replace'>>, 'REVERSE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Reverse'>>, 'RIGHT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Right'>>, 'ROUND': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Round'>>, 'ROW_NUMBER': <bound method Func.from_arg_list of <class 'sqlglot.expressions.RowNumber'>>, 'RTRIMMED_LENGTH': <bound method Func.from_arg_list of <class 'sqlglot.expressions.RtrimmedLength'>>, 'SHA': <bound method Func.from_arg_list of <class 'sqlglot.expressions.SHA'>>, 'SHA1': <bound method Func.from_arg_list of <class 'sqlglot.expressions.SHA'>>, 'S_H_A1_DIGEST': <bound method Func.from_arg_list of <class 'sqlglot.expressions.SHA1Digest'>>, 'SHA2': <bound method Func.from_arg_list of <class 'sqlglot.expressions.SHA2'>>, 'S_H_A2_DIGEST': <bound method Func.from_arg_list of <class 'sqlglot.expressions.SHA2Digest'>>, 'SAFE_ADD': <bound method Func.from_arg_list of <class 'sqlglot.expressions.SafeAdd'>>, 'SAFE_CONVERT_BYTES_TO_STRING': <bound method Func.from_arg_list of <class 'sqlglot.expressions.SafeConvertBytesToString'>>, 'SAFE_DIVIDE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.SafeDivide'>>, 'SAFE_MULTIPLY': <bound method Func.from_arg_list of <class 'sqlglot.expressions.SafeMultiply'>>, 'SAFE_NEGATE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.SafeNegate'>>, 'SAFE_SUBTRACT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.SafeSubtract'>>, 'SEARCH': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Search'>>, 'SEC': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Sec'>>, 'SECH': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Sech'>>, 'SIGN': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Sign'>>, 'SIGNUM': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Sign'>>, 'SIN': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Sin'>>, 'SINH': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Sinh'>>, 'SORT_ARRAY': <bound method Func.from_arg_list of <class 'sqlglot.expressions.SortArray'>>, 'SOUNDEX': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Soundex'>>, 'SOUNDEX_P123': <bound method Func.from_arg_list of <class 'sqlglot.expressions.SoundexP123'>>, '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'>>, 'TAN': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Tan'>>, '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_BASE32': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ToBase32'>>, '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_CODE_POINTS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ToCodePoints'>>, 'TO_DAYS': <function MySQL.Parser.<lambda>>, 'TO_DOUBLE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ToDouble'>>, 'TO_MAP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ToMap'>>, 'TO_NUMBER': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ToNumber'>>, 'TRANSFORM': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Transform'>>, 'TRANSLATE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Translate'>>, 'TRIM': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Trim'>>, 'TRY': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Try'>>, 'TRY_BASE64_DECODE_BINARY': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TryBase64DecodeBinary'>>, 'TRY_BASE64_DECODE_STRING': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TryBase64DecodeString'>>, 'TRY_CAST': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TryCast'>>, 'TRY_HEX_DECODE_BINARY': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TryHexDecodeBinary'>>, 'TRY_HEX_DECODE_STRING': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TryHexDecodeString'>>, 'TS_OR_DI_TO_DI': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TsOrDiToDi'>>, 'TS_OR_DS_ADD': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TsOrDsAdd'>>, 'TS_OR_DS_DIFF': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TsOrDsDiff'>>, 'TS_OR_DS_TO_DATE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TsOrDsToDate'>>, 'TS_OR_DS_TO_DATE_STR': <function Parser.<lambda>>, 'TS_OR_DS_TO_DATETIME': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TsOrDsToDatetime'>>, 'TS_OR_DS_TO_TIME': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TsOrDsToTime'>>, 'TS_OR_DS_TO_TIMESTAMP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TsOrDsToTimestamp'>>, 'TYPEOF': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Typeof'>>, 'UNHEX': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Unhex'>>, 'UNICODE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Unicode'>>, 'UNIX_DATE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.UnixDate'>>, 'UNIX_MICROS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.UnixMicros'>>, 'UNIX_MILLIS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.UnixMillis'>>, 'UNIX_SECONDS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.UnixSeconds'>>, 'UNIX_TO_STR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.UnixToStr'>>, 'UNIX_TO_TIME': <bound method Func.from_arg_list of <class 'sqlglot.expressions.UnixToTime'>>, 'UNIX_TO_TIME_STR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.UnixToTimeStr'>>, 'UNNEST': <function Parser.<lambda>>, 'UPPER': <function build_upper>, 'UCASE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Upper'>>, 'UTC_DATE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.UtcDate'>>, 'UTC_TIME': <bound method Func.from_arg_list of <class 'sqlglot.expressions.UtcTime'>>, 'UTC_TIMESTAMP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.UtcTimestamp'>>, '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'>>, 'VECTOR_SEARCH': <bound method Func.from_arg_list of <class 'sqlglot.expressions.VectorSearch'>>, '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>, 'BIT_AND': <bound method Func.from_arg_list of <class 'sqlglot.expressions.BitwiseAndAgg'>>, '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'>>, 'BIT_COUNT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.BitwiseCountAgg'>>, '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>, '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>>, '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>>, 'SUBSTR': <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.REVOKE: 'REVOKE'>: <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>>, '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 =
{'PERIOD', 'LIKE', 'INDEX', 'KEY', 'EXCLUDE', 'FOREIGN KEY', 'BUCKET', 'FULLTEXT', 'CHECK', 'UNIQUE', 'SPATIAL', 'PRIMARY KEY', 'TRUNCATE'}
PROFILE_TYPES: Dict[str, Sequence[Union[Sequence[str], str]]] =
{'ALL': (), 'CPU': (), 'IPC': (), 'MEMORY': (), 'SOURCE': (), 'SWAPS': (), 'BLOCK': ('IO',), 'CONTEXT': ('SWITCHES',), 'PAGE': ('FAULTS',)}
TYPE_TOKENS =
{<TokenType.NUMRANGE: 'NUMRANGE'>, <TokenType.USERDEFINED: 'USERDEFINED'>, <TokenType.POINT: 'POINT'>, <TokenType.INT256: 'INT256'>, <TokenType.DECIMAL64: 'DECIMAL64'>, <TokenType.VARIANT: 'VARIANT'>, <TokenType.SMALLINT: 'SMALLINT'>, <TokenType.BIGDECIMAL: 'BIGDECIMAL'>, <TokenType.AGGREGATEFUNCTION: 'AGGREGATEFUNCTION'>, <TokenType.LONGBLOB: 'LONGBLOB'>, <TokenType.DATE32: 'DATE32'>, <TokenType.DYNAMIC: 'DYNAMIC'>, <TokenType.STRUCT: 'STRUCT'>, <TokenType.YEAR: 'YEAR'>, <TokenType.DOUBLE: 'DOUBLE'>, <TokenType.JSON: 'JSON'>, <TokenType.CHAR: 'CHAR'>, <TokenType.MEDIUMTEXT: 'MEDIUMTEXT'>, <TokenType.TEXT: 'TEXT'>, <TokenType.TIMESTAMPNTZ: 'TIMESTAMPNTZ'>, <TokenType.PSEUDO_TYPE: 'PSEUDO_TYPE'>, <TokenType.VARCHAR: 'VARCHAR'>, <TokenType.TDIGEST: 'TDIGEST'>, <TokenType.NOTHING: 'NOTHING'>, <TokenType.ENUM: 'ENUM'>, <TokenType.NESTED: 'NESTED'>, <TokenType.FIXEDSTRING: 'FIXEDSTRING'>, <TokenType.BOOLEAN: 'BOOLEAN'>, <TokenType.IPV6: 'IPV6'>, <TokenType.DATEMULTIRANGE: 'DATEMULTIRANGE'>, <TokenType.UDOUBLE: 'UDOUBLE'>, <TokenType.TSMULTIRANGE: 'TSMULTIRANGE'>, <TokenType.TIMESTAMP_MS: 'TIMESTAMP_MS'>, <TokenType.LONGTEXT: 'LONGTEXT'>, <TokenType.MONEY: 'MONEY'>, <TokenType.RANGE: 'RANGE'>, <TokenType.DATETIME2: 'DATETIME2'>, <TokenType.UINT128: 'UINT128'>, <TokenType.USMALLINT: 'USMALLINT'>, <TokenType.SMALLMONEY: 'SMALLMONEY'>, <TokenType.SET: 'SET'>, <TokenType.ARRAY: 'ARRAY'>, <TokenType.NVARCHAR: 'NVARCHAR'>, <TokenType.TINYBLOB: 'TINYBLOB'>, <TokenType.INT4MULTIRANGE: 'INT4MULTIRANGE'>, <TokenType.SMALLDATETIME: 'SMALLDATETIME'>, <TokenType.FLOAT: 'FLOAT'>, <TokenType.ENUM16: 'ENUM16'>, <TokenType.MULTILINESTRING: 'MULTILINESTRING'>, <TokenType.BIT: 'BIT'>, <TokenType.UINT: 'UINT'>, <TokenType.NUMMULTIRANGE: 'NUMMULTIRANGE'>, <TokenType.TSTZMULTIRANGE: 'TSTZMULTIRANGE'>, <TokenType.TINYINT: 'TINYINT'>, <TokenType.JSONB: 'JSONB'>, <TokenType.BIGSERIAL: 'BIGSERIAL'>, <TokenType.SERIAL: 'SERIAL'>, <TokenType.DECIMAL32: 'DECIMAL32'>, <TokenType.ROWVERSION: 'ROWVERSION'>, <TokenType.UBIGINT: 'UBIGINT'>, <TokenType.INTERVAL: 'INTERVAL'>, <TokenType.INT128: 'INT128'>, <TokenType.IPV4: 'IPV4'>, <TokenType.MAP: 'MAP'>, <TokenType.UINT256: 'UINT256'>, <TokenType.GEOMETRY: 'GEOMETRY'>, <TokenType.TSRANGE: 'TSRANGE'>, <TokenType.INT4RANGE: 'INT4RANGE'>, <TokenType.UMEDIUMINT: 'UMEDIUMINT'>, <TokenType.DECIMAL256: 'DECIMAL256'>, <TokenType.IPPREFIX: 'IPPREFIX'>, <TokenType.HSTORE: 'HSTORE'>, <TokenType.HLLSKETCH: 'HLLSKETCH'>, <TokenType.DECIMAL: 'DECIMAL'>, <TokenType.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, <TokenType.TSTZRANGE: 'TSTZRANGE'>, <TokenType.INET: 'INET'>, <TokenType.GEOGRAPHY: 'GEOGRAPHY'>, <TokenType.DATERANGE: 'DATERANGE'>, <TokenType.TINYTEXT: 'TINYTEXT'>, <TokenType.TIME: 'TIME'>, <TokenType.UNION: 'UNION'>, <TokenType.POLYGON: 'POLYGON'>, <TokenType.ENUM8: 'ENUM8'>, <TokenType.SIMPLEAGGREGATEFUNCTION: 'SIMPLEAGGREGATEFUNCTION'>, <TokenType.LINESTRING: 'LINESTRING'>, <TokenType.DATE: 'DATE'>, <TokenType.DATETIME64: 'DATETIME64'>, <TokenType.XML: 'XML'>, <TokenType.UNKNOWN: 'UNKNOWN'>, <TokenType.TIMESTAMP: 'TIMESTAMP'>, <TokenType.GEOGRAPHYPOINT: 'GEOGRAPHYPOINT'>, <TokenType.LIST: 'LIST'>, <TokenType.RING: 'RING'>, <TokenType.TIMESTAMP_NS: 'TIMESTAMP_NS'>, <TokenType.OBJECT: 'OBJECT'>, <TokenType.UUID: 'UUID'>, <TokenType.VOID: 'VOID'>, <TokenType.DATETIME: 'DATETIME'>, <TokenType.SUPER: 'SUPER'>, <TokenType.MULTIPOLYGON: 'MULTIPOLYGON'>, <TokenType.TIMESTAMP_S: 'TIMESTAMP_S'>, <TokenType.NULLABLE: 'NULLABLE'>, <TokenType.DECIMAL128: 'DECIMAL128'>, <TokenType.MEDIUMBLOB: 'MEDIUMBLOB'>, <TokenType.VECTOR: 'VECTOR'>, <TokenType.VARBINARY: 'VARBINARY'>, <TokenType.INT: 'INT'>, <TokenType.UTINYINT: 'UTINYINT'>, <TokenType.BLOB: 'BLOB'>, <TokenType.OBJECT_IDENTIFIER: 'OBJECT_IDENTIFIER'>, <TokenType.NCHAR: 'NCHAR'>, <TokenType.UDECIMAL: 'UDECIMAL'>, <TokenType.SMALLSERIAL: 'SMALLSERIAL'>, <TokenType.LOWCARDINALITY: 'LOWCARDINALITY'>, <TokenType.TIMETZ: 'TIMETZ'>, <TokenType.BINARY: 'BINARY'>, <TokenType.INT8MULTIRANGE: 'INT8MULTIRANGE'>, <TokenType.TIMESTAMPTZ: 'TIMESTAMPTZ'>, <TokenType.IPADDRESS: 'IPADDRESS'>, <TokenType.BPCHAR: 'BPCHAR'>, <TokenType.INT8RANGE: 'INT8RANGE'>, <TokenType.BIGINT: 'BIGINT'>, <TokenType.IMAGE: 'IMAGE'>, <TokenType.MEDIUMINT: 'MEDIUMINT'>, <TokenType.NAME: 'NAME'>, <TokenType.NULL: 'NULL'>}
ENUM_TYPE_TOKENS =
{<TokenType.ENUM: 'ENUM'>, <TokenType.ENUM8: 'ENUM8'>, <TokenType.SET: 'SET'>, <TokenType.DYNAMIC: 'DYNAMIC'>, <TokenType.ENUM16: 'ENUM16'>}
OPERATION_MODIFIERS =
{'HIGH_PRIORITY', 'SQL_NO_CACHE', 'STRAIGHT_JOIN', 'SQL_BUFFER_RESULT', 'SQL_SMALL_RESULT', 'SQL_CALC_FOUND_ROWS', 'SQL_BIG_RESULT'}
SHOW_TRIE: Dict =
{'BINARY': {'LOGS': {0: True}}, 'MASTER': {'LOGS': {0: True}, 'STATUS': {0: True}}, 'BINLOG': {'EVENTS': {0: True}}, 'CHARACTER': {'SET': {0: True}}, 'CHARSET': {0: True}, 'COLLATION': {0: True}, 'FULL': {'COLUMNS': {0: True}, 'PROCESSLIST': {0: True}, 'TABLES': {0: True}}, 'COLUMNS': {0: True}, 'CREATE': {'DATABASE': {0: True}, 'EVENT': {0: True}, 'FUNCTION': {0: True}, 'PROCEDURE': {0: True}, 'TABLE': {0: True}, 'TRIGGER': {0: True}, 'VIEW': {0: True}}, 'DATABASES': {0: True}, 'SCHEMAS': {0: True}, 'ENGINE': {0: True}, 'STORAGE': {'ENGINES': {0: True}}, 'ENGINES': {0: True}, 'ERRORS': {0: True}, 'EVENTS': {0: True}, 'FUNCTION': {'CODE': {0: True}, 'STATUS': {0: True}}, 'GRANTS': {0: True}, 'INDEX': {0: True}, 'OPEN': {'TABLES': {0: True}}, 'PLUGINS': {0: True}, 'PROCEDURE': {'CODE': {0: True}, 'STATUS': {0: True}}, 'PRIVILEGES': {0: True}, 'PROCESSLIST': {0: True}, 'PROFILE': {0: True}, 'PROFILES': {0: True}, 'RELAYLOG': {'EVENTS': {0: True}}, 'REPLICAS': {0: True}, 'SLAVE': {'HOSTS': {0: True}, 'STATUS': {0: True}}, 'REPLICA': {'STATUS': {0: True}}, 'GLOBAL': {'STATUS': {0: True}, 'VARIABLES': {0: True}}, 'SESSION': {'STATUS': {0: True}, 'VARIABLES': {0: True}}, 'STATUS': {0: True}, 'TABLE': {'STATUS': {0: True}}, 'TABLES': {0: True}, 'TRIGGERS': {0: True}, 'VARIABLES': {0: True}, 'WARNINGS': {0: True}}
SET_TRIE: Dict =
{'GLOBAL': {0: True}, 'LOCAL': {0: True}, 'SESSION': {0: True}, 'TRANSACTION': {0: True}, 'PERSIST': {0: True}, 'PERSIST_ONLY': {0: True}, 'CHARACTER': {'SET': {0: True}}, 'CHARSET': {0: True}, 'NAMES': {0: True}}
Inherited Members
- sqlglot.parser.Parser
- Parser
- NO_PAREN_FUNCTIONS
- STRUCT_TYPE_TOKENS
- NESTED_TYPE_TOKENS
- AGGREGATE_TYPE_TOKENS
- SIGNED_TO_UNSIGNED_TYPE_TOKEN
- SUBQUERY_PREDICATES
- RESERVED_TOKENS
- DB_CREATABLES
- CREATABLES
- ALTERABLES
- ID_VAR_TOKENS
- ALIAS_TOKENS
- COLON_PLACEHOLDER_TOKENS
- ARRAY_CONSTRUCTORS
- COMMENT_TABLE_ALIAS_TOKENS
- UPDATE_ALIAS_TOKENS
- TRIM_TYPES
- ASSIGNMENT
- EQUALITY
- COMPARISON
- BITWISE
- TERM
- FACTOR
- EXPONENT
- TIMES
- TIMESTAMPS
- SET_OPERATIONS
- JOIN_METHODS
- JOIN_SIDES
- JOIN_KINDS
- JOIN_HINTS
- LAMBDAS
- COLUMN_OPERATORS
- CAST_COLUMN_OPERATORS
- EXPRESSION_PARSERS
- UNARY_PARSERS
- STRING_PARSERS
- NUMERIC_PARSERS
- PRIMARY_PARSERS
- PLACEHOLDER_PARSERS
- PIPE_SYNTAX_TRANSFORM_PARSERS
- NO_PAREN_FUNCTION_PARSERS
- INVALID_FUNC_NAME_TOKENS
- FUNCTIONS_WITH_ALIASED_ARGS
- KEY_VALUE_DEFINITIONS
- QUERY_MODIFIER_PARSERS
- QUERY_MODIFIER_TOKENS
- TYPE_LITERAL_PARSERS
- TYPE_CONVERTERS
- DDL_SELECT_TOKENS
- PRE_VOLATILE_TOKENS
- TRANSACTION_KIND
- TRANSACTION_CHARACTERISTICS
- CONFLICT_ACTIONS
- CREATE_SEQUENCE
- ISOLATED_LOADING_OPTIONS
- USABLES
- CAST_ACTIONS
- SCHEMA_BINDING_OPTIONS
- PROCEDURE_OPTIONS
- EXECUTE_AS_OPTIONS
- KEY_CONSTRAINT_OPTIONS
- WINDOW_EXCLUDE_OPTIONS
- INSERT_ALTERNATIVES
- CLONE_KEYWORDS
- HISTORICAL_DATA_PREFIX
- HISTORICAL_DATA_KIND
- OPCLASS_FOLLOW_KEYWORDS
- OPTYPE_FOLLOW_TOKENS
- TABLE_INDEX_HINT_TOKENS
- VIEW_ATTRIBUTES
- WINDOW_ALIAS_TOKENS
- WINDOW_BEFORE_PAREN_TOKENS
- WINDOW_SIDES
- JSON_KEY_VALUE_SEPARATOR_TOKENS
- FETCH_TOKENS
- ADD_CONSTRAINT_TOKENS
- DISTINCT_TOKENS
- 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
- ALTER_TABLE_PARTITIONS
- JOINS_HAVE_EQUAL_PRECEDENCE
- ZONE_AWARE_TIMESTAMP_CONSTRUCTOR
- MAP_KEYS_ARE_ARBITRARY_EXPRESSIONS
- JSON_EXTRACT_REQUIRES_JSON_EXPRESSION
- ADD_JOIN_ON_TRUE
- SUPPORTS_OMITTED_INTERVAL_SPAN_UNIT
- 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
732 class Generator(generator.Generator): 733 INTERVAL_ALLOWS_PLURAL_FORM = False 734 LOCKING_READS_SUPPORTED = True 735 NULL_ORDERING_SUPPORTED: t.Optional[bool] = None 736 JOIN_HINTS = False 737 TABLE_HINTS = True 738 DUPLICATE_KEY_UPDATE_WITH_SET = False 739 QUERY_HINT_SEP = " " 740 VALUES_AS_TABLE = False 741 NVL2_SUPPORTED = False 742 LAST_DAY_SUPPORTS_DATE_PART = False 743 JSON_TYPE_REQUIRED_FOR_EXTRACTION = True 744 JSON_PATH_BRACKETED_KEY_SUPPORTED = False 745 JSON_KEY_VALUE_PAIR_SEP = "," 746 SUPPORTS_TO_NUMBER = False 747 PARSE_JSON_NAME: t.Optional[str] = None 748 PAD_FILL_PATTERN_IS_REQUIRED = True 749 WRAP_DERIVED_VALUES = False 750 VARCHAR_REQUIRES_SIZE = True 751 SUPPORTS_MEDIAN = False 752 753 TRANSFORMS = { 754 **generator.Generator.TRANSFORMS, 755 exp.ArrayAgg: rename_func("GROUP_CONCAT"), 756 exp.BitwiseAndAgg: rename_func("BIT_AND"), 757 exp.BitwiseOrAgg: rename_func("BIT_OR"), 758 exp.BitwiseXorAgg: rename_func("BIT_XOR"), 759 exp.BitwiseCountAgg: rename_func("BIT_COUNT"), 760 exp.CurrentDate: no_paren_current_date_sql, 761 exp.DateDiff: _remove_ts_or_ds_to_date( 762 lambda self, e: self.func("DATEDIFF", e.this, e.expression), ("this", "expression") 763 ), 764 exp.DateAdd: _remove_ts_or_ds_to_date(date_add_sql("ADD")), 765 exp.DateStrToDate: datestrtodate_sql, 766 exp.DateSub: _remove_ts_or_ds_to_date(date_add_sql("SUB")), 767 exp.DateTrunc: _date_trunc_sql, 768 exp.Day: _remove_ts_or_ds_to_date(), 769 exp.DayOfMonth: _remove_ts_or_ds_to_date(rename_func("DAYOFMONTH")), 770 exp.DayOfWeek: _remove_ts_or_ds_to_date(rename_func("DAYOFWEEK")), 771 exp.DayOfYear: _remove_ts_or_ds_to_date(rename_func("DAYOFYEAR")), 772 exp.GroupConcat: lambda self, 773 e: f"""GROUP_CONCAT({self.sql(e, "this")} SEPARATOR {self.sql(e, "separator") or "','"})""", 774 exp.ILike: no_ilike_sql, 775 exp.JSONExtractScalar: arrow_json_extract_sql, 776 exp.Length: length_or_char_length_sql, 777 exp.LogicalOr: rename_func("MAX"), 778 exp.LogicalAnd: rename_func("MIN"), 779 exp.Max: max_or_greatest, 780 exp.Min: min_or_least, 781 exp.Month: _remove_ts_or_ds_to_date(), 782 exp.NullSafeEQ: lambda self, e: self.binary(e, "<=>"), 783 exp.NullSafeNEQ: lambda self, e: f"NOT {self.binary(e, '<=>')}", 784 exp.NumberToStr: rename_func("FORMAT"), 785 exp.Pivot: no_pivot_sql, 786 exp.Select: transforms.preprocess( 787 [ 788 transforms.eliminate_distinct_on, 789 transforms.eliminate_semi_and_anti_joins, 790 transforms.eliminate_qualify, 791 transforms.eliminate_full_outer_join, 792 transforms.unnest_generate_date_array_using_recursive_cte, 793 ] 794 ), 795 exp.StrPosition: lambda self, e: strposition_sql( 796 self, e, func_name="LOCATE", supports_position=True 797 ), 798 exp.StrToDate: _str_to_date_sql, 799 exp.StrToTime: _str_to_date_sql, 800 exp.Stuff: rename_func("INSERT"), 801 exp.TableSample: no_tablesample_sql, 802 exp.TimeFromParts: rename_func("MAKETIME"), 803 exp.TimestampAdd: date_add_interval_sql("DATE", "ADD"), 804 exp.TimestampDiff: lambda self, e: self.func( 805 "TIMESTAMPDIFF", unit_to_var(e), e.expression, e.this 806 ), 807 exp.TimestampSub: date_add_interval_sql("DATE", "SUB"), 808 exp.TimeStrToUnix: rename_func("UNIX_TIMESTAMP"), 809 exp.TimeStrToTime: lambda self, e: timestrtotime_sql( 810 self, 811 e, 812 include_precision=not e.args.get("zone"), 813 ), 814 exp.TimeToStr: _remove_ts_or_ds_to_date( 815 lambda self, e: self.func("DATE_FORMAT", e.this, self.format_time(e)) 816 ), 817 exp.Trim: trim_sql, 818 exp.TryCast: no_trycast_sql, 819 exp.TsOrDsAdd: date_add_sql("ADD"), 820 exp.TsOrDsDiff: lambda self, e: self.func("DATEDIFF", e.this, e.expression), 821 exp.TsOrDsToDate: _ts_or_ds_to_date_sql, 822 exp.Unicode: lambda self, e: f"ORD(CONVERT({self.sql(e.this)} USING utf32))", 823 exp.UnixToTime: _unix_to_time_sql, 824 exp.Week: _remove_ts_or_ds_to_date(), 825 exp.WeekOfYear: _remove_ts_or_ds_to_date(rename_func("WEEKOFYEAR")), 826 exp.Year: _remove_ts_or_ds_to_date(), 827 exp.UtcTimestamp: rename_func("UTC_TIMESTAMP"), 828 exp.UtcTime: rename_func("UTC_TIME"), 829 } 830 831 UNSIGNED_TYPE_MAPPING = { 832 exp.DataType.Type.UBIGINT: "BIGINT", 833 exp.DataType.Type.UINT: "INT", 834 exp.DataType.Type.UMEDIUMINT: "MEDIUMINT", 835 exp.DataType.Type.USMALLINT: "SMALLINT", 836 exp.DataType.Type.UTINYINT: "TINYINT", 837 exp.DataType.Type.UDECIMAL: "DECIMAL", 838 exp.DataType.Type.UDOUBLE: "DOUBLE", 839 } 840 841 TIMESTAMP_TYPE_MAPPING = { 842 exp.DataType.Type.DATETIME2: "DATETIME", 843 exp.DataType.Type.SMALLDATETIME: "DATETIME", 844 exp.DataType.Type.TIMESTAMP: "DATETIME", 845 exp.DataType.Type.TIMESTAMPNTZ: "DATETIME", 846 exp.DataType.Type.TIMESTAMPTZ: "TIMESTAMP", 847 exp.DataType.Type.TIMESTAMPLTZ: "TIMESTAMP", 848 } 849 850 TYPE_MAPPING = { 851 **generator.Generator.TYPE_MAPPING, 852 **UNSIGNED_TYPE_MAPPING, 853 **TIMESTAMP_TYPE_MAPPING, 854 } 855 856 TYPE_MAPPING.pop(exp.DataType.Type.MEDIUMTEXT) 857 TYPE_MAPPING.pop(exp.DataType.Type.LONGTEXT) 858 TYPE_MAPPING.pop(exp.DataType.Type.TINYTEXT) 859 TYPE_MAPPING.pop(exp.DataType.Type.BLOB) 860 TYPE_MAPPING.pop(exp.DataType.Type.MEDIUMBLOB) 861 TYPE_MAPPING.pop(exp.DataType.Type.LONGBLOB) 862 TYPE_MAPPING.pop(exp.DataType.Type.TINYBLOB) 863 864 PROPERTIES_LOCATION = { 865 **generator.Generator.PROPERTIES_LOCATION, 866 exp.TransientProperty: exp.Properties.Location.UNSUPPORTED, 867 exp.VolatileProperty: exp.Properties.Location.UNSUPPORTED, 868 } 869 870 LIMIT_FETCH = "LIMIT" 871 872 LIMIT_ONLY_LITERALS = True 873 874 CHAR_CAST_MAPPING = dict.fromkeys( 875 ( 876 exp.DataType.Type.LONGTEXT, 877 exp.DataType.Type.LONGBLOB, 878 exp.DataType.Type.MEDIUMBLOB, 879 exp.DataType.Type.MEDIUMTEXT, 880 exp.DataType.Type.TEXT, 881 exp.DataType.Type.TINYBLOB, 882 exp.DataType.Type.TINYTEXT, 883 exp.DataType.Type.VARCHAR, 884 ), 885 "CHAR", 886 ) 887 SIGNED_CAST_MAPPING = dict.fromkeys( 888 ( 889 exp.DataType.Type.BIGINT, 890 exp.DataType.Type.BOOLEAN, 891 exp.DataType.Type.INT, 892 exp.DataType.Type.SMALLINT, 893 exp.DataType.Type.TINYINT, 894 exp.DataType.Type.MEDIUMINT, 895 ), 896 "SIGNED", 897 ) 898 899 # MySQL doesn't support many datatypes in cast. 900 # https://dev.mysql.com/doc/refman/8.0/en/cast-functions.html#function_cast 901 CAST_MAPPING = { 902 **CHAR_CAST_MAPPING, 903 **SIGNED_CAST_MAPPING, 904 exp.DataType.Type.UBIGINT: "UNSIGNED", 905 } 906 907 TIMESTAMP_FUNC_TYPES = { 908 exp.DataType.Type.TIMESTAMPTZ, 909 exp.DataType.Type.TIMESTAMPLTZ, 910 } 911 912 # https://dev.mysql.com/doc/refman/8.0/en/keywords.html 913 RESERVED_KEYWORDS = { 914 "accessible", 915 "add", 916 "all", 917 "alter", 918 "analyze", 919 "and", 920 "as", 921 "asc", 922 "asensitive", 923 "before", 924 "between", 925 "bigint", 926 "binary", 927 "blob", 928 "both", 929 "by", 930 "call", 931 "cascade", 932 "case", 933 "change", 934 "char", 935 "character", 936 "check", 937 "collate", 938 "column", 939 "condition", 940 "constraint", 941 "continue", 942 "convert", 943 "create", 944 "cross", 945 "cube", 946 "cume_dist", 947 "current_date", 948 "current_time", 949 "current_timestamp", 950 "current_user", 951 "cursor", 952 "database", 953 "databases", 954 "day_hour", 955 "day_microsecond", 956 "day_minute", 957 "day_second", 958 "dec", 959 "decimal", 960 "declare", 961 "default", 962 "delayed", 963 "delete", 964 "dense_rank", 965 "desc", 966 "describe", 967 "deterministic", 968 "distinct", 969 "distinctrow", 970 "div", 971 "double", 972 "drop", 973 "dual", 974 "each", 975 "else", 976 "elseif", 977 "empty", 978 "enclosed", 979 "escaped", 980 "except", 981 "exists", 982 "exit", 983 "explain", 984 "false", 985 "fetch", 986 "first_value", 987 "float", 988 "float4", 989 "float8", 990 "for", 991 "force", 992 "foreign", 993 "from", 994 "fulltext", 995 "function", 996 "generated", 997 "get", 998 "grant", 999 "group", 1000 "grouping", 1001 "groups", 1002 "having", 1003 "high_priority", 1004 "hour_microsecond", 1005 "hour_minute", 1006 "hour_second", 1007 "if", 1008 "ignore", 1009 "in", 1010 "index", 1011 "infile", 1012 "inner", 1013 "inout", 1014 "insensitive", 1015 "insert", 1016 "int", 1017 "int1", 1018 "int2", 1019 "int3", 1020 "int4", 1021 "int8", 1022 "integer", 1023 "intersect", 1024 "interval", 1025 "into", 1026 "io_after_gtids", 1027 "io_before_gtids", 1028 "is", 1029 "iterate", 1030 "join", 1031 "json_table", 1032 "key", 1033 "keys", 1034 "kill", 1035 "lag", 1036 "last_value", 1037 "lateral", 1038 "lead", 1039 "leading", 1040 "leave", 1041 "left", 1042 "like", 1043 "limit", 1044 "linear", 1045 "lines", 1046 "load", 1047 "localtime", 1048 "localtimestamp", 1049 "lock", 1050 "long", 1051 "longblob", 1052 "longtext", 1053 "loop", 1054 "low_priority", 1055 "master_bind", 1056 "master_ssl_verify_server_cert", 1057 "match", 1058 "maxvalue", 1059 "mediumblob", 1060 "mediumint", 1061 "mediumtext", 1062 "middleint", 1063 "minute_microsecond", 1064 "minute_second", 1065 "mod", 1066 "modifies", 1067 "natural", 1068 "not", 1069 "no_write_to_binlog", 1070 "nth_value", 1071 "ntile", 1072 "null", 1073 "numeric", 1074 "of", 1075 "on", 1076 "optimize", 1077 "optimizer_costs", 1078 "option", 1079 "optionally", 1080 "or", 1081 "order", 1082 "out", 1083 "outer", 1084 "outfile", 1085 "over", 1086 "partition", 1087 "percent_rank", 1088 "precision", 1089 "primary", 1090 "procedure", 1091 "purge", 1092 "range", 1093 "rank", 1094 "read", 1095 "reads", 1096 "read_write", 1097 "real", 1098 "recursive", 1099 "references", 1100 "regexp", 1101 "release", 1102 "rename", 1103 "repeat", 1104 "replace", 1105 "require", 1106 "resignal", 1107 "restrict", 1108 "return", 1109 "revoke", 1110 "right", 1111 "rlike", 1112 "row", 1113 "rows", 1114 "row_number", 1115 "schema", 1116 "schemas", 1117 "second_microsecond", 1118 "select", 1119 "sensitive", 1120 "separator", 1121 "set", 1122 "show", 1123 "signal", 1124 "smallint", 1125 "spatial", 1126 "specific", 1127 "sql", 1128 "sqlexception", 1129 "sqlstate", 1130 "sqlwarning", 1131 "sql_big_result", 1132 "sql_calc_found_rows", 1133 "sql_small_result", 1134 "ssl", 1135 "starting", 1136 "stored", 1137 "straight_join", 1138 "system", 1139 "table", 1140 "terminated", 1141 "then", 1142 "tinyblob", 1143 "tinyint", 1144 "tinytext", 1145 "to", 1146 "trailing", 1147 "trigger", 1148 "true", 1149 "undo", 1150 "union", 1151 "unique", 1152 "unlock", 1153 "unsigned", 1154 "update", 1155 "usage", 1156 "use", 1157 "using", 1158 "utc_date", 1159 "utc_time", 1160 "utc_timestamp", 1161 "values", 1162 "varbinary", 1163 "varchar", 1164 "varcharacter", 1165 "varying", 1166 "virtual", 1167 "when", 1168 "where", 1169 "while", 1170 "window", 1171 "with", 1172 "write", 1173 "xor", 1174 "year_month", 1175 "zerofill", 1176 } 1177 1178 def computedcolumnconstraint_sql(self, expression: exp.ComputedColumnConstraint) -> str: 1179 persisted = "STORED" if expression.args.get("persisted") else "VIRTUAL" 1180 return f"GENERATED ALWAYS AS ({self.sql(expression.this.unnest())}) {persisted}" 1181 1182 def array_sql(self, expression: exp.Array) -> str: 1183 self.unsupported("Arrays are not supported by MySQL") 1184 return self.function_fallback_sql(expression) 1185 1186 def arraycontainsall_sql(self, expression: exp.ArrayContainsAll) -> str: 1187 self.unsupported("Array operations are not supported by MySQL") 1188 return self.function_fallback_sql(expression) 1189 1190 def dpipe_sql(self, expression: exp.DPipe) -> str: 1191 return self.func("CONCAT", *expression.flatten()) 1192 1193 def extract_sql(self, expression: exp.Extract) -> str: 1194 unit = expression.name 1195 if unit and unit.lower() == "epoch": 1196 return self.func("UNIX_TIMESTAMP", expression.expression) 1197 1198 return super().extract_sql(expression) 1199 1200 def datatype_sql(self, expression: exp.DataType) -> str: 1201 if ( 1202 self.VARCHAR_REQUIRES_SIZE 1203 and expression.is_type(exp.DataType.Type.VARCHAR) 1204 and not expression.expressions 1205 ): 1206 # `VARCHAR` must always have a size - if it doesn't, we always generate `TEXT` 1207 return "TEXT" 1208 1209 # https://dev.mysql.com/doc/refman/8.0/en/numeric-type-syntax.html 1210 result = super().datatype_sql(expression) 1211 if expression.this in self.UNSIGNED_TYPE_MAPPING: 1212 result = f"{result} UNSIGNED" 1213 1214 return result 1215 1216 def jsonarraycontains_sql(self, expression: exp.JSONArrayContains) -> str: 1217 return f"{self.sql(expression, 'this')} MEMBER OF({self.sql(expression, 'expression')})" 1218 1219 def cast_sql(self, expression: exp.Cast, safe_prefix: t.Optional[str] = None) -> str: 1220 if expression.to.this in self.TIMESTAMP_FUNC_TYPES: 1221 return self.func("TIMESTAMP", expression.this) 1222 1223 to = self.CAST_MAPPING.get(expression.to.this) 1224 1225 if to: 1226 expression.to.set("this", to) 1227 return super().cast_sql(expression) 1228 1229 def show_sql(self, expression: exp.Show) -> str: 1230 this = f" {expression.name}" 1231 full = " FULL" if expression.args.get("full") else "" 1232 global_ = " GLOBAL" if expression.args.get("global") else "" 1233 1234 target = self.sql(expression, "target") 1235 target = f" {target}" if target else "" 1236 if expression.name in ("COLUMNS", "INDEX"): 1237 target = f" FROM{target}" 1238 elif expression.name == "GRANTS": 1239 target = f" FOR{target}" 1240 elif expression.name in ("LINKS", "PARTITIONS"): 1241 target = f" ON{target}" if target else "" 1242 elif expression.name == "PROJECTIONS": 1243 target = f" ON TABLE{target}" if target else "" 1244 1245 db = self._prefixed_sql("FROM", expression, "db") 1246 1247 like = self._prefixed_sql("LIKE", expression, "like") 1248 where = self.sql(expression, "where") 1249 1250 types = self.expressions(expression, key="types") 1251 types = f" {types}" if types else types 1252 query = self._prefixed_sql("FOR QUERY", expression, "query") 1253 1254 if expression.name == "PROFILE": 1255 offset = self._prefixed_sql("OFFSET", expression, "offset") 1256 limit = self._prefixed_sql("LIMIT", expression, "limit") 1257 else: 1258 offset = "" 1259 limit = self._oldstyle_limit_sql(expression) 1260 1261 log = self._prefixed_sql("IN", expression, "log") 1262 position = self._prefixed_sql("FROM", expression, "position") 1263 1264 channel = self._prefixed_sql("FOR CHANNEL", expression, "channel") 1265 1266 if expression.name == "ENGINE": 1267 mutex_or_status = " MUTEX" if expression.args.get("mutex") else " STATUS" 1268 else: 1269 mutex_or_status = "" 1270 1271 for_table = self._prefixed_sql("FOR TABLE", expression, "for_table") 1272 for_group = self._prefixed_sql("FOR GROUP", expression, "for_group") 1273 for_user = self._prefixed_sql("FOR USER", expression, "for_user") 1274 for_role = self._prefixed_sql("FOR ROLE", expression, "for_role") 1275 into_outfile = self._prefixed_sql("INTO OUTFILE", expression, "into_outfile") 1276 json = " JSON" if expression.args.get("json") else "" 1277 1278 return f"SHOW{full}{global_}{this}{json}{target}{for_table}{types}{db}{query}{log}{position}{channel}{mutex_or_status}{like}{where}{offset}{limit}{for_group}{for_user}{for_role}{into_outfile}" 1279 1280 def altercolumn_sql(self, expression: exp.AlterColumn) -> str: 1281 dtype = self.sql(expression, "dtype") 1282 if not dtype: 1283 return super().altercolumn_sql(expression) 1284 1285 this = self.sql(expression, "this") 1286 return f"MODIFY COLUMN {this} {dtype}" 1287 1288 def _prefixed_sql(self, prefix: str, expression: exp.Expression, arg: str) -> str: 1289 sql = self.sql(expression, arg) 1290 return f" {prefix} {sql}" if sql else "" 1291 1292 def _oldstyle_limit_sql(self, expression: exp.Show) -> str: 1293 limit = self.sql(expression, "limit") 1294 offset = self.sql(expression, "offset") 1295 if limit: 1296 limit_offset = f"{offset}, {limit}" if offset else limit 1297 return f" LIMIT {limit_offset}" 1298 return "" 1299 1300 def chr_sql(self, expression: exp.Chr) -> str: 1301 this = self.expressions(sqls=[expression.this] + expression.expressions) 1302 charset = expression.args.get("charset") 1303 using = f" USING {self.sql(charset)}" if charset else "" 1304 return f"CHAR({this}{using})" 1305 1306 def timestamptrunc_sql(self, expression: exp.TimestampTrunc) -> str: 1307 unit = expression.args.get("unit") 1308 1309 # Pick an old-enough date to avoid negative timestamp diffs 1310 start_ts = "'0000-01-01 00:00:00'" 1311 1312 # Source: https://stackoverflow.com/a/32955740 1313 timestamp_diff = build_date_delta(exp.TimestampDiff)([unit, start_ts, expression.this]) 1314 interval = exp.Interval(this=timestamp_diff, unit=unit) 1315 dateadd = build_date_delta_with_interval(exp.DateAdd)([start_ts, interval]) 1316 1317 return self.sql(dateadd) 1318 1319 def converttimezone_sql(self, expression: exp.ConvertTimezone) -> str: 1320 from_tz = expression.args.get("source_tz") 1321 to_tz = expression.args.get("target_tz") 1322 dt = expression.args.get("timestamp") 1323 1324 return self.func("CONVERT_TZ", dt, from_tz, to_tz) 1325 1326 def attimezone_sql(self, expression: exp.AtTimeZone) -> str: 1327 self.unsupported("AT TIME ZONE is not supported by MySQL") 1328 return self.sql(expression.this) 1329 1330 def isascii_sql(self, expression: exp.IsAscii) -> str: 1331 return f"REGEXP_LIKE({self.sql(expression.this)}, '^[[:ascii:]]*$')" 1332 1333 @unsupported_args("this") 1334 def currentschema_sql(self, expression: exp.CurrentSchema) -> str: 1335 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.JSONBContainsAnyTopKeys'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.JSONBContainsAllTopKeys'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.JSONBDeleteAtPath'>: <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.UtcDate'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.UtcTime'>: <function rename_func.<locals>.<lambda>>, <class 'sqlglot.expressions.UtcTimestamp'>: <function rename_func.<locals>.<lambda>>, <class 'sqlglot.expressions.VarMap'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.ViewAttributeProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.VolatileProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.WeekStart'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.WithJournalTableProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.WithProcedureOptions'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.WithSchemaBindingProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.WithOperator'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.ForceProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.ArrayAgg'>: <function rename_func.<locals>.<lambda>>, <class 'sqlglot.expressions.BitwiseAndAgg'>: <function rename_func.<locals>.<lambda>>, <class 'sqlglot.expressions.BitwiseOrAgg'>: <function rename_func.<locals>.<lambda>>, <class 'sqlglot.expressions.BitwiseXorAgg'>: <function rename_func.<locals>.<lambda>>, <class 'sqlglot.expressions.BitwiseCountAgg'>: <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 =
{'row_number', 'null', 'between', 'precision', 'limit', 'on', 'mediumblob', 'double', 'if', 'maxvalue', 'enclosed', 'column', 'replace', 'varying', 'use', 'default', 'intersect', 'primary', 'outer', 'database', 'day_minute', 'div', 'middleint', 'localtime', 'drop', 'read', 'smallint', 'utc_timestamp', 'system', 'dual', 'desc', 'select', 'sql_big_result', 'interval', 'second_microsecond', 'spatial', 'databases', 'inout', 'float4', 'insert', 'escaped', 'mod', 'leave', 'linear', 'partition', 'day_hour', 'int3', 'longtext', 'generated', 'resignal', 'range', 'loop', 'release', 'sqlexception', 'grouping', 'join', 'call', 'option', 'keys', 'explain', 'minute_microsecond', 'group', 'trigger', 'for', 'schemas', 'high_priority', 'out', 'accessible', 'as', 'asc', 'int', 'sql_calc_found_rows', 'usage', 'inner', 'load', 'collate', 'int8', 'union', 'io_before_gtids', 'json_table', 'rank', 'where', 'sqlstate', 'all', 'last_value', 'stored', 'show', 'longblob', 'mediumtext', 'long', 'infile', 'using', 'else', 'leading', 'cross', 'continue', 'row', 'utc_time', 'bigint', 'tinyblob', 'condition', 'groups', 'constraint', 'virtual', 'straight_join', 'delete', 'reads', 'hour_microsecond', 'ssl', 'current_date', 'natural', 'master_bind', 'hour_second', 'lateral', 'varcharacter', 'real', 'require', 'values', 'write', 'distinct', 'declare', 'like', 'table', 'current_time', 'optimizer_costs', 'procedure', 'tinyint', 'sql_small_result', 'window', 'fulltext', 'specific', 'asensitive', 'to', 'kill', 'repeat', 'over', 'int2', 'signal', 'each', 'lines', 'update', 'first_value', 'empty', 'or', 'exit', 'restrict', 'key', 'elseif', 'integer', 'current_timestamp', 'sensitive', 'trailing', 'hour_minute', 'int4', 'alter', 'low_priority', 'revoke', 'deterministic', 'outfile', 'dec', 'localtimestamp', 'rows', 'dense_rank', 'check', 'current_user', 'regexp', 'foreign', 'force', 'get', 'fetch', 'optimize', 'with', 'insensitive', 'terminated', 'rlike', 'cursor', 'of', 'purge', 'master_ssl_verify_server_cert', 'nth_value', 'not', 'return', 'zerofill', 'unsigned', 'schema', 'and', 'separator', 'false', 'minute_second', 'character', 'grant', 'day_second', 'percent_rank', 'lock', 'change', 'when', 'lead', 'year_month', 'mediumint', 'no_write_to_binlog', 'then', 'unique', 'sql', 'cube', 'decimal', 'rename', 'io_after_gtids', 'convert', 'delayed', 'into', 'true', 'cascade', 'undo', 'distinctrow', 'modifies', 'optionally', 'create', 'lag', 'char', 'index', 'add', 'left', 'recursive', 'float8', 'function', 'ntile', 'cume_dist', 'by', 'in', 'blob', 'starting', 'having', 'numeric', 'is', 'before', 'match', 'describe', 'case', 'day_microsecond', 'from', 'set', 'read_write', 'unlock', 'int1', 'right', 'binary', 'while', 'float', 'references', 'both', 'order', 'xor', 'exists', 'tinytext', 'analyze', 'varchar', 'varbinary', 'iterate', 'utc_date', 'sqlwarning', 'except', 'ignore'}
def
computedcolumnconstraint_sql(self, expression: sqlglot.expressions.ComputedColumnConstraint) -> str:
1200 def datatype_sql(self, expression: exp.DataType) -> str: 1201 if ( 1202 self.VARCHAR_REQUIRES_SIZE 1203 and expression.is_type(exp.DataType.Type.VARCHAR) 1204 and not expression.expressions 1205 ): 1206 # `VARCHAR` must always have a size - if it doesn't, we always generate `TEXT` 1207 return "TEXT" 1208 1209 # https://dev.mysql.com/doc/refman/8.0/en/numeric-type-syntax.html 1210 result = super().datatype_sql(expression) 1211 if expression.this in self.UNSIGNED_TYPE_MAPPING: 1212 result = f"{result} UNSIGNED" 1213 1214 return result
def
cast_sql( self, expression: sqlglot.expressions.Cast, safe_prefix: Optional[str] = None) -> str:
1219 def cast_sql(self, expression: exp.Cast, safe_prefix: t.Optional[str] = None) -> str: 1220 if expression.to.this in self.TIMESTAMP_FUNC_TYPES: 1221 return self.func("TIMESTAMP", expression.this) 1222 1223 to = self.CAST_MAPPING.get(expression.to.this) 1224 1225 if to: 1226 expression.to.set("this", to) 1227 return super().cast_sql(expression)
1229 def show_sql(self, expression: exp.Show) -> str: 1230 this = f" {expression.name}" 1231 full = " FULL" if expression.args.get("full") else "" 1232 global_ = " GLOBAL" if expression.args.get("global") else "" 1233 1234 target = self.sql(expression, "target") 1235 target = f" {target}" if target else "" 1236 if expression.name in ("COLUMNS", "INDEX"): 1237 target = f" FROM{target}" 1238 elif expression.name == "GRANTS": 1239 target = f" FOR{target}" 1240 elif expression.name in ("LINKS", "PARTITIONS"): 1241 target = f" ON{target}" if target else "" 1242 elif expression.name == "PROJECTIONS": 1243 target = f" ON TABLE{target}" if target else "" 1244 1245 db = self._prefixed_sql("FROM", expression, "db") 1246 1247 like = self._prefixed_sql("LIKE", expression, "like") 1248 where = self.sql(expression, "where") 1249 1250 types = self.expressions(expression, key="types") 1251 types = f" {types}" if types else types 1252 query = self._prefixed_sql("FOR QUERY", expression, "query") 1253 1254 if expression.name == "PROFILE": 1255 offset = self._prefixed_sql("OFFSET", expression, "offset") 1256 limit = self._prefixed_sql("LIMIT", expression, "limit") 1257 else: 1258 offset = "" 1259 limit = self._oldstyle_limit_sql(expression) 1260 1261 log = self._prefixed_sql("IN", expression, "log") 1262 position = self._prefixed_sql("FROM", expression, "position") 1263 1264 channel = self._prefixed_sql("FOR CHANNEL", expression, "channel") 1265 1266 if expression.name == "ENGINE": 1267 mutex_or_status = " MUTEX" if expression.args.get("mutex") else " STATUS" 1268 else: 1269 mutex_or_status = "" 1270 1271 for_table = self._prefixed_sql("FOR TABLE", expression, "for_table") 1272 for_group = self._prefixed_sql("FOR GROUP", expression, "for_group") 1273 for_user = self._prefixed_sql("FOR USER", expression, "for_user") 1274 for_role = self._prefixed_sql("FOR ROLE", expression, "for_role") 1275 into_outfile = self._prefixed_sql("INTO OUTFILE", expression, "into_outfile") 1276 json = " JSON" if expression.args.get("json") else "" 1277 1278 return f"SHOW{full}{global_}{this}{json}{target}{for_table}{types}{db}{query}{log}{position}{channel}{mutex_or_status}{like}{where}{offset}{limit}{for_group}{for_user}{for_role}{into_outfile}"
1306 def timestamptrunc_sql(self, expression: exp.TimestampTrunc) -> str: 1307 unit = expression.args.get("unit") 1308 1309 # Pick an old-enough date to avoid negative timestamp diffs 1310 start_ts = "'0000-01-01 00:00:00'" 1311 1312 # Source: https://stackoverflow.com/a/32955740 1313 timestamp_diff = build_date_delta(exp.TimestampDiff)([unit, start_ts, expression.this]) 1314 interval = exp.Interval(this=timestamp_diff, unit=unit) 1315 dateadd = build_date_delta_with_interval(exp.DateAdd)([start_ts, interval]) 1316 1317 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
- UNICODE_SUBSTITUTE
- 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
- MATCH_AGAINST_TABLE_PREFIX
- UNSUPPORTED_TYPES
- TIME_PART_SINGULARS
- TOKEN_MAPPING
- STRUCT_DELIMITER
- PARAMETER_TOKEN
- NAMED_PLACEHOLDER_TOKEN
- EXPRESSION_PRECEDES_PROPERTIES_CREATABLES
- WITH_SEPARATED_COMMENTS
- EXCLUDE_COMMENTS
- UNWRAPPED_INTERVAL_VALUES
- PARAMETERIZABLE_TEXT_TYPES
- EXPRESSIONS_WITHOUT_NESTED_CTES
- RESPECT_IGNORE_NULLS_UNSUPPORTED_EXPRESSIONS
- SAFE_JSON_PATH_KEY_RE
- SENTINEL_LINE_BREAK
- pretty
- identify
- normalize
- pad
- unsupported_level
- max_unsupported
- leading_comma
- max_text_width
- comments
- dialect
- normalize_functions
- unsupported_messages
- generate
- preprocess
- unsupported
- sep
- seg
- sanitize_comment
- maybe_comment
- wrap
- no_identify
- normalize_func
- indent
- sql
- uncache_sql
- cache_sql
- characterset_sql
- column_parts
- column_sql
- columnposition_sql
- columndef_sql
- columnconstraint_sql
- autoincrementcolumnconstraint_sql
- compresscolumnconstraint_sql
- generatedasidentitycolumnconstraint_sql
- generatedasrowcolumnconstraint_sql
- periodforsystemtimeconstraint_sql
- notnullcolumnconstraint_sql
- primarykeycolumnconstraint_sql
- uniquecolumnconstraint_sql
- createable_sql
- create_sql
- sequenceproperties_sql
- clone_sql
- describe_sql
- heredoc_sql
- prepend_ctes
- with_sql
- cte_sql
- tablealias_sql
- bitstring_sql
- hexstring_sql
- bytestring_sql
- unicodestring_sql
- rawstring_sql
- datatypeparam_sql
- directory_sql
- delete_sql
- drop_sql
- set_operation
- set_operations
- fetch_sql
- limitoptions_sql
- filter_sql
- hint_sql
- indexparameters_sql
- index_sql
- identifier_sql
- hex_sql
- lowerhex_sql
- inputoutputformat_sql
- national_sql
- partition_sql
- properties_sql
- root_properties
- properties
- with_properties
- locate_properties
- property_name
- property_sql
- likeproperty_sql
- fallbackproperty_sql
- journalproperty_sql
- freespaceproperty_sql
- checksumproperty_sql
- mergeblockratioproperty_sql
- datablocksizeproperty_sql
- blockcompressionproperty_sql
- isolatedloadingproperty_sql
- partitionboundspec_sql
- partitionedofproperty_sql
- lockingproperty_sql
- withdataproperty_sql
- withsystemversioningproperty_sql
- insert_sql
- introducer_sql
- kill_sql
- pseudotype_sql
- objectidentifier_sql
- onconflict_sql
- returning_sql
- rowformatdelimitedproperty_sql
- withtablehint_sql
- indextablehint_sql
- historicaldata_sql
- table_parts
- table_sql
- tablefromrows_sql
- tablesample_sql
- pivot_sql
- version_sql
- tuple_sql
- update_sql
- values_sql
- var_sql
- into_sql
- from_sql
- groupingsets_sql
- rollup_sql
- cube_sql
- group_sql
- having_sql
- connect_sql
- prior_sql
- join_sql
- lambda_sql
- lateral_op
- lateral_sql
- limit_sql
- offset_sql
- setitem_sql
- set_sql
- queryband_sql
- pragma_sql
- lock_sql
- literal_sql
- escape_str
- loaddata_sql
- null_sql
- boolean_sql
- order_sql
- withfill_sql
- cluster_sql
- distribute_sql
- sort_sql
- ordered_sql
- matchrecognizemeasure_sql
- matchrecognize_sql
- query_modifiers
- options_modifier
- for_modifiers
- queryoption_sql
- offset_limit_modifiers
- after_limit_modifiers
- select_sql
- schema_sql
- schema_columns_sql
- star_sql
- parameter_sql
- sessionparameter_sql
- placeholder_sql
- subquery_sql
- qualify_sql
- unnest_sql
- prewhere_sql
- where_sql
- window_sql
- partition_by_sql
- windowspec_sql
- withingroup_sql
- between_sql
- bracket_offset_expressions
- bracket_sql
- all_sql
- any_sql
- exists_sql
- case_sql
- constraint_sql
- nextvaluefor_sql
- trim_sql
- convert_concat_args
- concat_sql
- concatws_sql
- check_sql
- foreignkey_sql
- primarykey_sql
- if_sql
- matchagainst_sql
- jsonkeyvalue_sql
- jsonpath_sql
- json_path_part
- formatjson_sql
- formatphrase_sql
- jsonobject_sql
- jsonobjectagg_sql
- jsonarray_sql
- jsonarrayagg_sql
- jsoncolumndef_sql
- jsonschema_sql
- jsontable_sql
- openjsoncolumndef_sql
- openjson_sql
- in_sql
- in_unnest_op
- interval_sql
- return_sql
- reference_sql
- anonymous_sql
- paren_sql
- neg_sql
- not_sql
- alias_sql
- pivotalias_sql
- aliases_sql
- atindex_sql
- fromtimezone_sql
- add_sql
- and_sql
- or_sql
- xor_sql
- connector_sql
- bitwiseand_sql
- bitwiseleftshift_sql
- bitwisenot_sql
- bitwiseor_sql
- bitwiserightshift_sql
- bitwisexor_sql
- currentdate_sql
- collate_sql
- command_sql
- comment_sql
- mergetreettlaction_sql
- mergetreettl_sql
- transaction_sql
- commit_sql
- rollback_sql
- alterindex_sql
- alterdiststyle_sql
- altersortkey_sql
- alterrename_sql
- renamecolumn_sql
- alterset_sql
- alter_sql
- altersession_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
- generateembedding_sql
- mltranslate_sql
- mlforecast_sql
- featuresattime_sql
- vectorsearch_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
- revoke_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
- 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
- install_sql
- get_put_sql
- translatecharacters_sql
- decodecase_sql
- semanticview_sql
- getextract_sql
- datefromunixdate_sql
- space_sql
- buildproperty_sql
- refreshtriggerproperty_sql
- modelattribute_sql
- directorystage_sql