diff --git a/src/main/java/com/alibaba/druid/mapping/spi/MySqlMappingProvider.java b/src/main/java/com/alibaba/druid/mapping/spi/MySqlMappingProvider.java index fdc5d36e2f..518f95b662 100644 --- a/src/main/java/com/alibaba/druid/mapping/spi/MySqlMappingProvider.java +++ b/src/main/java/com/alibaba/druid/mapping/spi/MySqlMappingProvider.java @@ -2,7 +2,9 @@ package com.alibaba.druid.mapping.spi; import java.util.List; +import com.alibaba.druid.mapping.Entity; import com.alibaba.druid.mapping.MappingEngine; +import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr; import com.alibaba.druid.sql.ast.expr.SQLIntegerExpr; import com.alibaba.druid.sql.ast.expr.SQLNumericLiteralExpr; import com.alibaba.druid.sql.ast.statement.SQLInsertStatement; @@ -53,7 +55,14 @@ public class MySqlMappingProvider implements MappingProvider { public MySqlDeleteStatement explainToDeleteSQLObject(MappingEngine engine, String sql) { MySqlStatementParser parser = new MySqlStatementParser(sql); - return parser.parseDeleteStatement(); + + MySqlDeleteStatement stmt = parser.parseDeleteStatement(); + if (stmt.getTableSource() == null) { + Entity entity = engine.getFirstEntity(); + stmt.setTableName(new SQLIdentifierExpr(entity.getName())); + } + + return stmt; } public SQLUpdateStatement explainToUpdateSQLObject(MappingEngine engine, String sql) { diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/statement/MySqlDeleteStatement.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/statement/MySqlDeleteStatement.java index 60a71bc8eb..8f2f6a73d6 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/statement/MySqlDeleteStatement.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/statement/MySqlDeleteStatement.java @@ -21,6 +21,7 @@ import java.util.List; import com.alibaba.druid.sql.ast.SQLName; import com.alibaba.druid.sql.ast.SQLOrderBy; import com.alibaba.druid.sql.ast.statement.SQLDeleteStatement; +import com.alibaba.druid.sql.ast.statement.SQLExprTableSource; import com.alibaba.druid.sql.ast.statement.SQLTableSource; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSelectQueryBlock.Limit; import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlASTVisitor; @@ -39,7 +40,7 @@ public class MySqlDeleteStatement extends SQLDeleteStatement { private SQLTableSource using; private SQLOrderBy orderBy; private Limit limit; - private final List tableNames = new ArrayList(); + private final List tableSources = new ArrayList(); public boolean isLowPriority() { return lowPriority; @@ -78,22 +79,23 @@ public class MySqlDeleteStatement extends SQLDeleteStatement { } public SQLName getTableName() { - if (tableNames.size() == 0) { + if (tableSources.size() == 0) { return null; } - return tableNames.get(0); + return (SQLName) tableSources.get(0).getExpr(); } public void setTableName(SQLName tableName) { - if (tableNames.size() == 0) { - tableNames.add(tableName); + SQLExprTableSource tableSource = new SQLExprTableSource(tableName); + if (tableSources.size() == 0) { + tableSources.add(tableSource); } else { - tableNames.set(0, tableName); + tableSources.set(0, tableSource); } } - public List getTableNames() { - return tableNames; + public List getTableSources() { + return tableSources; } public void setFrom(SQLTableSource from) { @@ -131,7 +133,7 @@ public class MySqlDeleteStatement extends SQLDeleteStatement { protected void accept0(MySqlASTVisitor visitor) { if (visitor.visit(this)) { - acceptChild(visitor, getTableNames()); + acceptChild(visitor, getTableSources()); acceptChild(visitor, getWhere()); acceptChild(visitor, getFrom()); acceptChild(visitor, getUsing()); diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlStatementParser.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlStatementParser.java index 139312fc12..b7247225ce 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlStatementParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlStatementParser.java @@ -27,6 +27,7 @@ import com.alibaba.druid.sql.ast.expr.SQLLiteralExpr; import com.alibaba.druid.sql.ast.expr.SQLQueryExpr; import com.alibaba.druid.sql.ast.statement.SQLCreateTableStatement; import com.alibaba.druid.sql.ast.statement.SQLDropTableStatement; +import com.alibaba.druid.sql.ast.statement.SQLExprTableSource; import com.alibaba.druid.sql.ast.statement.SQLInsertStatement; import com.alibaba.druid.sql.ast.statement.SQLSelectStatement; import com.alibaba.druid.sql.ast.statement.SQLTableSource; @@ -108,7 +109,17 @@ public class MySqlStatementParser extends SQLStatementParser { } if (lexer.token() == Token.IDENTIFIER) { - exprParser.names(deleteStatement.getTableNames()); + for (;;) { + SQLName name = exprParser.name(); + deleteStatement.getTableSources().add(new SQLExprTableSource(name)); + + if (lexer.token() == Token.COMMA) { + lexer.nextToken(); + continue; + } + + break; + } if (lexer.token() == Token.FROM) { lexer.nextToken(); @@ -119,7 +130,17 @@ public class MySqlStatementParser extends SQLStatementParser { if (lexer.token() == Token.FROM) { lexer.nextToken(); } - exprParser.names(deleteStatement.getTableNames()); + for (;;) { + SQLName name = exprParser.name(); + deleteStatement.getTableSources().add(new SQLExprTableSource(name)); + + if (lexer.token() == Token.COMMA) { + lexer.nextToken(); + continue; + } + + break; + } } if (identifierEquals("USING")) { diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlOutputVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlOutputVisitor.java index 635045529c..b84a936387 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlOutputVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlOutputVisitor.java @@ -661,9 +661,9 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV if (x.getFrom() == null) { print("FROM "); - printAndAccept(x.getTableNames(), ", "); + printAndAccept(x.getTableSources(), ", "); } else { - printAndAccept(x.getTableNames(), ", "); + printAndAccept(x.getTableSources(), ", "); println(); print("FROM "); x.getFrom().accept(this); diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlSchemaStatVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlSchemaStatVisitor.java index 91fa856636..084fff2095 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlSchemaStatVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlSchemaStatVisitor.java @@ -2,9 +2,11 @@ package com.alibaba.druid.sql.dialect.mysql.visitor; import java.util.Map; +import com.alibaba.druid.sql.ast.SQLExpr; import com.alibaba.druid.sql.ast.SQLName; import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr; import com.alibaba.druid.sql.ast.statement.SQLDropTableStatement; +import com.alibaba.druid.sql.ast.statement.SQLExprTableSource; import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock; import com.alibaba.druid.sql.ast.statement.SQLSelectStatement; import com.alibaba.druid.sql.dialect.mysql.ast.MySqlKey; @@ -63,12 +65,14 @@ public class MySqlSchemaStatVisitor extends SchemaStatVisitor implements MySqlAS setAliasMap(); - if (x.getTableNames().size() == 1) { - String ident = ((SQLIdentifierExpr) x.getTableNames().get(0)).getName(); + if (x.getTableSources().size() == 1) { + SQLName tableName = (SQLName) x.getTableSources().get(0).getExpr(); + String ident = tableName.toString(); setCurrentTable(x, ident); } - for (SQLName tableName : x.getTableNames()) { + for (SQLExprTableSource tableSource : x.getTableSources()) { + SQLExpr tableName = tableSource.getExpr(); String ident = tableName.toString(); TableStat stat = getTableStat(ident); stat.incrementDeleteCount(); diff --git a/src/test/java/com/alibaba/druid/bvt/mapping/MappingVisitorTest.java b/src/test/java/com/alibaba/druid/bvt/mapping/MappingVisitorTest.java index 6504c90db1..3494e5709f 100644 --- a/src/test/java/com/alibaba/druid/bvt/mapping/MappingVisitorTest.java +++ b/src/test/java/com/alibaba/druid/bvt/mapping/MappingVisitorTest.java @@ -30,8 +30,15 @@ public class MappingVisitorTest extends TestCase { engine.explainToSelectSQL("select *")); Assert.assertEquals("SELECT serviceTag AS \"编号\", ip AS \"IP地址\"\nFROM device\nWHERE ip = '127.0.0.1'", engine.explainToSelectSQL("select 编号, IP地址 WHERE IP地址 = '127.0.0.1'")); + Assert.assertEquals("SELECT serviceTag AS \"编号\", ip AS \"IP地址\"\nFROM device\nWHERE ip = '127.0.0.1'", + engine.explainToSelectSQL("WHERE IP地址 = '127.0.0.1'")); } + + public void test_delete() throws Exception { + Assert.assertEquals("DELETE FROM device\nWHERE ip = '127.0.0.1'", + engine.explainToDeleteSQL("WHERE IP地址 = '127.0.0.1'")); + } public void test_1() throws Exception { engine.setMaxLimit(10);