diff --git a/pom.xml b/pom.xml
index 835d38ec8e..6ee6c20d51 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1,14 +1,8 @@
4.0.0
-
-
+
+
com.alibaba
druid
1.0.16-SNAPSHOT
@@ -38,18 +32,9 @@
-
+
wenshao
@@ -303,32 +288,32 @@
-
- mac-profile-oracle-jdk
-
- false
-
- ${java.home}/../lib/jconsole.jar
-
-
-
-
- com.alibaba
- jconsole
- 1.8.0
- system
- ${java.home}/../lib/jconsole.jar
-
+
+ mac-profile-oracle-jdk
+
+ false
+
+ ${java.home}/../lib/jconsole.jar
+
+
+
+
+ com.alibaba
+ jconsole
+ 1.8.0
+ system
+ ${java.home}/../lib/jconsole.jar
+
-
- com.alibaba
- tools
- 1.8.0
- system
- ${java.home}/../lib/tools.jar
-
-
-
+
+ com.alibaba
+ tools
+ 1.8.0
+ system
+ ${java.home}/../lib/tools.jar
+
+
+
@@ -469,7 +454,7 @@
11.2.0.3
provided
-
+
org.quartz-scheduler
quartz
@@ -478,14 +463,8 @@
true
-
+
junit
junit
@@ -571,7 +550,7 @@
1.b.52
test
-
+
com.taobao.tbdatasource
tbdatasource
@@ -584,7 +563,7 @@
-
+
org.javasimon
javasimon-spring
@@ -609,5 +588,19 @@
14.0.1
test
+
+
+ com.aliyun.odps
+ odps-sdk-udf
+ 0.17.3
+ provided
+ true
+
+
+ javax.validation
+ validation-api
+
+
+
diff --git a/src/main/java/com/alibaba/druid/sql/SQLUtils.java b/src/main/java/com/alibaba/druid/sql/SQLUtils.java
index 77fb7b7cfa..7ac6200c46 100644
--- a/src/main/java/com/alibaba/druid/sql/SQLUtils.java
+++ b/src/main/java/com/alibaba/druid/sql/SQLUtils.java
@@ -337,14 +337,15 @@ public class SQLUtils {
return new SQLASTOutputVisitor(out);
}
-
+
+ @Deprecated
public static SchemaStatVisitor createSchemaStatVisitor(List statementList, String dbType) {
+ return createSchemaStatVisitor(dbType);
+ }
+
+ public static SchemaStatVisitor createSchemaStatVisitor(String dbType) {
if (JdbcUtils.ORACLE.equals(dbType) || JdbcUtils.ALI_ORACLE.equals(dbType)) {
- if (statementList.size() == 1) {
- return new OracleSchemaStatVisitor();
- } else {
- return new OracleSchemaStatVisitor();
- }
+ return new OracleSchemaStatVisitor();
}
if (JdbcUtils.MYSQL.equals(dbType) || //
diff --git a/src/main/java/com/alibaba/druid/sql/dialect/odps/visitor/OdpsOutputVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/odps/visitor/OdpsOutputVisitor.java
index 7a8e90a7c6..37155f7e1d 100644
--- a/src/main/java/com/alibaba/druid/sql/dialect/odps/visitor/OdpsOutputVisitor.java
+++ b/src/main/java/com/alibaba/druid/sql/dialect/odps/visitor/OdpsOutputVisitor.java
@@ -153,6 +153,8 @@ public class OdpsOutputVisitor extends SQLASTOutputVisitor implements OdpsASTVis
}
if (x.getSelect() != null) {
+ println();
+ print("AS");
println();
x.getSelect().accept(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 a496454014..10f288566a 100644
--- a/src/main/java/com/alibaba/druid/sql/parser/SQLStatementParser.java
+++ b/src/main/java/com/alibaba/druid/sql/parser/SQLStatementParser.java
@@ -216,44 +216,91 @@ public class SQLStatementParser extends SQLParser {
}
if (lexer.token() == Token.DROP) {
+ List beforeComments = null;
+ if (lexer.isKeepComments() && lexer.hasComment()) {
+ beforeComments = lexer.readAndResetComments();
+ }
+
lexer.nextToken();
if (lexer.token() == Token.TABLE || identifierEquals("TEMPORARY")) {
SQLDropTableStatement stmt = parseDropTable(false);
+
+ if (beforeComments != null) {
+ stmt.addBeforeComment(beforeComments);
+ }
statementList.add(stmt);
continue;
} else if (lexer.token() == Token.USER) {
SQLStatement stmt = parseDropUser();
+ if (beforeComments != null) {
+ stmt.addBeforeComment(beforeComments);
+ }
+
statementList.add(stmt);
continue;
} else if (lexer.token() == Token.INDEX) {
SQLStatement stmt = parseDropIndex();
+ if (beforeComments != null) {
+ stmt.addBeforeComment(beforeComments);
+ }
+
statementList.add(stmt);
continue;
} else if (lexer.token() == Token.VIEW) {
SQLStatement stmt = parseDropView(false);
+
+ if (beforeComments != null) {
+ stmt.addBeforeComment(beforeComments);
+ }
+
statementList.add(stmt);
continue;
} else if (lexer.token() == Token.TRIGGER) {
SQLStatement stmt = parseDropTrigger(false);
+
+ if (beforeComments != null) {
+ stmt.addBeforeComment(beforeComments);
+ }
+
statementList.add(stmt);
continue;
} else if (lexer.token() == Token.DATABASE) {
SQLStatement stmt = parseDropDatabase(false);
+
+ if (beforeComments != null) {
+ stmt.addBeforeComment(beforeComments);
+ }
+
statementList.add(stmt);
continue;
} else if (lexer.token() == Token.FUNCTION) {
SQLStatement stmt = parseDropFunction(false);
+
+ if (beforeComments != null) {
+ stmt.addBeforeComment(beforeComments);
+ }
+
statementList.add(stmt);
continue;
} else if (lexer.token() == Token.TABLESPACE) {
SQLStatement stmt = parseDropTablespace(false);
+
+ if (beforeComments != null) {
+ stmt.addBeforeComment(beforeComments);
+ }
+
statementList.add(stmt);
continue;
} else if (lexer.token() == Token.PROCEDURE) {
SQLStatement stmt = parseDropProcedure(false);
+
+ if (beforeComments != null) {
+ stmt.addBeforeComment(beforeComments);
+ }
+
statementList.add(stmt);
continue;
} else {
@@ -1255,12 +1302,16 @@ public class SQLStatementParser extends SQLParser {
}
protected SQLDropTableSpaceStatement parseDropTablespace(boolean acceptDrop) {
+ SQLDropTableSpaceStatement stmt = new SQLDropTableSpaceStatement(getDbType());
+
+ if (lexer.isKeepComments() && lexer.hasComment()) {
+ stmt.addBeforeComment(lexer.readAndResetComments());
+ }
+
if (acceptDrop) {
accept(Token.DROP);
}
-
- SQLDropTableSpaceStatement stmt = new SQLDropTableSpaceStatement(getDbType());
-
+
accept(Token.TABLESPACE);
if (lexer.token() == Token.IF) {
diff --git a/src/main/java/com/alibaba/druid/stat/DruidStatService.java b/src/main/java/com/alibaba/druid/stat/DruidStatService.java
index 0d7da15f61..a475529c0e 100644
--- a/src/main/java/com/alibaba/druid/stat/DruidStatService.java
+++ b/src/main/java/com/alibaba/druid/stat/DruidStatService.java
@@ -317,9 +317,9 @@ public final class DruidStatService implements DruidStatServiceMBean {
List statementList = SQLUtils.parseStatements(sql, dbType);
if (!statementList.isEmpty()) {
- SQLStatement statemen = statementList.get(0);
- SchemaStatVisitor visitor = SQLUtils.createSchemaStatVisitor(statementList, dbType);
- statemen.accept(visitor);
+ SQLStatement sqlStmt = statementList.get(0);
+ SchemaStatVisitor visitor = SQLUtils.createSchemaStatVisitor(dbType);
+ sqlStmt.accept(visitor);
map.put("parsedTable", visitor.getTables().toString());
map.put("parsedFields", visitor.getColumns().toString());
map.put("parsedConditions", visitor.getConditions().toString());
diff --git a/src/main/java/com/alibaba/druid/support/opds/udf/ExportColumns.java b/src/main/java/com/alibaba/druid/support/opds/udf/ExportColumns.java
new file mode 100644
index 0000000000..6a59b3ce2a
--- /dev/null
+++ b/src/main/java/com/alibaba/druid/support/opds/udf/ExportColumns.java
@@ -0,0 +1,35 @@
+package com.alibaba.druid.support.opds.udf;
+
+import java.util.List;
+
+import com.alibaba.druid.sql.SQLUtils;
+import com.alibaba.druid.sql.ast.SQLStatement;
+import com.alibaba.druid.sql.visitor.SchemaStatVisitor;
+import com.alibaba.druid.stat.TableStat;
+import com.aliyun.odps.udf.UDF;
+
+public class ExportColumns extends UDF {
+ public String evaluate(String sql) {
+ return evaluate(sql, null);
+ }
+
+ public String evaluate(String sql, String dbType) {
+ List statementList = SQLUtils.parseStatements(sql, dbType);
+ SchemaStatVisitor visitor = SQLUtils.createSchemaStatVisitor(dbType);
+
+ for (SQLStatement stmt : statementList) {
+ stmt.accept(visitor);
+ }
+
+ StringBuffer buf = new StringBuffer();
+
+ for (TableStat.Column column : visitor.getColumns()) {
+ if (buf.length() != 0) {
+ buf.append(',');
+ }
+ buf.append(column.toString());
+ }
+
+ return buf.toString();
+ }
+}
diff --git a/src/main/java/com/alibaba/druid/support/opds/udf/ExportTables.java b/src/main/java/com/alibaba/druid/support/opds/udf/ExportTables.java
new file mode 100644
index 0000000000..1e751f7b11
--- /dev/null
+++ b/src/main/java/com/alibaba/druid/support/opds/udf/ExportTables.java
@@ -0,0 +1,38 @@
+package com.alibaba.druid.support.opds.udf;
+
+import java.util.List;
+import java.util.Map;
+
+import com.alibaba.druid.sql.SQLUtils;
+import com.alibaba.druid.sql.ast.SQLStatement;
+import com.alibaba.druid.sql.visitor.SchemaStatVisitor;
+import com.alibaba.druid.stat.TableStat;
+import com.aliyun.odps.udf.UDF;
+
+public class ExportTables extends UDF {
+ public String evaluate(String sql) {
+ return evaluate(sql, null);
+ }
+
+ public String evaluate(String sql, String dbType) {
+ List statementList = SQLUtils.parseStatements(sql, dbType);
+ SchemaStatVisitor visitor = SQLUtils.createSchemaStatVisitor(dbType);
+
+ for (SQLStatement stmt : statementList) {
+ stmt.accept(visitor);
+ }
+
+ StringBuffer buf = new StringBuffer();
+
+ for (Map.Entry entry : visitor.getTables().entrySet()) {
+ TableStat.Name name = entry.getKey();
+
+ if (buf.length() != 0) {
+ buf.append(',');
+ }
+ buf.append(name.toString());
+ }
+
+ return buf.toString();
+ }
+}
diff --git a/src/test/java/com/alibaba/druid/bvt/sql/odps/OdpsCreateTableTest2.java b/src/test/java/com/alibaba/druid/bvt/sql/odps/OdpsCreateTableTest2.java
index 8a71f46d3a..74100221be 100644
--- a/src/test/java/com/alibaba/druid/bvt/sql/odps/OdpsCreateTableTest2.java
+++ b/src/test/java/com/alibaba/druid/bvt/sql/odps/OdpsCreateTableTest2.java
@@ -18,6 +18,7 @@ public class OdpsCreateTableTest2 extends TestCase {
parser.match(Token.EOF);
String output = SQLUtils.toOdpsString(stmt);
Assert.assertEquals("CREATE TABLE sale_detail"
+ + "\nAS"
+ "\nSELECT *" //
+ "\nFROM dual", output);
}
diff --git a/src/test/java/com/alibaba/druid/bvt/sql/odps/OdpsFormatCommentTest23.java b/src/test/java/com/alibaba/druid/bvt/sql/odps/OdpsFormatCommentTest23.java
new file mode 100644
index 0000000000..2726865068
--- /dev/null
+++ b/src/test/java/com/alibaba/druid/bvt/sql/odps/OdpsFormatCommentTest23.java
@@ -0,0 +1,18 @@
+package com.alibaba.druid.bvt.sql.odps;
+
+import org.junit.Assert;
+
+import com.alibaba.druid.sql.SQLUtils;
+
+import junit.framework.TestCase;
+
+public class OdpsFormatCommentTest23 extends TestCase {
+ public void test_drop_table() throws Exception {
+ String sql = "-- xxx"
+ + "\n -- yyy"
+ + "\ndrop table if exists mytables;";
+ Assert.assertEquals("-- xxx"
+ + "\n-- yyy"
+ + "\nDROP TABLE IF EXISTS mytables;", SQLUtils.formatOdps(sql));
+ }
+}
diff --git a/src/test/java/com/alibaba/druid/bvt/sql/odps/OdpsFormatCommentTest24.java b/src/test/java/com/alibaba/druid/bvt/sql/odps/OdpsFormatCommentTest24.java
new file mode 100644
index 0000000000..0ffdbdfde9
--- /dev/null
+++ b/src/test/java/com/alibaba/druid/bvt/sql/odps/OdpsFormatCommentTest24.java
@@ -0,0 +1,18 @@
+package com.alibaba.druid.bvt.sql.odps;
+
+import org.junit.Assert;
+
+import com.alibaba.druid.sql.SQLUtils;
+
+import junit.framework.TestCase;
+
+public class OdpsFormatCommentTest24 extends TestCase {
+ public void test_drop_view() throws Exception {
+ String sql = "-- xxx"
+ + "\n -- yyy"
+ + "\ndrop view if exists mytables;";
+ Assert.assertEquals("-- xxx"
+ + "\n-- yyy"
+ + "\nDROP VIEW IF EXISTS mytables;", SQLUtils.formatOdps(sql));
+ }
+}
diff --git a/src/test/java/com/alibaba/druid/bvt/sql/odps/OdpsFormatCommentTest25.java b/src/test/java/com/alibaba/druid/bvt/sql/odps/OdpsFormatCommentTest25.java
new file mode 100644
index 0000000000..f72999a6e7
--- /dev/null
+++ b/src/test/java/com/alibaba/druid/bvt/sql/odps/OdpsFormatCommentTest25.java
@@ -0,0 +1,18 @@
+package com.alibaba.druid.bvt.sql.odps;
+
+import org.junit.Assert;
+
+import com.alibaba.druid.sql.SQLUtils;
+
+import junit.framework.TestCase;
+
+public class OdpsFormatCommentTest25 extends TestCase {
+ public void test_drop_function() throws Exception {
+ String sql = "-- xxx"
+ + "\n -- yyy"
+ + "\ndrop function if exists mytables;";
+ Assert.assertEquals("-- xxx"
+ + "\n-- yyy"
+ + "\nDROP FUNCTION IF EXISTS mytables;", SQLUtils.formatOdps(sql));
+ }
+}
diff --git a/src/test/java/com/alibaba/druid/bvt/sql/odps/OdpsFormatCommentTest26.java b/src/test/java/com/alibaba/druid/bvt/sql/odps/OdpsFormatCommentTest26.java
new file mode 100644
index 0000000000..edc3403fbd
--- /dev/null
+++ b/src/test/java/com/alibaba/druid/bvt/sql/odps/OdpsFormatCommentTest26.java
@@ -0,0 +1,17 @@
+package com.alibaba.druid.bvt.sql.odps;
+
+import org.junit.Assert;
+
+import com.alibaba.druid.sql.SQLUtils;
+
+import junit.framework.TestCase;
+
+public class OdpsFormatCommentTest26 extends TestCase {
+ public void test_drop_function() throws Exception {
+ String sql = "create table t as select * from dual;";
+ Assert.assertEquals("CREATE TABLE t"
+ + "\nAS"
+ + "\nSELECT *"
+ + "\nFROM dual;", SQLUtils.formatOdps(sql));
+ }
+}