diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleUpdateParser.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleUpdateParser.java index 3e6e89da54..7bb663064a 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleUpdateParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleUpdateParser.java @@ -103,9 +103,7 @@ public class OracleUpdateParser extends SQLStatementParser { } private void parseHints(OracleUpdateStatement update) { - if (lexer.token() == Token.HINT) { - throw new ParserException("TODO"); - } + this.exprParser.parseHints(update.getHints()); } private void parseWhere(OracleUpdateStatement update) { 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 f6ab1876ee..80fa646599 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 @@ -277,7 +277,11 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS public boolean visit(OracleDeleteStatement x) { if (x.getTableName() != null) { print("DELETE "); - printHints(x.getHints()); + + if (x.getHints().size() > 0) { + printAndAccept(x.getHints(), ", "); + print(' '); + } print("FROM "); if (x.isOnly()) { @@ -753,7 +757,11 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS public boolean visit(OracleUpdateStatement x) { print("UPDATE "); - printHints(x.getHints()); + + if (x.getHints().size() > 0) { + printAndAccept(x.getHints(), ", "); + print(' '); + } if (x.isOnly()) { print("ONLY ("); @@ -1485,7 +1493,48 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS @Override public boolean visit(OracleInsertStatement x) { - visit((SQLInsertStatement) x); + //visit((SQLInsertStatement) x); + + print("INSERT "); + + if (x.getHints().size() > 0) { + printAndAccept(x.getHints(), ", "); + print(' '); + } + + print("INTO "); + + x.getTableSource().accept(this); + + if (x.getColumns().size() > 0) { + incrementIndent(); + println(); + print("("); + for (int i = 0, size = x.getColumns().size(); i < size; ++i) { + if (i != 0) { + if (i % 5 == 0) { + println(); + } + print(", "); + } + x.getColumns().get(i).accept(this); + } + print(")"); + decrementIndent(); + } + + if (x.getValues() != null) { + println(); + print("VALUES"); + println(); + x.getValues().accept(this); + } else { + if (x.getQuery() != null) { + println(); + x.getQuery().setParent(x); + x.getQuery().accept(this); + } + } if (x.getReturning() != null) { println(); diff --git a/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlSelectTest_19.java b/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlSelectTest_19.java index b729e0c5d4..d5874734b5 100644 --- a/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlSelectTest_19.java +++ b/src/test/java/com/alibaba/druid/bvt/sql/mysql/MySqlSelectTest_19.java @@ -23,8 +23,6 @@ import com.alibaba.druid.sql.MysqlTest; import com.alibaba.druid.sql.ast.SQLStatement; import com.alibaba.druid.sql.dialect.mysql.parser.MySqlStatementParser; import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlSchemaStatVisitor; -import com.alibaba.druid.stat.TableStat; -import com.alibaba.druid.stat.TableStat.Column; public class MySqlSelectTest_19 extends MysqlTest { diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleHintTest.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleHintTest.java index 9007a30bb5..37e13706e5 100644 --- a/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleHintTest.java +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleHintTest.java @@ -3,12 +3,14 @@ package com.alibaba.druid.bvt.sql.oracle; import java.util.List; import com.alibaba.druid.sql.PagerUtils; +import com.alibaba.druid.sql.SQLUtils; import com.alibaba.druid.sql.ast.SQLStatement; import com.alibaba.druid.sql.dialect.oracle.parser.OracleStatementParser; import com.alibaba.druid.sql.dialect.oracle.visitor.OracleOutputVisitor; import com.alibaba.druid.util.JdbcUtils; import org.junit.Assert; + import junit.framework.TestCase; public class OracleHintTest extends TestCase { @@ -33,4 +35,39 @@ public class OracleHintTest extends TestCase { String countSQL = PagerUtils.count(sql, JdbcUtils.ORACLE); Assert.assertEquals("SELECT /*+leading(e) index(e ORD_ORDER_ITEM_GS_BS_DI_IND)*/ DISTINCT COUNT(*)\nFROM ord_order_item e\nWHERE e.F1 = DATE '2011-10-01'", countSQL); } + + public void test_hint3() throws Exception { + String sql = "SELECT /*+index(a MTN_SMS_LOG_PK)*/ * from MTN_SMS_LOG a"; + String formattedSql = SQLUtils.formatOracle(sql); + Assert.assertEquals("SELECT /*+index(a MTN_SMS_LOG_PK)*/ *" + "\nFROM MTN_SMS_LOG a", formattedSql); + } + + public void test_hint4() throws Exception { + String sql = "UPDATE /*+index(a MTN_SMS_LOG_PK)*/  MTN_SMS_LOG  a SET GMT_MODIFIED = sysdate WHERE id=1"; + String formattedSql = SQLUtils.formatOracle(sql); + Assert.assertEquals("UPDATE /*+index(a MTN_SMS_LOG_PK)*/ MTN_SMS_LOG a" + + "\nSET GMT_MODIFIED = SYSDATE" + + "\nWHERE id = 1", formattedSql); + } + + public void test_hint5() throws Exception { + String sql = "SELECT /*+index(clk) use_nl(clk) */ distinct log.id log_id from t"; + String formattedSql = SQLUtils.formatOracle(sql); + Assert.assertEquals("SELECT /*+index(clk) use_nl(clk) */ DISTINCT log.id AS log_id" + "\nFROM t", formattedSql); + } + + public void test_hint6() throws Exception { + String sql = "insert /*+APPEND*/ into emp_new select a.no, sysdate, a.name, b.service_duration from emp a, work b where a.no=b.no"; + String formattedSql = SQLUtils.formatOracle(sql); + Assert.assertEquals("INSERT /*+APPEND*/ INTO emp_new" + "\nSELECT a.no, SYSDATE, a.name, b.service_duration" + + "\nFROM emp a, work b" + "\nWHERE a.no = b.no", formattedSql); + } + + public void test_hint7() throws Exception { + String sql = "delete /*+PARALLEL(semp, 5) */ from semp"; + String formattedSql = SQLUtils.formatOracle(sql); + Assert.assertEquals("DELETE /*+PARALLEL(semp, 5) */ FROM semp", formattedSql); + } + + }