diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2023-09-07 11:39:43 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2023-09-07 11:39:43 +0000 |
commit | 341eb1a6bdf0dd5b015e5140d3b068c6fd3f4d87 (patch) | |
tree | 61fb7eca2238fb5d41d3906f4af41de03abd25ea /sqlglot/dialects/mysql.py | |
parent | Adding upstream version 17.12.0. (diff) | |
download | sqlglot-341eb1a6bdf0dd5b015e5140d3b068c6fd3f4d87.tar.xz sqlglot-341eb1a6bdf0dd5b015e5140d3b068c6fd3f4d87.zip |
Adding upstream version 18.2.0.upstream/18.2.0
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'sqlglot/dialects/mysql.py')
-rw-r--r-- | sqlglot/dialects/mysql.py | 32 |
1 files changed, 27 insertions, 5 deletions
diff --git a/sqlglot/dialects/mysql.py b/sqlglot/dialects/mysql.py index 9ab4ce8..f9249eb 100644 --- a/sqlglot/dialects/mysql.py +++ b/sqlglot/dialects/mysql.py @@ -8,6 +8,7 @@ from sqlglot.dialects.dialect import ( arrow_json_extract_scalar_sql, datestrtodate_sql, format_time_lambda, + json_keyvalue_comma_sql, locate_to_strposition, max_or_greatest, min_or_least, @@ -32,7 +33,7 @@ def _show_parser(*args: t.Any, **kwargs: t.Any) -> t.Callable[[MySQL.Parser], ex return _parse -def _date_trunc_sql(self: generator.Generator, expression: exp.DateTrunc) -> str: +def _date_trunc_sql(self: MySQL.Generator, expression: exp.DateTrunc) -> str: expr = self.sql(expression, "this") unit = expression.text("unit") @@ -63,12 +64,12 @@ def _str_to_date(args: t.List) -> exp.StrToDate: return exp.StrToDate(this=seq_get(args, 0), format=date_format) -def _str_to_date_sql(self: generator.Generator, expression: exp.StrToDate | exp.StrToTime) -> str: +def _str_to_date_sql(self: MySQL.Generator, expression: exp.StrToDate | exp.StrToTime) -> str: date_format = self.format_time(expression) return f"STR_TO_DATE({self.sql(expression.this)}, {date_format})" -def _trim_sql(self: generator.Generator, expression: exp.Trim) -> str: +def _trim_sql(self: MySQL.Generator, expression: exp.Trim) -> str: target = self.sql(expression, "this") trim_type = self.sql(expression, "position") remove_chars = self.sql(expression, "expression") @@ -83,8 +84,8 @@ def _trim_sql(self: generator.Generator, expression: exp.Trim) -> str: return f"TRIM({trim_type}{remove_chars}{from_part}{target})" -def _date_add_sql(kind: str) -> t.Callable[[generator.Generator, exp.DateAdd | exp.DateSub], str]: - def func(self: generator.Generator, expression: exp.DateAdd | exp.DateSub) -> str: +def _date_add_sql(kind: str) -> t.Callable[[MySQL.Generator, exp.DateAdd | exp.DateSub], str]: + def func(self: MySQL.Generator, expression: exp.DateAdd | exp.DateSub) -> str: this = self.sql(expression, "this") unit = expression.text("unit").upper() or "DAY" return f"DATE_{kind}({this}, {self.sql(exp.Interval(this=expression.expression.copy(), unit=unit))})" @@ -93,6 +94,9 @@ def _date_add_sql(kind: str) -> t.Callable[[generator.Generator, exp.DateAdd | e class MySQL(Dialect): + # https://dev.mysql.com/doc/refman/8.0/en/identifiers.html + IDENTIFIERS_CAN_START_WITH_DIGIT = True + TIME_FORMAT = "'%Y-%m-%d %T'" DPIPE_IS_STRING_CONCAT = False @@ -129,6 +133,7 @@ class MySQL(Dialect): "LONGTEXT": TokenType.LONGTEXT, "MEDIUMBLOB": TokenType.MEDIUMBLOB, "MEDIUMTEXT": TokenType.MEDIUMTEXT, + "MEDIUMINT": TokenType.MEDIUMINT, "MEMBER OF": TokenType.MEMBER_OF, "SEPARATOR": TokenType.SEPARATOR, "START": TokenType.BEGIN, @@ -136,6 +141,7 @@ class MySQL(Dialect): "SIGNED INTEGER": TokenType.BIGINT, "UNSIGNED": TokenType.UBIGINT, "UNSIGNED INTEGER": TokenType.UBIGINT, + "YEAR": TokenType.YEAR, "_ARMSCII8": TokenType.INTRODUCER, "_ASCII": TokenType.INTRODUCER, "_BIG5": TokenType.INTRODUCER, @@ -185,6 +191,8 @@ class MySQL(Dialect): COMMANDS = tokens.Tokenizer.COMMANDS - {TokenType.SHOW} class Parser(parser.Parser): + SUPPORTS_USER_DEFINED_TYPES = False + FUNC_TOKENS = { *parser.Parser.FUNC_TOKENS, TokenType.DATABASE, @@ -492,6 +500,17 @@ class MySQL(Dialect): return self.expression(exp.SetItem, this=charset, collate=collate, kind="NAMES") + def _parse_type(self) -> t.Optional[exp.Expression]: + # mysql binary is special and can work anywhere, even in order by operations + # it operates like a no paren func + if self._match(TokenType.BINARY, advance=False): + data_type = self._parse_types(check_func=True, allow_identifiers=False) + + if isinstance(data_type, exp.DataType): + return self.expression(exp.Cast, this=self._parse_column(), to=data_type) + + return super()._parse_type() + class Generator(generator.Generator): LOCKING_READS_SUPPORTED = True NULL_ORDERING_SUPPORTED = False @@ -500,6 +519,7 @@ class MySQL(Dialect): DUPLICATE_KEY_UPDATE_WITH_SET = False QUERY_HINT_SEP = " " VALUES_AS_TABLE = False + NVL2_SUPPORTED = False TRANSFORMS = { **generator.Generator.TRANSFORMS, @@ -515,6 +535,7 @@ class MySQL(Dialect): exp.GroupConcat: lambda self, e: f"""GROUP_CONCAT({self.sql(e, "this")} SEPARATOR {self.sql(e, "separator") or "','"})""", exp.ILike: no_ilike_sql, exp.JSONExtractScalar: arrow_json_extract_scalar_sql, + exp.JSONKeyValue: json_keyvalue_comma_sql, exp.Max: max_or_greatest, exp.Min: min_or_least, exp.NullSafeEQ: lambda self, e: self.binary(e, "<=>"), @@ -524,6 +545,7 @@ class MySQL(Dialect): exp.StrPosition: strposition_to_locate_sql, exp.StrToDate: _str_to_date_sql, exp.StrToTime: _str_to_date_sql, + exp.Stuff: rename_func("INSERT"), exp.TableSample: no_tablesample_sql, exp.TimeStrToUnix: rename_func("UNIX_TIMESTAMP"), exp.TimeStrToTime: lambda self, e: self.sql(exp.cast(e.this, "datetime", copy=True)), |