diff --git a/src/main/java/com/alibaba/druid/mapping/MappingEngine.java b/src/main/java/com/alibaba/druid/mapping/MappingEngine.java index 4d4a1ac5b1..7211aa5bbd 100644 --- a/src/main/java/com/alibaba/druid/mapping/MappingEngine.java +++ b/src/main/java/com/alibaba/druid/mapping/MappingEngine.java @@ -31,6 +31,14 @@ public class MappingEngine { public MappingEngine(){ this(new MySqlMappingProvider()); } + + public Entity getFirstEntity() { + for (Map.Entry entry : entities.entrySet()) { + return entry.getValue(); + } + + return null; + } public DataSource getDataSource() { return dataSource; @@ -88,9 +96,9 @@ public class MappingEngine { return provider.explainToDeleteSQLObject(this, sql); } - public String explainToDeleteSQLObjectSQL(String sql) { + public String explainToDeleteSQL(String sql) { SQLDeleteStatement query = explainToDeleteSQLObject(sql); - + query.accept(this.createMappingVisitor()); return toSQL(query); diff --git a/src/main/java/com/alibaba/druid/mapping/spi/OracleMappingProvider.java b/src/main/java/com/alibaba/druid/mapping/spi/OracleMappingProvider.java index 8717f7ac6b..2e449545ad 100644 --- a/src/main/java/com/alibaba/druid/mapping/spi/OracleMappingProvider.java +++ b/src/main/java/com/alibaba/druid/mapping/spi/OracleMappingProvider.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.statement.SQLInsertStatement; import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock; import com.alibaba.druid.sql.ast.statement.SQLUpdateStatement; @@ -22,7 +24,7 @@ public class OracleMappingProvider implements MappingProvider { @Override public SQLASTOutputVisitor createOutputVisitor(MappingEngine engine, Appendable out) { - return new OracleOutputVisitor(out); + return new OracleOutputVisitor(out, false); } public SQLSelectQueryBlock explainToSelectSQLObject(MappingEngine engine, String sql) { @@ -34,20 +36,26 @@ public class OracleMappingProvider implements MappingProvider { public OracleDeleteStatement explainToDeleteSQLObject(MappingEngine engine, String sql) { OracleStatementParser parser = new OracleStatementParser(sql); - return parser.parseDeleteStatement(); + OracleDeleteStatement 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) { OracleStatementParser parser = new OracleStatementParser(sql); return parser.parseUpdateStatement(); } - - + public SQLInsertStatement explainToInsertSQLObject(MappingEngine engine, String sql) { OracleStatementParser parser = new OracleStatementParser(sql); return (SQLInsertStatement) parser.parseInsert(); } - + @Override public ExportParameterVisitor createExportParameterVisitor(List parameters) { return new OracleExportParameterVisitor(parameters); diff --git a/src/main/java/com/alibaba/druid/mapping/spi/OracleMappingVisitor.java b/src/main/java/com/alibaba/druid/mapping/spi/OracleMappingVisitor.java index 74ef2ab442..2dd8469997 100644 --- a/src/main/java/com/alibaba/druid/mapping/spi/OracleMappingVisitor.java +++ b/src/main/java/com/alibaba/druid/mapping/spi/OracleMappingVisitor.java @@ -11,6 +11,7 @@ import com.alibaba.druid.sql.ast.statement.SQLSelectItem; import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock; import com.alibaba.druid.sql.ast.statement.SQLSubqueryTableSource; import com.alibaba.druid.sql.ast.statement.SQLTableSource; +import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleDeleteStatement; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectQueryBlock; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleSelectTableReference; import com.alibaba.druid.sql.dialect.oracle.visitor.OracleASTVIsitorAdapter; @@ -85,4 +86,10 @@ public class OracleMappingVisitor extends OracleASTVIsitorAdapter implements Map public boolean visit(OracleSelectTableReference x) { return MappingVisitorUtils.visit(this, x); } + + @Override + public boolean visit(OracleDeleteStatement x) { + + return true; + } } diff --git a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLDeleteStatement.java b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLDeleteStatement.java index 13ad5b6ba6..03065caeaa 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLDeleteStatement.java +++ b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLDeleteStatement.java @@ -18,25 +18,38 @@ package com.alibaba.druid.sql.ast.statement; import com.alibaba.druid.sql.ast.SQLExpr; import com.alibaba.druid.sql.ast.SQLName; import com.alibaba.druid.sql.ast.SQLStatementImpl; +import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr; import com.alibaba.druid.sql.visitor.SQLASTVisitor; public class SQLDeleteStatement extends SQLStatementImpl { - private static final long serialVersionUID = 1L; - protected SQLName tableName; - protected SQLExpr where; - private String alias; + private static final long serialVersionUID = 1L; + protected SQLExprTableSource tableSource; + protected SQLExpr where; + private String alias; public SQLDeleteStatement(){ } + public SQLExprTableSource getTableSource() { + return tableSource; + } + + public void setTableSource(SQLExprTableSource tableSource) { + this.tableSource = tableSource; + } + public SQLName getTableName() { - return tableName; + return (SQLName) tableSource.getExpr(); } public void setTableName(SQLName tableName) { - this.tableName = tableName; + this.tableSource = new SQLExprTableSource(tableName); + } + + public void setTableName(String name) { + setTableName(new SQLIdentifierExpr(name)); } public SQLExpr getWhere() { @@ -55,19 +68,10 @@ public class SQLDeleteStatement extends SQLStatementImpl { this.alias = alias; } - public void output(StringBuffer buf) { - buf.append("DELETE FROM "); - this.tableName.output(buf); - if (this.where != null) { - buf.append(" WHERE "); - this.where.output(buf); - } - } - @Override protected void accept0(SQLASTVisitor visitor) { if (visitor.visit(this)) { - acceptChild(visitor, tableName); + acceptChild(visitor, tableSource); acceptChild(visitor, where); } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlSelectParser.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlSelectParser.java index 77b29ec445..dc78fd3fef 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlSelectParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlSelectParser.java @@ -50,108 +50,110 @@ public class MySqlSelectParser extends SQLSelectParser { return queryRest(select); } - accept(Token.SELECT); - MySqlSelectQueryBlock queryBlock = new MySqlSelectQueryBlock(); - if (lexer.token() == (Token.DISTINCT)) { - queryBlock.setDistionOption(SQLSetQuantifier.DISTINCT); + if (lexer.token() == Token.SELECT) { lexer.nextToken(); - } else if (identifierEquals("DISTINCTROW")) { - queryBlock.setDistionOption(SQLSetQuantifier.DISTINCTROW); - lexer.nextToken(); - } else if (lexer.token() == (Token.ALL)) { - queryBlock.setDistionOption(SQLSetQuantifier.ALL); - lexer.nextToken(); - } - if (identifierEquals("HIGH_PRIORITY")) { - queryBlock.setHignPriority(true); - lexer.nextToken(); - } - - if (identifierEquals("STRAIGHT_JOIN")) { - queryBlock.setStraightJoin(true); - lexer.nextToken(); - } - - if (identifierEquals("SQL_SMALL_RESULT")) { - queryBlock.setSmallResult(true); - lexer.nextToken(); - } - - if (identifierEquals("SQL_BIG_RESULT")) { - queryBlock.setBigResult(true); - lexer.nextToken(); - } - - if (identifierEquals("SQL_BUFFER_RESULT")) { - queryBlock.setBufferResult(true); - lexer.nextToken(); - } - - if (identifierEquals("SQL_CACHE")) { - queryBlock.setCache(true); - lexer.nextToken(); - } - - if (identifierEquals("SQL_NO_CACHE")) { - queryBlock.setCache(false); - lexer.nextToken(); - } - - if (identifierEquals("SQL_CALC_FOUND_ROWS")) { - queryBlock.setCalcFoundRows(true); - lexer.nextToken(); - } - - parseSelectList(queryBlock); - - if (lexer.token() == (Token.INTO)) { - lexer.nextToken(); - acceptIdentifier("OUTFILE"); - SQLExpr outFile = expr(); - queryBlock.setOutFile(outFile); - - if (identifierEquals("FIELDS") || identifierEquals("COLUMNS")) { + if (lexer.token() == (Token.DISTINCT)) { + queryBlock.setDistionOption(SQLSetQuantifier.DISTINCT); + lexer.nextToken(); + } else if (identifierEquals("DISTINCTROW")) { + queryBlock.setDistionOption(SQLSetQuantifier.DISTINCTROW); + lexer.nextToken(); + } else if (lexer.token() == (Token.ALL)) { + queryBlock.setDistionOption(SQLSetQuantifier.ALL); lexer.nextToken(); - - if (identifierEquals("TERMINATED")) { - lexer.nextToken(); - accept(Token.BY); - } - queryBlock.setOutFileColumnsTerminatedBy((SQLLiteralExpr) expr()); - - if (identifierEquals("OPTIONALLY")) { - lexer.nextToken(); - queryBlock.setOutFileColumnsEnclosedOptionally(true); - } - - if (identifierEquals("ENCLOSED")) { - lexer.nextToken(); - accept(Token.BY); - queryBlock.setOutFileColumnsEnclosedBy((SQLLiteralExpr) expr()); - } - - if (identifierEquals("ESCAPED")) { - lexer.nextToken(); - accept(Token.BY); - queryBlock.setOutFileColumnsEscaped((SQLLiteralExpr) expr()); - } } - if (identifierEquals("LINES")) { + if (identifierEquals("HIGH_PRIORITY")) { + queryBlock.setHignPriority(true); lexer.nextToken(); + } - if (identifierEquals("STARTING")) { + if (identifierEquals("STRAIGHT_JOIN")) { + queryBlock.setStraightJoin(true); + lexer.nextToken(); + } + + if (identifierEquals("SQL_SMALL_RESULT")) { + queryBlock.setSmallResult(true); + lexer.nextToken(); + } + + if (identifierEquals("SQL_BIG_RESULT")) { + queryBlock.setBigResult(true); + lexer.nextToken(); + } + + if (identifierEquals("SQL_BUFFER_RESULT")) { + queryBlock.setBufferResult(true); + lexer.nextToken(); + } + + if (identifierEquals("SQL_CACHE")) { + queryBlock.setCache(true); + lexer.nextToken(); + } + + if (identifierEquals("SQL_NO_CACHE")) { + queryBlock.setCache(false); + lexer.nextToken(); + } + + if (identifierEquals("SQL_CALC_FOUND_ROWS")) { + queryBlock.setCalcFoundRows(true); + lexer.nextToken(); + } + + parseSelectList(queryBlock); + + if (lexer.token() == (Token.INTO)) { + lexer.nextToken(); + acceptIdentifier("OUTFILE"); + SQLExpr outFile = expr(); + queryBlock.setOutFile(outFile); + + if (identifierEquals("FIELDS") || identifierEquals("COLUMNS")) { lexer.nextToken(); - accept(Token.BY); - queryBlock.setOutFileLinesStartingBy((SQLLiteralExpr) expr()); - } else { - identifierEquals("TERMINATED"); + + if (identifierEquals("TERMINATED")) { + lexer.nextToken(); + accept(Token.BY); + } + queryBlock.setOutFileColumnsTerminatedBy((SQLLiteralExpr) expr()); + + if (identifierEquals("OPTIONALLY")) { + lexer.nextToken(); + queryBlock.setOutFileColumnsEnclosedOptionally(true); + } + + if (identifierEquals("ENCLOSED")) { + lexer.nextToken(); + accept(Token.BY); + queryBlock.setOutFileColumnsEnclosedBy((SQLLiteralExpr) expr()); + } + + if (identifierEquals("ESCAPED")) { + lexer.nextToken(); + accept(Token.BY); + queryBlock.setOutFileColumnsEscaped((SQLLiteralExpr) expr()); + } + } + + if (identifierEquals("LINES")) { lexer.nextToken(); - accept(Token.BY); - queryBlock.setOutFileLinesTerminatedBy((SQLLiteralExpr) expr()); + + if (identifierEquals("STARTING")) { + lexer.nextToken(); + accept(Token.BY); + queryBlock.setOutFileLinesStartingBy((SQLLiteralExpr) expr()); + } else { + identifierEquals("TERMINATED"); + lexer.nextToken(); + accept(Token.BY); + queryBlock.setOutFileLinesTerminatedBy((SQLLiteralExpr) expr()); + } } } } 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 5937075e72..139312fc12 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 @@ -87,45 +87,47 @@ public class MySqlStatementParser extends SQLStatementParser { } public MySqlDeleteStatement parseDeleteStatement() throws ParserException { - accept(Token.DELETE); - MySqlDeleteStatement deleteStatement = new MySqlDeleteStatement(); - if (identifierEquals("LOW_PRIORITY")) { - deleteStatement.setLowPriority(true); + if (lexer.token() == Token.DELETE) { lexer.nextToken(); - } - if (identifierEquals("QUICK")) { - deleteStatement.setQuick(true); - lexer.nextToken(); - } - - if (identifierEquals("IGNORE")) { - deleteStatement.setIgnore(true); - lexer.nextToken(); - } - - if (lexer.token() == Token.IDENTIFIER) { - exprParser.names(deleteStatement.getTableNames()); - - if (lexer.token() == Token.FROM) { + if (identifierEquals("LOW_PRIORITY")) { + deleteStatement.setLowPriority(true); lexer.nextToken(); + } + + if (identifierEquals("QUICK")) { + deleteStatement.setQuick(true); + lexer.nextToken(); + } + + if (identifierEquals("IGNORE")) { + deleteStatement.setIgnore(true); + lexer.nextToken(); + } + + if (lexer.token() == Token.IDENTIFIER) { + exprParser.names(deleteStatement.getTableNames()); + + if (lexer.token() == Token.FROM) { + lexer.nextToken(); + SQLTableSource tableSource = createSQLSelectParser().parseTableSource(); + deleteStatement.setFrom(tableSource); + } + } else { + if (lexer.token() == Token.FROM) { + lexer.nextToken(); + } + exprParser.names(deleteStatement.getTableNames()); + } + + if (identifierEquals("USING")) { + lexer.nextToken(); + SQLTableSource tableSource = createSQLSelectParser().parseTableSource(); - deleteStatement.setFrom(tableSource); + deleteStatement.setUsing(tableSource); } - } else { - if (lexer.token() == Token.FROM) { - lexer.nextToken(); - } - exprParser.names(deleteStatement.getTableNames()); - } - - if (identifierEquals("USING")) { - lexer.nextToken(); - - SQLTableSource tableSource = createSQLSelectParser().parseTableSource(); - deleteStatement.setUsing(tableSource); } if (lexer.token() == (Token.WHERE)) { @@ -987,7 +989,7 @@ public class MySqlStatementParser extends SQLStatementParser { return stmt; } - + protected SQLDropTableStatement parseDropTable(boolean acceptDrop) { if (acceptDrop) { accept(Token.DROP); @@ -995,7 +997,7 @@ public class MySqlStatementParser extends SQLStatementParser { accept(Token.TABLE); MySqlDropTableStatement stmt = new MySqlDropTableStatement(); - + if (lexer.token() == Token.IF) { lexer.nextToken(); accept(Token.EXISTS); diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleDeleteStatement.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleDeleteStatement.java index e645dff506..8bc9fcff4b 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleDeleteStatement.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/stmt/OracleDeleteStatement.java @@ -56,7 +56,7 @@ public class OracleDeleteStatement extends SQLDeleteStatement { protected void accept0(OracleASTVisitor visitor) { if (visitor.visit(this)) { acceptChild(visitor, this.hints); - acceptChild(visitor, this.getTableName()); + acceptChild(visitor, this.tableSource); acceptChild(visitor, this.getWhere()); acceptChild(visitor, returning); } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleSelectParser.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleSelectParser.java index d04bb95128..d9998fb64b 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleSelectParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleSelectParser.java @@ -173,14 +173,14 @@ public class OracleSelectParser extends SQLSelectParser { lexer.nextToken(); this.createExprParser().exprList(forUpdate.getOf()); } - + if (lexer.token() == Token.NOWAIT) { lexer.nextToken(); forUpdate.setNotWait(true); } else if (lexer.token() == Token.WAIT) { lexer.nextToken(); forUpdate.setWait(this.createExprParser().primary()); - } else if (identifierEquals("SKIP")) { + } else if (identifierEquals("SKIP")) { lexer.nextToken(); acceptIdentifier("LOCKED"); forUpdate.setSkipLocked(true); @@ -239,26 +239,28 @@ public class OracleSelectParser extends SQLSelectParser { return queryRest(select); } - accept(Token.SELECT); - OracleSelectQueryBlock queryBlock = new OracleSelectQueryBlock(); - parseHints(queryBlock); + if (lexer.token() == Token.SELECT) { + lexer.nextToken(); - if (lexer.token() == (Token.DISTINCT)) { - queryBlock.setDistionOption(SQLSetQuantifier.DISTINCT); - lexer.nextToken(); - } else if (lexer.token() == (Token.UNIQUE)) { - queryBlock.setDistionOption(SQLSetQuantifier.UNIQUE); - lexer.nextToken(); - } else if (lexer.token() == (Token.ALL)) { - queryBlock.setDistionOption(SQLSetQuantifier.ALL); - lexer.nextToken(); + parseHints(queryBlock); + + if (lexer.token() == (Token.DISTINCT)) { + queryBlock.setDistionOption(SQLSetQuantifier.DISTINCT); + lexer.nextToken(); + } else if (lexer.token() == (Token.UNIQUE)) { + queryBlock.setDistionOption(SQLSetQuantifier.UNIQUE); + lexer.nextToken(); + } else if (lexer.token() == (Token.ALL)) { + queryBlock.setDistionOption(SQLSetQuantifier.ALL); + lexer.nextToken(); + } + + this.createExprParser().parseHints(queryBlock.getHints()); + + parseSelectList(queryBlock); } - this.createExprParser().parseHints(queryBlock.getHints()); - - parseSelectList(queryBlock); - parseInto(queryBlock); parseFrom(queryBlock); @@ -588,11 +590,11 @@ public class OracleSelectParser extends SQLSelectParser { SQLSelectGroupByClause groupBy = new SQLSelectGroupByClause(); groupBy.setHaving(this.createExprParser().expr()); - + if (lexer.token() == (Token.GROUP)) { lexer.nextToken(); accept(Token.BY); - + for (;;) { if (identifierEquals("GROUPING")) { GroupingSetExpr groupingSet = new GroupingSetExpr(); @@ -613,16 +615,16 @@ public class OracleSelectParser extends SQLSelectParser { lexer.nextToken(); } } - + queryBlock.setGroupBy(groupBy); } } - + protected String as() throws ParserException { if (lexer.token() == Token.CONNECT) { return null; } - + return super.as(); } @@ -713,13 +715,13 @@ public class OracleSelectParser extends SQLSelectParser { parseTableSourceQueryTableExpr(tableReference); parsePivot(tableReference); } - + return parseTableSourceRest(tableReference); } private void parseTableSourceQueryTableExpr(OracleSelectTableReference tableReference) { tableReference.setExpr(this.createExprParser().expr()); - + { FlashbackQueryClause clause = flashback(); tableReference.setFlashback(clause); @@ -825,7 +827,6 @@ public class OracleSelectParser extends SQLSelectParser { if (lexer.token() == Token.OF) { lexer.nextToken(); - if (identifierEquals("SCN")) { AsOfFlashbackQueryClause clause = new AsOfFlashbackQueryClause(); clause.setType(AsOfFlashbackQueryClause.Type.SCN); @@ -839,14 +840,14 @@ public class OracleSelectParser extends SQLSelectParser { AsOfSnapshotClause clause = new AsOfSnapshotClause(); clause.setExpr(this.expr()); accept(Token.RPAREN); - + return clause; } else { AsOfFlashbackQueryClause clause = new AsOfFlashbackQueryClause(); accept(Token.TIMESTAMP); clause.setType(AsOfFlashbackQueryClause.Type.TIMESTAMP); clause.setExpr(createExprParser().expr()); - + return clause; } @@ -869,7 +870,7 @@ public class OracleSelectParser extends SQLSelectParser { tableSource.setAlias(as()); } } - + if (lexer.token() == Token.HINT) { this.createExprParser().parseHints(tableSource.getHints()); } @@ -878,7 +879,7 @@ public class OracleSelectParser extends SQLSelectParser { if (lexer.token() == Token.LEFT) { lexer.nextToken(); - if (lexer.token() == Token.OUTER) { + if (lexer.token() == Token.OUTER) { lexer.nextToken(); } accept(Token.JOIN); @@ -887,16 +888,16 @@ public class OracleSelectParser extends SQLSelectParser { if (lexer.token() == Token.RIGHT) { lexer.nextToken(); - if (lexer.token() == Token.OUTER) { + if (lexer.token() == Token.OUTER) { lexer.nextToken(); } accept(Token.JOIN); joinType = OracleSelectJoin.JoinType.RIGHT_OUTER_JOIN; } - if (lexer.token() == Token.FULL) { + if (lexer.token() == Token.FULL) { lexer.nextToken(); - if (lexer.token() == Token.OUTER) { + if (lexer.token() == Token.OUTER) { lexer.nextToken(); } accept(Token.JOIN); @@ -934,7 +935,7 @@ public class OracleSelectParser extends SQLSelectParser { this.createExprParser().exprList(join.getUsing()); accept(Token.RPAREN); } - + return parseTableSourceRest(join); } @@ -1082,7 +1083,7 @@ public class OracleSelectParser extends SQLSelectParser { tableSource.setPivot(unPivot); } } - + protected void parseInto(OracleSelectQueryBlock x) { if (lexer.token() == Token.INTO) { lexer.nextToken(); diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleStatementParser.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleStatementParser.java index f699fd59f7..66f5fb242f 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleStatementParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleStatementParser.java @@ -1415,31 +1415,33 @@ public class OracleStatementParser extends SQLStatementParser { } public OracleDeleteStatement parseDeleteStatement() throws ParserException { - accept(Token.DELETE); - OracleDeleteStatement deleteStatement = new OracleDeleteStatement(); - this.createExprParser().parseHints(deleteStatement.getHints()); - - if (lexer.token() == (Token.FROM)) { + if (lexer.token() == Token.DELETE) { lexer.nextToken(); + + this.createExprParser().parseHints(deleteStatement.getHints()); + + if (lexer.token() == (Token.FROM)) { + lexer.nextToken(); + } + + if (identifierEquals("ONLY")) { + lexer.nextToken(); + accept(Token.LPAREN); + + SQLName tableName = exprParser.name(); + deleteStatement.setTableName(tableName); + + accept(Token.RPAREN); + } else { + SQLName tableName = exprParser.name(); + deleteStatement.setTableName(tableName); + } + + deleteStatement.setAlias(as()); } - if (identifierEquals("ONLY")) { - lexer.nextToken(); - accept(Token.LPAREN); - - SQLName tableName = exprParser.name(); - deleteStatement.setTableName(tableName); - - accept(Token.RPAREN); - } else { - SQLName tableName = exprParser.name(); - deleteStatement.setTableName(tableName); - } - - deleteStatement.setAlias(as()); - if (lexer.token() == (Token.WHERE)) { lexer.nextToken(); deleteStatement.setWhere(this.exprParser.expr()); diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/visitor/OracleOutputVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/visitor/OracleOutputVisitor.java index f238ab4e5c..0ed82e5548 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/oracle/visitor/OracleOutputVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/visitor/OracleOutputVisitor.java @@ -165,11 +165,26 @@ import com.alibaba.druid.sql.visitor.SQLASTOutputVisitor; public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleASTVisitor { + private final boolean printPostSemi; + public OracleOutputVisitor(Appendable appender){ + this(appender, true); + } + + public OracleOutputVisitor(Appendable appender, boolean printPostSemi){ super(appender); + this.printPostSemi = printPostSemi; + } + + public boolean isPrintPostSemi() { + return printPostSemi; } public void postVisit(SQLObject x) { + if (!printPostSemi) { + return; + } + if (x instanceof SQLStatement) { if (x instanceof OraclePLSQLCommitStatement) { return; @@ -265,20 +280,22 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS } public boolean visit(OracleDeleteStatement x) { - print("DELETE "); - printHints(x.getHints()); + if (x.getTableName() != null) { + print("DELETE "); + printHints(x.getHints()); - print("FROM "); - if (x.isOnly()) { - print("ONLY ("); - x.getTableName().accept(this); - print(")"); - } else { - x.getTableName().accept(this); + print("FROM "); + if (x.isOnly()) { + print("ONLY ("); + x.getTableName().accept(this); + print(")"); + } else { + x.getTableName().accept(this); + } + + printAlias(x.getAlias()); } - printAlias(x.getAlias()); - if (x.getWhere() != null) { println(); print("WHERE "); @@ -2633,15 +2650,15 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS print(" WRITE"); if (x.getWait() != null) { if (x.getWait().booleanValue()) { - print(" WAIT"); + print(" WAIT"); } else { print(" NOWAIT"); } } - + if (x.getImmediate() != null) { if (x.getImmediate().booleanValue()) { - print(" IMMEDIATE"); + print(" IMMEDIATE"); } else { print(" BATCH"); } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/postgresql/ast/stmt/PGDeleteStatement.java b/src/main/java/com/alibaba/druid/sql/dialect/postgresql/ast/stmt/PGDeleteStatement.java index 4c552aaaa1..e0f805504c 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/postgresql/ast/stmt/PGDeleteStatement.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/postgresql/ast/stmt/PGDeleteStatement.java @@ -66,7 +66,7 @@ public class PGDeleteStatement extends SQLDeleteStatement implements PGSQLStatem public void accept0(PGASTVisitor visitor) { if (visitor.visit(this)) { acceptChild(visitor, with); - acceptChild(visitor, tableName); + acceptChild(visitor, tableSource); acceptChild(visitor, using); acceptChild(visitor, where); } diff --git a/src/test/java/com/alibaba/druid/bvt/mapping/MappingVisitorOracleTest.java b/src/test/java/com/alibaba/druid/bvt/mapping/MappingVisitorOracleTest.java new file mode 100644 index 0000000000..1c5f563dcb --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/mapping/MappingVisitorOracleTest.java @@ -0,0 +1,45 @@ +package com.alibaba.druid.bvt.mapping; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.druid.mapping.Entity; +import com.alibaba.druid.mapping.MappingEngine; +import com.alibaba.druid.mapping.Property; +import com.alibaba.druid.mapping.spi.OracleMappingProvider; + +public class MappingVisitorOracleTest extends TestCase { + + MappingEngine engine = new MappingEngine(new OracleMappingProvider()); + + protected void setUp() throws Exception { + + Entity entity = new Entity(); + entity.setName("设备"); + entity.setDescription("Device"); + entity.setTableName("device"); + + entity.addProperty(new Property("编号", "", "serviceTag")); + entity.addProperty(new Property("IP地址", "", "ip")); + + engine.addEntity(entity); + } + + public void test_0() throws Exception { + + Assert.assertEquals("SELECT serviceTag AS \"编号\", ip AS \"IP地址\"\nFROM device", + 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'")); + } + +}