Skip to content

Commit

Permalink
feat: support EXPLAIN in mysql (#4235)
Browse files Browse the repository at this point in the history
* feat: support EXPLAIN ANALYZE in mysql

* fix format

* remove write_sql

* add DESCRIBE_STATEMENT_STYLES

* move DESCRIBE_STATEMENT_STYLES

* use DESCRIBE_STYLES

* ops
  • Loading branch information
xiaoyu-meng-mxy authored Oct 14, 2024
1 parent 202aaa0 commit eeae25e
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 1 deletion.
3 changes: 3 additions & 0 deletions sqlglot/dialects/mysql.py
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,9 @@ class Tokenizer(tokens.Tokenizer):
KEYWORDS = {
**tokens.Tokenizer.KEYWORDS,
"CHARSET": TokenType.CHARACTER_SET,
# The DESCRIBE and EXPLAIN statements are synonyms.
# https://dev.mysql.com/doc/refman/8.4/en/explain.html
"EXPLAIN": TokenType.DESCRIBE,
"FORCE": TokenType.FORCE,
"IGNORE": TokenType.IGNORE,
"KEY": TokenType.KEY,
Expand Down
5 changes: 4 additions & 1 deletion sqlglot/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -1286,6 +1286,9 @@ class Parser(metaclass=_Parser):

PRIVILEGE_FOLLOW_TOKENS = {TokenType.ON, TokenType.COMMA, TokenType.L_PAREN}

# The style options for the DESCRIBE statement
DESCRIBE_STYLES = {"ANALYZE", "EXTENDED", "FORMATTED", "HISTORY"}

STRICT_CAST = True

PREFIXED_PIVOT_COLUMNS = False
Expand Down Expand Up @@ -2567,7 +2570,7 @@ def _parse_returns(self) -> exp.ReturnsProperty:

def _parse_describe(self) -> exp.Describe:
kind = self._match_set(self.CREATABLES) and self._prev.text
style = self._match_texts(("EXTENDED", "FORMATTED", "HISTORY")) and self._prev.text.upper()
style = self._match_texts(self.DESCRIBE_STYLES) and self._prev.text.upper()
if self._match(TokenType.DOT):
style = None
self._retreat(self._index - 2)
Expand Down
9 changes: 9 additions & 0 deletions tests/dialects/test_mysql.py
Original file line number Diff line number Diff line change
Expand Up @@ -1305,3 +1305,12 @@ def test_grant(self):
for sql in grant_cmds:
with self.subTest(f"Testing MySQL's GRANT command statement: {sql}"):
self.validate_identity(sql, check_command_warning=True)

def test_explain(self):
self.validate_identity(
"EXPLAIN ANALYZE SELECT * FROM t", "DESCRIBE ANALYZE SELECT * FROM t"
)

expression = self.parse_one("EXPLAIN ANALYZE SELECT * FROM t")
self.assertIsInstance(expression, exp.Describe)
self.assertEqual(expression.text("style"), "ANALYZE")

0 comments on commit eeae25e

Please sign in to comment.