From c607356412fd76f06e318878108d0e9f993d51f2 Mon Sep 17 00:00:00 2001 From: wenshao Date: Wed, 22 Mar 2017 13:52:30 +0800 Subject: [PATCH] improved sql parser for mysql explain. for issue #1645 --- .../sql/ast/statement/SQLExplainStatement.java | 10 ++++++++++ .../druid/sql/parser/SQLStatementParser.java | 9 +++++++++ .../druid/sql/visitor/SQLASTOutputVisitor.java | 5 +++++ .../com/alibaba/druid/bvt/bug/Issue1645.java | 18 ++++++++++++++++++ 4 files changed, 42 insertions(+) create mode 100644 src/test/java/com/alibaba/druid/bvt/bug/Issue1645.java diff --git a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLExplainStatement.java b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLExplainStatement.java index 920899dd35..16678db7c6 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLExplainStatement.java +++ b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLExplainStatement.java @@ -24,6 +24,8 @@ import com.alibaba.druid.sql.visitor.SQLASTVisitor; public class SQLExplainStatement extends SQLStatementImpl { + private String type; + protected SQLStatement statement; private List hints; @@ -47,6 +49,14 @@ public class SQLExplainStatement extends SQLStatementImpl { this.statement = statement; } + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + @Override protected void accept0(SQLASTVisitor visitor) { if (visitor.visit(this)) { diff --git a/src/main/java/com/alibaba/druid/sql/parser/SQLStatementParser.java b/src/main/java/com/alibaba/druid/sql/parser/SQLStatementParser.java index dc0e936b7c..337b40b729 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/SQLStatementParser.java +++ b/src/main/java/com/alibaba/druid/sql/parser/SQLStatementParser.java @@ -2087,6 +2087,15 @@ public class SQLStatementParser extends SQLParser { explain.setHints(this.exprParser.parseHints()); } + if (JdbcConstants.MYSQL.equals(dbType)) { + if (identifierEquals("FORMAT") + || identifierEquals("EXTENDED") + || identifierEquals("PARTITIONS")) { + explain.setType(lexer.stringVal); + lexer.nextToken(); + } + } + explain.setStatement(parseStatement()); return explain; diff --git a/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java b/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java index e59bcd9cf5..0d51e537f5 100644 --- a/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java @@ -2631,6 +2631,11 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet print(' '); printAndAccept(x.getHints(), " "); } + + if (x.getType() != null) { + print(' '); + print0(x.getType()); + } println(); x.getStatement().accept(this); return false; diff --git a/src/test/java/com/alibaba/druid/bvt/bug/Issue1645.java b/src/test/java/com/alibaba/druid/bvt/bug/Issue1645.java new file mode 100644 index 0000000000..642528297b --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/bug/Issue1645.java @@ -0,0 +1,18 @@ +package com.alibaba.druid.bvt.bug; + +import com.alibaba.druid.sql.SQLUtils; +import com.alibaba.druid.util.JdbcConstants; +import junit.framework.TestCase; + +/** + * Created by wenshao on 22/03/2017. + */ +public class Issue1645 extends TestCase { + public void test_for_issue() throws Exception { + String sql = "explain extended select * from foo"; + String formatedSql = SQLUtils.format(sql, JdbcConstants.MYSQL); + assertEquals("EXPLAIN extended\n" + + "SELECT *\n" + + "FROM foo", formatedSql); + } +}