sqlglot.dialects.mysql
1from __future__ import annotations 2 3from sqlglot import tokens 4from sqlglot.dialects.dialect import ( 5 Dialect, 6 NormalizationStrategy, 7 UsingColumnOrder, 8) 9from sqlglot.generators.mysql import MySQLGenerator 10from sqlglot.parsers.mysql import MySQLParser 11from sqlglot.tokens import TokenType 12from sqlglot.typing.mysql import EXPRESSION_METADATA 13 14 15class MySQL(Dialect): 16 PROMOTE_TO_INFERRED_DATETIME_TYPE = True 17 USING_COLUMN_ORDER = UsingColumnOrder.LEFT_TABLE 18 19 # https://dev.mysql.com/doc/refman/8.0/en/identifiers.html 20 IDENTIFIERS_CAN_START_WITH_DIGIT = True 21 22 # We default to treating all identifiers as case-sensitive, since it matches MySQL's 23 # behavior on Linux systems. For MacOS and Windows systems, one can override this 24 # setting by specifying `dialect="mysql, normalization_strategy = lowercase"`. 25 # 26 # See also https://dev.mysql.com/doc/refman/8.2/en/identifier-case-sensitivity.html 27 NORMALIZATION_STRATEGY = NormalizationStrategy.CASE_SENSITIVE 28 29 TIME_FORMAT = "'%Y-%m-%d %T'" 30 DPIPE_IS_STRING_CONCAT = False 31 CONCAT_WS_COALESCE = True 32 SUPPORTS_USER_DEFINED_TYPES = False 33 SAFE_DIVISION = True 34 SAFE_TO_ELIMINATE_DOUBLE_NEGATION = False 35 LEAST_GREATEST_IGNORES_NULLS = False 36 37 EXPRESSION_METADATA = EXPRESSION_METADATA.copy() 38 39 # https://prestodb.io/docs/current/functions/datetime.html#mysql-date-functions 40 TIME_MAPPING = { 41 "%M": "%B", 42 "%c": "%-m", 43 "%e": "%-d", 44 "%h": "%I", 45 "%i": "%M", 46 "%s": "%S", 47 "%u": "%W", 48 "%k": "%-H", 49 "%l": "%-I", 50 "%r": "%I:%M:%S %p", 51 "%T": "%H:%M:%S", 52 "%W": "%A", 53 "%x": "%G", 54 # %v (ISO week) is unmapped due to collision with %V (roundtrip issue) 55 } 56 57 VALID_INTERVAL_UNITS = { 58 *Dialect.VALID_INTERVAL_UNITS, 59 "SECOND_MICROSECOND", 60 "MINUTE_MICROSECOND", 61 "MINUTE_SECOND", 62 "HOUR_MICROSECOND", 63 "HOUR_SECOND", 64 "HOUR_MINUTE", 65 "DAY_MICROSECOND", 66 "DAY_SECOND", 67 "DAY_MINUTE", 68 "DAY_HOUR", 69 "YEAR_MONTH", 70 } 71 72 UNESCAPED_SEQUENCES = { 73 "\\0": "\0", 74 "\\Z": "\x1a", 75 "\\%": "\\%", 76 "\\_": "\\_", 77 "\\a": "a", 78 "\\f": "f", 79 "\\v": "v", 80 } 81 82 class Tokenizer(tokens.Tokenizer): 83 QUOTES = ["'", '"'] 84 COMMENTS = ["--", "#", ("/*", "*/")] 85 IDENTIFIERS = ["`"] 86 STRING_ESCAPES = ["'", '"', "\\"] 87 BIT_STRINGS = [("b'", "'"), ("B'", "'"), ("0b", "")] 88 HEX_STRINGS = [("x'", "'"), ("X'", "'"), ("0x", "")] 89 # https://dev.mysql.com/doc/refman/8.4/en/string-literals.html 90 DROP_UNKNOWN_ESCAPES = True 91 92 NESTED_COMMENTS = False 93 DASH_COMMENT_REQUIRES_BOUNDARY = True 94 COMMENTS_TERMINATE_AT_NEWLINE_ONLY = True 95 96 KEYWORDS = { 97 **tokens.Tokenizer.KEYWORDS, 98 "BLOB": TokenType.BLOB, 99 "CHARSET": TokenType.CHARACTER_SET, 100 "DISTINCTROW": TokenType.DISTINCT, 101 "EXPLAIN": TokenType.DESCRIBE, 102 "FORCE": TokenType.FORCE, 103 "IGNORE": TokenType.IGNORE, 104 "KEY": TokenType.KEY, 105 "LOCK TABLES": TokenType.COMMAND, 106 "LONGBLOB": TokenType.LONGBLOB, 107 "LONGTEXT": TokenType.LONGTEXT, 108 "MEDIUMBLOB": TokenType.MEDIUMBLOB, 109 "MEDIUMINT": TokenType.MEDIUMINT, 110 "MEDIUMTEXT": TokenType.MEDIUMTEXT, 111 "MEMBER OF": TokenType.MEMBER_OF, 112 "MOD": TokenType.MOD, 113 "SEPARATOR": TokenType.SEPARATOR, 114 "SERIAL": TokenType.SERIAL, 115 "SIGNED": TokenType.BIGINT, 116 "SIGNED INTEGER": TokenType.BIGINT, 117 "START": TokenType.BEGIN, 118 "TIMESTAMP": TokenType.TIMESTAMPTZ, 119 "TINYBLOB": TokenType.TINYBLOB, 120 "TINYTEXT": TokenType.TINYTEXT, 121 "UNLOCK TABLES": TokenType.COMMAND, 122 "UNSIGNED": TokenType.UBIGINT, 123 "UNSIGNED INTEGER": TokenType.UBIGINT, 124 "YEAR": TokenType.YEAR, 125 "_ARMSCII8": TokenType.INTRODUCER, 126 "_ASCII": TokenType.INTRODUCER, 127 "_BIG5": TokenType.INTRODUCER, 128 "_BINARY": TokenType.INTRODUCER, 129 "_CP1250": TokenType.INTRODUCER, 130 "_CP1251": TokenType.INTRODUCER, 131 "_CP1256": TokenType.INTRODUCER, 132 "_CP1257": TokenType.INTRODUCER, 133 "_CP850": TokenType.INTRODUCER, 134 "_CP852": TokenType.INTRODUCER, 135 "_CP866": TokenType.INTRODUCER, 136 "_CP932": TokenType.INTRODUCER, 137 "_DEC8": TokenType.INTRODUCER, 138 "_EUCJPMS": TokenType.INTRODUCER, 139 "_EUCKR": TokenType.INTRODUCER, 140 "_GB18030": TokenType.INTRODUCER, 141 "_GB2312": TokenType.INTRODUCER, 142 "_GBK": TokenType.INTRODUCER, 143 "_GEOSTD8": TokenType.INTRODUCER, 144 "_GREEK": TokenType.INTRODUCER, 145 "_HEBREW": TokenType.INTRODUCER, 146 "_HP8": TokenType.INTRODUCER, 147 "_KEYBCS2": TokenType.INTRODUCER, 148 "_KOI8R": TokenType.INTRODUCER, 149 "_KOI8U": TokenType.INTRODUCER, 150 "_LATIN1": TokenType.INTRODUCER, 151 "_LATIN2": TokenType.INTRODUCER, 152 "_LATIN5": TokenType.INTRODUCER, 153 "_LATIN7": TokenType.INTRODUCER, 154 "_MACCE": TokenType.INTRODUCER, 155 "_MACROMAN": TokenType.INTRODUCER, 156 "_SJIS": TokenType.INTRODUCER, 157 "_SWE7": TokenType.INTRODUCER, 158 "_TIS620": TokenType.INTRODUCER, 159 "_UCS2": TokenType.INTRODUCER, 160 "_UJIS": TokenType.INTRODUCER, 161 # https://dev.mysql.com/doc/refman/8.0/en/string-literals.html 162 "_UTF8": TokenType.INTRODUCER, 163 "_UTF16": TokenType.INTRODUCER, 164 "_UTF16LE": TokenType.INTRODUCER, 165 "_UTF32": TokenType.INTRODUCER, 166 "_UTF8MB3": TokenType.INTRODUCER, 167 "_UTF8MB4": TokenType.INTRODUCER, 168 "@@": TokenType.SESSION_PARAMETER, 169 } 170 171 COMMANDS = {*tokens.Tokenizer.COMMANDS, TokenType.REPLACE} - {TokenType.SHOW} 172 173 Parser = MySQLParser 174 175 Generator = MySQLGenerator
16class MySQL(Dialect): 17 PROMOTE_TO_INFERRED_DATETIME_TYPE = True 18 USING_COLUMN_ORDER = UsingColumnOrder.LEFT_TABLE 19 20 # https://dev.mysql.com/doc/refman/8.0/en/identifiers.html 21 IDENTIFIERS_CAN_START_WITH_DIGIT = True 22 23 # We default to treating all identifiers as case-sensitive, since it matches MySQL's 24 # behavior on Linux systems. For MacOS and Windows systems, one can override this 25 # setting by specifying `dialect="mysql, normalization_strategy = lowercase"`. 26 # 27 # See also https://dev.mysql.com/doc/refman/8.2/en/identifier-case-sensitivity.html 28 NORMALIZATION_STRATEGY = NormalizationStrategy.CASE_SENSITIVE 29 30 TIME_FORMAT = "'%Y-%m-%d %T'" 31 DPIPE_IS_STRING_CONCAT = False 32 CONCAT_WS_COALESCE = True 33 SUPPORTS_USER_DEFINED_TYPES = False 34 SAFE_DIVISION = True 35 SAFE_TO_ELIMINATE_DOUBLE_NEGATION = False 36 LEAST_GREATEST_IGNORES_NULLS = False 37 38 EXPRESSION_METADATA = EXPRESSION_METADATA.copy() 39 40 # https://prestodb.io/docs/current/functions/datetime.html#mysql-date-functions 41 TIME_MAPPING = { 42 "%M": "%B", 43 "%c": "%-m", 44 "%e": "%-d", 45 "%h": "%I", 46 "%i": "%M", 47 "%s": "%S", 48 "%u": "%W", 49 "%k": "%-H", 50 "%l": "%-I", 51 "%r": "%I:%M:%S %p", 52 "%T": "%H:%M:%S", 53 "%W": "%A", 54 "%x": "%G", 55 # %v (ISO week) is unmapped due to collision with %V (roundtrip issue) 56 } 57 58 VALID_INTERVAL_UNITS = { 59 *Dialect.VALID_INTERVAL_UNITS, 60 "SECOND_MICROSECOND", 61 "MINUTE_MICROSECOND", 62 "MINUTE_SECOND", 63 "HOUR_MICROSECOND", 64 "HOUR_SECOND", 65 "HOUR_MINUTE", 66 "DAY_MICROSECOND", 67 "DAY_SECOND", 68 "DAY_MINUTE", 69 "DAY_HOUR", 70 "YEAR_MONTH", 71 } 72 73 UNESCAPED_SEQUENCES = { 74 "\\0": "\0", 75 "\\Z": "\x1a", 76 "\\%": "\\%", 77 "\\_": "\\_", 78 "\\a": "a", 79 "\\f": "f", 80 "\\v": "v", 81 } 82 83 class Tokenizer(tokens.Tokenizer): 84 QUOTES = ["'", '"'] 85 COMMENTS = ["--", "#", ("/*", "*/")] 86 IDENTIFIERS = ["`"] 87 STRING_ESCAPES = ["'", '"', "\\"] 88 BIT_STRINGS = [("b'", "'"), ("B'", "'"), ("0b", "")] 89 HEX_STRINGS = [("x'", "'"), ("X'", "'"), ("0x", "")] 90 # https://dev.mysql.com/doc/refman/8.4/en/string-literals.html 91 DROP_UNKNOWN_ESCAPES = True 92 93 NESTED_COMMENTS = False 94 DASH_COMMENT_REQUIRES_BOUNDARY = True 95 COMMENTS_TERMINATE_AT_NEWLINE_ONLY = True 96 97 KEYWORDS = { 98 **tokens.Tokenizer.KEYWORDS, 99 "BLOB": TokenType.BLOB, 100 "CHARSET": TokenType.CHARACTER_SET, 101 "DISTINCTROW": TokenType.DISTINCT, 102 "EXPLAIN": TokenType.DESCRIBE, 103 "FORCE": TokenType.FORCE, 104 "IGNORE": TokenType.IGNORE, 105 "KEY": TokenType.KEY, 106 "LOCK TABLES": TokenType.COMMAND, 107 "LONGBLOB": TokenType.LONGBLOB, 108 "LONGTEXT": TokenType.LONGTEXT, 109 "MEDIUMBLOB": TokenType.MEDIUMBLOB, 110 "MEDIUMINT": TokenType.MEDIUMINT, 111 "MEDIUMTEXT": TokenType.MEDIUMTEXT, 112 "MEMBER OF": TokenType.MEMBER_OF, 113 "MOD": TokenType.MOD, 114 "SEPARATOR": TokenType.SEPARATOR, 115 "SERIAL": TokenType.SERIAL, 116 "SIGNED": TokenType.BIGINT, 117 "SIGNED INTEGER": TokenType.BIGINT, 118 "START": TokenType.BEGIN, 119 "TIMESTAMP": TokenType.TIMESTAMPTZ, 120 "TINYBLOB": TokenType.TINYBLOB, 121 "TINYTEXT": TokenType.TINYTEXT, 122 "UNLOCK TABLES": TokenType.COMMAND, 123 "UNSIGNED": TokenType.UBIGINT, 124 "UNSIGNED INTEGER": TokenType.UBIGINT, 125 "YEAR": TokenType.YEAR, 126 "_ARMSCII8": TokenType.INTRODUCER, 127 "_ASCII": TokenType.INTRODUCER, 128 "_BIG5": TokenType.INTRODUCER, 129 "_BINARY": TokenType.INTRODUCER, 130 "_CP1250": TokenType.INTRODUCER, 131 "_CP1251": TokenType.INTRODUCER, 132 "_CP1256": TokenType.INTRODUCER, 133 "_CP1257": TokenType.INTRODUCER, 134 "_CP850": TokenType.INTRODUCER, 135 "_CP852": TokenType.INTRODUCER, 136 "_CP866": TokenType.INTRODUCER, 137 "_CP932": TokenType.INTRODUCER, 138 "_DEC8": TokenType.INTRODUCER, 139 "_EUCJPMS": TokenType.INTRODUCER, 140 "_EUCKR": TokenType.INTRODUCER, 141 "_GB18030": TokenType.INTRODUCER, 142 "_GB2312": TokenType.INTRODUCER, 143 "_GBK": TokenType.INTRODUCER, 144 "_GEOSTD8": TokenType.INTRODUCER, 145 "_GREEK": TokenType.INTRODUCER, 146 "_HEBREW": TokenType.INTRODUCER, 147 "_HP8": TokenType.INTRODUCER, 148 "_KEYBCS2": TokenType.INTRODUCER, 149 "_KOI8R": TokenType.INTRODUCER, 150 "_KOI8U": TokenType.INTRODUCER, 151 "_LATIN1": TokenType.INTRODUCER, 152 "_LATIN2": TokenType.INTRODUCER, 153 "_LATIN5": TokenType.INTRODUCER, 154 "_LATIN7": TokenType.INTRODUCER, 155 "_MACCE": TokenType.INTRODUCER, 156 "_MACROMAN": TokenType.INTRODUCER, 157 "_SJIS": TokenType.INTRODUCER, 158 "_SWE7": TokenType.INTRODUCER, 159 "_TIS620": TokenType.INTRODUCER, 160 "_UCS2": TokenType.INTRODUCER, 161 "_UJIS": TokenType.INTRODUCER, 162 # https://dev.mysql.com/doc/refman/8.0/en/string-literals.html 163 "_UTF8": TokenType.INTRODUCER, 164 "_UTF16": TokenType.INTRODUCER, 165 "_UTF16LE": TokenType.INTRODUCER, 166 "_UTF32": TokenType.INTRODUCER, 167 "_UTF8MB3": TokenType.INTRODUCER, 168 "_UTF8MB4": TokenType.INTRODUCER, 169 "@@": TokenType.SESSION_PARAMETER, 170 } 171 172 COMMANDS = {*tokens.Tokenizer.COMMANDS, TokenType.REPLACE} - {TokenType.SHOW} 173 174 Parser = MySQLParser 175 176 Generator = MySQLGenerator
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.
Where star expansion places the columns of a USING or NATURAL join.
Given a(a_id, k1, k2) and b(k2, b_id, k1), SELECT * FROM a JOIN b USING (k2, k1) returns:
USING_LIST:k2, k1, a_id, b_idLEFT_TABLE:k1, k2, a_id, b_idIN_PLACE:a_id, k1, k2, b_id
When join columns come first, this applies at every join: each USING join moves its columns ahead of all the columns to its left.
Specifies the strategy according to which identifiers should be normalized.
A NULL arg in CONCAT_WS yields NULL by default, but in some dialects it is skipped.
Whether LEAST/GREATEST functions ignore NULL values, e.g:
- BigQuery, Snowflake, MySQL, Presto/Trino: LEAST(1, NULL, 2) -> NULL
- Spark, Postgres, DuckDB, TSQL: LEAST(1, NULL, 2) -> 1
Associates this dialect's time formats with their equivalent Python strftime formats.
Mapping of an escaped sequence (\n) to its unescaped version (
).
Whether string literals support escape sequences (e.g. \n). Set by the metaclass based on the tokenizer's STRING_ESCAPES.
Whether byte string literals support escape sequences. Set by the metaclass based on the tokenizer's BYTE_STRING_ESCAPES.
Mapping of an identifier escape char (\) to its escaped version (\\). Set by the metaclass based on the tokenizer's IDENTIFIER_ESCAPES.
83 class Tokenizer(tokens.Tokenizer): 84 QUOTES = ["'", '"'] 85 COMMENTS = ["--", "#", ("/*", "*/")] 86 IDENTIFIERS = ["`"] 87 STRING_ESCAPES = ["'", '"', "\\"] 88 BIT_STRINGS = [("b'", "'"), ("B'", "'"), ("0b", "")] 89 HEX_STRINGS = [("x'", "'"), ("X'", "'"), ("0x", "")] 90 # https://dev.mysql.com/doc/refman/8.4/en/string-literals.html 91 DROP_UNKNOWN_ESCAPES = True 92 93 NESTED_COMMENTS = False 94 DASH_COMMENT_REQUIRES_BOUNDARY = True 95 COMMENTS_TERMINATE_AT_NEWLINE_ONLY = True 96 97 KEYWORDS = { 98 **tokens.Tokenizer.KEYWORDS, 99 "BLOB": TokenType.BLOB, 100 "CHARSET": TokenType.CHARACTER_SET, 101 "DISTINCTROW": TokenType.DISTINCT, 102 "EXPLAIN": TokenType.DESCRIBE, 103 "FORCE": TokenType.FORCE, 104 "IGNORE": TokenType.IGNORE, 105 "KEY": TokenType.KEY, 106 "LOCK TABLES": TokenType.COMMAND, 107 "LONGBLOB": TokenType.LONGBLOB, 108 "LONGTEXT": TokenType.LONGTEXT, 109 "MEDIUMBLOB": TokenType.MEDIUMBLOB, 110 "MEDIUMINT": TokenType.MEDIUMINT, 111 "MEDIUMTEXT": TokenType.MEDIUMTEXT, 112 "MEMBER OF": TokenType.MEMBER_OF, 113 "MOD": TokenType.MOD, 114 "SEPARATOR": TokenType.SEPARATOR, 115 "SERIAL": TokenType.SERIAL, 116 "SIGNED": TokenType.BIGINT, 117 "SIGNED INTEGER": TokenType.BIGINT, 118 "START": TokenType.BEGIN, 119 "TIMESTAMP": TokenType.TIMESTAMPTZ, 120 "TINYBLOB": TokenType.TINYBLOB, 121 "TINYTEXT": TokenType.TINYTEXT, 122 "UNLOCK TABLES": TokenType.COMMAND, 123 "UNSIGNED": TokenType.UBIGINT, 124 "UNSIGNED INTEGER": TokenType.UBIGINT, 125 "YEAR": TokenType.YEAR, 126 "_ARMSCII8": TokenType.INTRODUCER, 127 "_ASCII": TokenType.INTRODUCER, 128 "_BIG5": TokenType.INTRODUCER, 129 "_BINARY": TokenType.INTRODUCER, 130 "_CP1250": TokenType.INTRODUCER, 131 "_CP1251": TokenType.INTRODUCER, 132 "_CP1256": TokenType.INTRODUCER, 133 "_CP1257": TokenType.INTRODUCER, 134 "_CP850": TokenType.INTRODUCER, 135 "_CP852": TokenType.INTRODUCER, 136 "_CP866": TokenType.INTRODUCER, 137 "_CP932": TokenType.INTRODUCER, 138 "_DEC8": TokenType.INTRODUCER, 139 "_EUCJPMS": TokenType.INTRODUCER, 140 "_EUCKR": TokenType.INTRODUCER, 141 "_GB18030": TokenType.INTRODUCER, 142 "_GB2312": TokenType.INTRODUCER, 143 "_GBK": TokenType.INTRODUCER, 144 "_GEOSTD8": TokenType.INTRODUCER, 145 "_GREEK": TokenType.INTRODUCER, 146 "_HEBREW": TokenType.INTRODUCER, 147 "_HP8": TokenType.INTRODUCER, 148 "_KEYBCS2": TokenType.INTRODUCER, 149 "_KOI8R": TokenType.INTRODUCER, 150 "_KOI8U": TokenType.INTRODUCER, 151 "_LATIN1": TokenType.INTRODUCER, 152 "_LATIN2": TokenType.INTRODUCER, 153 "_LATIN5": TokenType.INTRODUCER, 154 "_LATIN7": TokenType.INTRODUCER, 155 "_MACCE": TokenType.INTRODUCER, 156 "_MACROMAN": TokenType.INTRODUCER, 157 "_SJIS": TokenType.INTRODUCER, 158 "_SWE7": TokenType.INTRODUCER, 159 "_TIS620": TokenType.INTRODUCER, 160 "_UCS2": TokenType.INTRODUCER, 161 "_UJIS": TokenType.INTRODUCER, 162 # https://dev.mysql.com/doc/refman/8.0/en/string-literals.html 163 "_UTF8": TokenType.INTRODUCER, 164 "_UTF16": TokenType.INTRODUCER, 165 "_UTF16LE": TokenType.INTRODUCER, 166 "_UTF32": TokenType.INTRODUCER, 167 "_UTF8MB3": TokenType.INTRODUCER, 168 "_UTF8MB4": TokenType.INTRODUCER, 169 "@@": TokenType.SESSION_PARAMETER, 170 } 171 172 COMMANDS = {*tokens.Tokenizer.COMMANDS, TokenType.REPLACE} - {TokenType.SHOW}
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
- NUMERIC_ESCAPES
- NUMERIC_ESCAPES_ARE_BYTES
- LONE_SURROGATE_REPLACEMENT
- HINT_START
- TOKENS_PRECEDING_HINT
- COMMAND_PREFIX_TOKENS
- NUMERIC_LITERALS
- NUMBERS_CAN_HAVE_DECIMALS
- dialect
- tokenize
- sql
- size
- tokens