Skip to content

Commit

Permalink
fix(mysql): transpile CHAR (#2329)
Browse files Browse the repository at this point in the history
  • Loading branch information
barakalon authored Sep 26, 2023
1 parent ebdfc59 commit 8242a2c
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 0 deletions.
19 changes: 19 additions & 0 deletions sqlglot/dialects/mysql.py
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,7 @@ class Parser(parser.Parser):

FUNCTION_PARSERS = {
**parser.Parser.FUNCTION_PARSERS,
"CHAR": lambda self: self._parse_chr(),
"GROUP_CONCAT": lambda self: self.expression(
exp.GroupConcat,
this=self._parse_lambda(),
Expand Down Expand Up @@ -531,6 +532,18 @@ def _parse_type(self, parse_interval: bool = True) -> t.Optional[exp.Expression]

return super()._parse_type(parse_interval=parse_interval)

def _parse_chr(self) -> t.Optional[exp.Expression]:
expressions = self._parse_csv(self._parse_conjunction)
kwargs: t.Dict[str, t.Any] = {"this": seq_get(expressions, 0)}

if len(expressions) > 1:
kwargs["expressions"] = expressions[1:]

if self._match(TokenType.USING):
kwargs["charset"] = self._parse_var()

return self.expression(exp.Chr, **kwargs)

class Generator(generator.Generator):
LOCKING_READS_SUPPORTED = True
NULL_ORDERING_SUPPORTED = False
Expand Down Expand Up @@ -717,3 +730,9 @@ def _oldstyle_limit_sql(self, expression: exp.Show) -> str:
limit_offset = f"{offset}, {limit}" if offset else limit
return f" LIMIT {limit_offset}"
return ""

def chr_sql(self, expression: exp.Chr) -> str:
this = self.expressions(sqls=[expression.this] + expression.expressions)
charset = expression.args.get("charset")
using = f" USING {self.sql(charset)}" if charset else ""
return f"CHAR({this}{using})"
6 changes: 6 additions & 0 deletions sqlglot/expressions.py
Original file line number Diff line number Diff line change
Expand Up @@ -4293,6 +4293,12 @@ class Coalesce(Func):
_sql_names = ["COALESCE", "IFNULL", "NVL"]


class Chr(Func):
arg_types = {"this": True, "charset": False, "expressions": False}
is_var_len_args = True
_sql_names = ["CHR", "CHAR"]


class Concat(Func):
arg_types = {"expressions": True}
is_var_len_args = True
Expand Down
10 changes: 10 additions & 0 deletions tests/dialects/test_mysql.py
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,9 @@ def test_identity(self):
)
self.validate_identity("INTERVAL '1' YEAR")
self.validate_identity("DATE_ADD(x, INTERVAL 1 YEAR)")
self.validate_identity("CHAR(0)")
self.validate_identity("CHAR(77, 121, 83, 81, '76')")
self.validate_identity("CHAR(77, 77.3, '77.3' USING utf8mb4)")

def test_types(self):
self.validate_identity("CAST(x AS MEDIUMINT) + CAST(y AS YEAR(4))")
Expand Down Expand Up @@ -244,6 +247,13 @@ def test_canonical_functions(self):
self.validate_identity(
"SELECT WEEK_OF_YEAR('2023-01-01')", "SELECT WEEKOFYEAR('2023-01-01')"
)
self.validate_all(
"CHAR(10)",
write={
"mysql": "CHAR(10)",
"presto": "CHR(10)",
},
)

def test_escape(self):
self.validate_identity("""'"abc"'""")
Expand Down
1 change: 1 addition & 0 deletions tests/fixtures/identity.sql
Original file line number Diff line number Diff line change
Expand Up @@ -864,3 +864,4 @@ SELECT x FROM y ORDER BY x ASC
KILL '123'
KILL CONNECTION 123
KILL QUERY '123'
CHR(97)

0 comments on commit 8242a2c

Please sign in to comment.