From 46062863f2fd0063488246dcece45ceeec0aba58 Mon Sep 17 00:00:00 2001 From: "shaojin.wensj" Date: Wed, 16 Jan 2019 10:28:05 +0800 Subject: [PATCH] bug fixed for mysql parser & update pom version --- druid-spring-boot-starter/pom.xml | 4 +- pom.xml | 4 +- .../java/com/alibaba/druid/sql/SQLUtils.java | 18 +++ .../alibaba/druid/sql/ast/SQLStatement.java | 3 + .../sql/ast/statement/SQLInsertStatement.java | 15 ++- .../MySqlShowProcessListStatement.java | 16 ++- .../mysql/parser/MySqlStatementParser.java | 12 +- .../mysql/visitor/MySqlOutputVisitor.java | 8 ++ .../sql/visitor/SQLASTOutputVisitor.java | 8 ++ .../com/alibaba/druid/util/MySqlUtils.java | 16 +-- .../druid/bvt/pool/DruidDataSourceTest4.java | 1 - .../druid/bvt/sql/cobar/DALParserTest.java | 2 +- .../createTable/MySqlCreateTableTest134.java | 4 +- .../sql/mysql/insert/MySqlInsertTest_17.java | 57 +++++--- .../sql/mysql/insert/MySqlInsertTest_43.java | 125 ++++++++++++++++++ .../select/MySqlSelectTest_ads_keywords.java | 59 +++++++++ .../PG_getCreateTableScriptTest.java | 5 + 17 files changed, 317 insertions(+), 40 deletions(-) create mode 100644 src/test/java/com/alibaba/druid/bvt/sql/mysql/insert/MySqlInsertTest_43.java create mode 100644 src/test/java/com/alibaba/druid/bvt/sql/mysql/select/MySqlSelectTest_ads_keywords.java diff --git a/druid-spring-boot-starter/pom.xml b/druid-spring-boot-starter/pom.xml index e47427e730..fda5a235b7 100644 --- a/druid-spring-boot-starter/pom.xml +++ b/druid-spring-boot-starter/pom.xml @@ -4,14 +4,14 @@ 4.0.0 com.alibaba druid-spring-boot-starter - 1.1.10-SNAPSHOT + 1.1.12 jar druid-spring-boot-starter Spring Boot with Druid support,help you simplify Druid config in Spring Boot. https://github.com/alibaba/druid - 1.1.9 + 1.1.10 1.5.12.RELEASE diff --git a/pom.xml b/pom.xml index 4f1ac81cec..27cb5d6d45 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.alibaba druid - 1.1.12-preview_1 + 1.1.13-preview_3 jar druid @@ -602,7 +602,7 @@ org.apache.commons commons-dbcp2 - 2.1.1 + 2.5.0 test diff --git a/src/main/java/com/alibaba/druid/sql/SQLUtils.java b/src/main/java/com/alibaba/druid/sql/SQLUtils.java index b5b1fc0568..acbded2c43 100644 --- a/src/main/java/com/alibaba/druid/sql/SQLUtils.java +++ b/src/main/java/com/alibaba/druid/sql/SQLUtils.java @@ -477,6 +477,24 @@ public class SQLUtils { return stmtList; } + public static SQLStatement parseSingleStatement(String sql, String dbType, SQLParserFeature... features) { + SQLStatementParser parser = SQLParserUtils.createSQLStatementParser(sql, dbType, features); + List stmtList = parser.parseStatementList(); + + if (stmtList.size() > 1) { + throw new ParserException(" Mutil-Statment be found."); + } + + if (parser.getLexer().token() != Token.EOF) { + throw new ParserException("syntax error. " + sql); + } + return stmtList.get(0); + } + + public static SQLStatement parseSingleMysqlStatement(String sql) { + return parseSingleStatement(sql, JdbcConstants.MYSQL); + } + /** * @author owenludong.lud * @param columnName diff --git a/src/main/java/com/alibaba/druid/sql/ast/SQLStatement.java b/src/main/java/com/alibaba/druid/sql/ast/SQLStatement.java index 740a6388e5..63b5742058 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/SQLStatement.java +++ b/src/main/java/com/alibaba/druid/sql/ast/SQLStatement.java @@ -24,4 +24,7 @@ public interface SQLStatement extends SQLObject { SQLStatement clone(); List getChildren(); String toLowerCaseString(); + + List getHeadHintsDirect(); + void setHeadHints(List headHints); } diff --git a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLInsertStatement.java b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLInsertStatement.java index 842d2dfab5..e275e1f750 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLInsertStatement.java +++ b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLInsertStatement.java @@ -19,10 +19,7 @@ import java.util.ArrayList; import java.util.List; import com.alibaba.druid.sql.SQLUtils; -import com.alibaba.druid.sql.ast.SQLExpr; -import com.alibaba.druid.sql.ast.SQLObject; -import com.alibaba.druid.sql.ast.SQLObjectImpl; -import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.ast.*; import com.alibaba.druid.sql.visitor.SQLASTVisitor; public class SQLInsertStatement extends SQLInsertInto implements SQLStatement { @@ -34,6 +31,8 @@ public class SQLInsertStatement extends SQLInsertInto implements SQLStatement { private boolean afterSemi; + protected List headHints; + public SQLInsertStatement(){ } @@ -198,4 +197,12 @@ public class SQLInsertStatement extends SQLInsertInto implements SQLStatement { public String toLowerCaseString() { return SQLUtils.toSQLString(this, dbType, SQLUtils.DEFAULT_LCASE_FORMAT_OPTION); } + + public List getHeadHintsDirect() { + return headHints; + } + + public void setHeadHints(List headHints) { + this.headHints = headHints; + } } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/statement/MySqlShowProcessListStatement.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/statement/MySqlShowProcessListStatement.java index c14c2444a5..50f39732f8 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/statement/MySqlShowProcessListStatement.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/ast/statement/MySqlShowProcessListStatement.java @@ -15,14 +15,18 @@ */ package com.alibaba.druid.sql.dialect.mysql.ast.statement; +import com.alibaba.druid.sql.ast.SQLExpr; import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlASTVisitor; public class MySqlShowProcessListStatement extends MySqlStatementImpl implements MySqlShowStatement { private boolean full = false; + private SQLExpr where; public void accept0(MySqlASTVisitor visitor) { - visitor.visit(this); + if (visitor.visit(this)) { + acceptChild(visitor, where); + } visitor.endVisit(this); } @@ -34,4 +38,14 @@ public class MySqlShowProcessListStatement extends MySqlStatementImpl implements this.full = full; } + public SQLExpr getWhere() { + return where; + } + + public void setWhere(SQLExpr x) { + if (x != null) { + x.setParent(this); + } + this.where = x; + } } 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 50afefc6b2..bdb048595d 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 @@ -934,12 +934,12 @@ public class MySqlStatementParser extends SQLStatementParser { } if (tddlHints) { - SQLStatementImpl stmt = (SQLStatementImpl)this.parseStatement(); + SQLStatement stmt = this.parseStatement(); stmt.setHeadHints(hints); statementList.add(stmt); return true; } else if (accept) { - SQLStatementImpl stmt = (SQLStatementImpl) this.parseStatement(); + SQLStatement stmt = this.parseStatement(); stmt.setHeadHints(hints); statementList.add(stmt); return true; @@ -1712,6 +1712,14 @@ public class MySqlStatementParser extends SQLStatementParser { if (lexer.identifierEquals("PROCESSLIST")) { lexer.nextToken(); MySqlShowProcessListStatement stmt = new MySqlShowProcessListStatement(); + + if (lexer.token() == Token.WHERE) { + lexer.nextToken(); + stmt.setWhere( + this.exprParser.expr() + ); + } + return stmt; } 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 7c9bf58ae4..302c639567 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 @@ -888,6 +888,14 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV @Override public boolean visit(MySqlInsertStatement x) { + List headHints = x.getHeadHintsDirect(); + if (headHints != null) { + for (SQLCommentHint hint : headHints) { + hint.accept(this); + println(); + } + } + print0(ucase ? "INSERT " : "insert "); if (x.isLowPriority()) { 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 77ced32a4e..05cc4645d7 100644 --- a/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java @@ -2548,6 +2548,14 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet } public boolean visit(SQLInsertStatement x) { + List headHints = x.getHeadHintsDirect(); + if (headHints != null) { + for (SQLCommentHint hint : headHints) { + hint.accept(this); + println(); + } + } + if (x.isUpsert()) { print0(ucase ? "UPSERT INTO " : "upsert into "); } else { diff --git a/src/main/java/com/alibaba/druid/util/MySqlUtils.java b/src/main/java/com/alibaba/druid/util/MySqlUtils.java index 0a15be4c10..8af453cf5a 100644 --- a/src/main/java/com/alibaba/druid/util/MySqlUtils.java +++ b/src/main/java/com/alibaba/druid/util/MySqlUtils.java @@ -349,14 +349,14 @@ public class MySqlUtils { return SQLUtils.toSQLString(stmtList, JdbcConstants.MYSQL); } - private static Class class_connectionImpl = null; - private static boolean class_connectionImpl_Error = false; - private static Method method_getIO = null; - private static boolean method_getIO_error = false; - private static Class class_MysqlIO = null; - private static boolean class_MysqlIO_Error = false; - private static Method method_getLastPacketReceivedTimeMs = null; - private static boolean method_getLastPacketReceivedTimeMs_error = false; + private static transient Class class_connectionImpl = null; + private static transient boolean class_connectionImpl_Error = false; + private static transient Method method_getIO = null; + private static transient boolean method_getIO_error = false; + private static transient Class class_MysqlIO = null; + private static transient boolean class_MysqlIO_Error = false; + private static transient Method method_getLastPacketReceivedTimeMs = null; + private static transient boolean method_getLastPacketReceivedTimeMs_error = false; public static long getLastPacketReceivedTimeMs(Connection conn) throws SQLException { if (class_connectionImpl == null && !class_connectionImpl_Error) { diff --git a/src/test/java/com/alibaba/druid/bvt/pool/DruidDataSourceTest4.java b/src/test/java/com/alibaba/druid/bvt/pool/DruidDataSourceTest4.java index 1cd1e85ebf..6cf507a5b7 100644 --- a/src/test/java/com/alibaba/druid/bvt/pool/DruidDataSourceTest4.java +++ b/src/test/java/com/alibaba/druid/bvt/pool/DruidDataSourceTest4.java @@ -20,7 +20,6 @@ public class DruidDataSourceTest4 extends TestCase { dataSource.setUrl("jdbc:mock:xxx"); dataSource.setTestOnBorrow(false); dataSource.setInitialSize(1); - } protected void tearDown() throws Exception { diff --git a/src/test/java/com/alibaba/druid/bvt/sql/cobar/DALParserTest.java b/src/test/java/com/alibaba/druid/bvt/sql/cobar/DALParserTest.java index 7aec461778..6143d306f8 100755 --- a/src/test/java/com/alibaba/druid/bvt/sql/cobar/DALParserTest.java +++ b/src/test/java/com/alibaba/druid/bvt/sql/cobar/DALParserTest.java @@ -853,7 +853,7 @@ public class DALParserTest extends TestCase { Assert.assertEquals("SHOW FULL PROCESSLIST", output); } - + public void test_show_profiles() throws Exception { String sql = "SHOW profiles"; MySqlStatementParser parser = new MySqlStatementParser(sql); diff --git a/src/test/java/com/alibaba/druid/bvt/sql/mysql/createTable/MySqlCreateTableTest134.java b/src/test/java/com/alibaba/druid/bvt/sql/mysql/createTable/MySqlCreateTableTest134.java index eeba14faba..259db6f755 100644 --- a/src/test/java/com/alibaba/druid/bvt/sql/mysql/createTable/MySqlCreateTableTest134.java +++ b/src/test/java/com/alibaba/druid/bvt/sql/mysql/createTable/MySqlCreateTableTest134.java @@ -27,7 +27,7 @@ public class MySqlCreateTableTest134 extends MysqlTest { "\tid int NOT NULL PRIMARY KEY AUTO_INCREMENT,\n" + "\tname char(40),\n" + "\tSimpleDate date,\n" + - "\tSimpleDate_dayofweek tinyint(4) GENERATED ALWAYS AS (dayofweek(SimpleDate)),\n" + + "\tSimpleDate_dayofweek tinyint(4) GENERATED ALWAYS AS (dayofweek(SimpleDate)) VIRTUAL,\n" + "\tKEY SimpleDate_dayofweek (SimpleDate_dayofweek)\n" + ");", stmt.toString()); @@ -35,7 +35,7 @@ public class MySqlCreateTableTest134 extends MysqlTest { "\tid int not null primary key auto_increment,\n" + "\tname char(40),\n" + "\tSimpleDate date,\n" + - "\tSimpleDate_dayofweek tinyint(4) generated always as (dayofweek(SimpleDate)),\n" + + "\tSimpleDate_dayofweek tinyint(4) generated always as (dayofweek(SimpleDate)) virtual,\n" + "\tkey SimpleDate_dayofweek (SimpleDate_dayofweek)\n" + ");", stmt.toLowerCaseString()); diff --git a/src/test/java/com/alibaba/druid/bvt/sql/mysql/insert/MySqlInsertTest_17.java b/src/test/java/com/alibaba/druid/bvt/sql/mysql/insert/MySqlInsertTest_17.java index 0ba2dead84..069949ae47 100644 --- a/src/test/java/com/alibaba/druid/bvt/sql/mysql/insert/MySqlInsertTest_17.java +++ b/src/test/java/com/alibaba/druid/bvt/sql/mysql/insert/MySqlInsertTest_17.java @@ -12,7 +12,8 @@ import java.util.List; public class MySqlInsertTest_17 extends MysqlTest { public void test_insert_rollback_on_fail() throws Exception { - String sql = "INSERT INTO dashboard_crowd_analysis(cname,cvalue,orders,users,dt,tagid)\n" + String sql = "/*+engine=MPP, mppNativeInsertFromSelect=true*/\n" + + "INSERT INTO dashboard_crowd_analysis(cname,cvalue,orders,users,dt,tagid)\n" + "SELECT x.cname as cname,\n" + " x.cvalue as cvalue,\n" + " x.orders as orders,\n" + " x.users as users,\n" + " 20171211 as dt,\n" + " 91 as tagid\n" + "FROM (WITH h AS\n" + " (SELECT a.userid,\n" + " a.col_1,\n" @@ -40,22 +41,44 @@ public class MySqlInsertTest_17 extends MysqlTest { MySqlInsertStatement insertStmt = (MySqlInsertStatement) stmt; // System.out.println(SQLUtils.toMySqlString(insertStmt)); - String formatSql = "INSERT INTO dashboard_crowd_analysis (cname, cvalue, orders, users, dt\n" + "\t, tagid)\n" - + "SELECT x.cname AS cname, x.cvalue AS cvalue, x.orders AS orders, x.users AS users, 20171211 AS dt\n" - + "\t, 91 AS tagid\n" + "FROM (\n" + "\tWITH h AS (\n" - + "\t\t\tSELECT a.userid, a.col_1, a.col_2, a.col_3, a.col_4\n" - + "\t\t\t\t, a.col_5, a.col_6, c.orders_week\n" + "\t\t\tFROM (\n" - + "\t\t\t\tSELECT userid, col_1, col_2, col_3, col_4\n" + "\t\t\t\t\t, col_5, col_6\n" - + "\t\t\t\tFROM ofo_personas_dimensions\n" + "\t\t\t\tWHERE dt = 20171211\n" + "\t\t\t) a\n" - + "\t\t\t\tJOIN (\n" + "\t\t\t\t\tSELECT userid\n" + "\t\t\t\t\tFROM personas_user_tag\n" - + "\t\t\t\t\tWHERE tagid = 91\n" + "\t\t\t\t) b\n" + "\t\t\t\tON a.userid = b.userid\n" - + "\t\t\t\tJOIN (\n" + "\t\t\t\t\tSELECT userid, orders_week\n" - + "\t\t\t\t\tFROM ofo_personas_metrics\n" + "\t\t\t\t\tWHERE dt = 20171211\n" - + "\t\t\t\t) c\n" + "\t\t\t\tON a.userid = c.userid\n" + "\t\t)\n" - + "\tSELECT 'col_1' AS cname, col_1 AS cvalue, SUM(orders_week) AS orders\n" - + "\t\t, COUNT(userid) AS users\n" + "\tFROM h\n" + "\tGROUP BY col_1\n" + "\tUNION ALL\n" - + "\tSELECT 'col_2' AS cname, col_2 AS cvalue, SUM(orders_week) AS orders\n" - + "\t\t, COUNT(userid) AS users\n" + "\tFROM h\n" + "\tGROUP BY col_2\n" + ") x"; + String formatSql = "/*+engine=MPP, mppNativeInsertFromSelect=true*/\n" + + "INSERT INTO dashboard_crowd_analysis (cname, cvalue, orders, users, dt\n" + + "\t, tagid)\n" + + "SELECT x.cname AS cname, x.cvalue AS cvalue, x.orders AS orders, x.users AS users, 20171211 AS dt\n" + + "\t, 91 AS tagid\n" + + "FROM (\n" + + "\tWITH h AS (\n" + + "\t\t\tSELECT a.userid, a.col_1, a.col_2, a.col_3, a.col_4\n" + + "\t\t\t\t, a.col_5, a.col_6, c.orders_week\n" + + "\t\t\tFROM (\n" + + "\t\t\t\tSELECT userid, col_1, col_2, col_3, col_4\n" + + "\t\t\t\t\t, col_5, col_6\n" + + "\t\t\t\tFROM ofo_personas_dimensions\n" + + "\t\t\t\tWHERE dt = 20171211\n" + + "\t\t\t) a\n" + + "\t\t\t\tJOIN (\n" + + "\t\t\t\t\tSELECT userid\n" + + "\t\t\t\t\tFROM personas_user_tag\n" + + "\t\t\t\t\tWHERE tagid = 91\n" + + "\t\t\t\t) b\n" + + "\t\t\t\tON a.userid = b.userid\n" + + "\t\t\t\tJOIN (\n" + + "\t\t\t\t\tSELECT userid, orders_week\n" + + "\t\t\t\t\tFROM ofo_personas_metrics\n" + + "\t\t\t\t\tWHERE dt = 20171211\n" + + "\t\t\t\t) c\n" + + "\t\t\t\tON a.userid = c.userid\n" + + "\t\t)\n" + + "\tSELECT 'col_1' AS cname, col_1 AS cvalue, SUM(orders_week) AS orders\n" + + "\t\t, COUNT(userid) AS users\n" + + "\tFROM h\n" + + "\tGROUP BY col_1\n" + + "\tUNION ALL\n" + + "\tSELECT 'col_2' AS cname, col_2 AS cvalue, SUM(orders_week) AS orders\n" + + "\t\t, COUNT(userid) AS users\n" + + "\tFROM h\n" + + "\tGROUP BY col_2\n" + + ") x"; Assert.assertEquals(formatSql, SQLUtils.toMySqlString(insertStmt)); } diff --git a/src/test/java/com/alibaba/druid/bvt/sql/mysql/insert/MySqlInsertTest_43.java b/src/test/java/com/alibaba/druid/bvt/sql/mysql/insert/MySqlInsertTest_43.java new file mode 100644 index 0000000000..7872bb344c --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/mysql/insert/MySqlInsertTest_43.java @@ -0,0 +1,125 @@ +/* + * Copyright 1999-2017 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alibaba.druid.bvt.sql.mysql.insert; + +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlInsertStatement; +import com.alibaba.druid.sql.dialect.mysql.parser.MySqlStatementParser; +import com.alibaba.druid.sql.parser.SQLParserFeature; +import com.alibaba.druid.sql.visitor.ParameterizedOutputVisitorUtils; +import com.alibaba.druid.util.JdbcConstants; +import junit.framework.TestCase; + +import java.util.List; + +public class MySqlInsertTest_43 extends TestCase { + + public void test_insert_0() throws Exception { + String sql = "insert into adl_indication_ums_warehouse_ebax_a (sys_pk,sys_ds,sys_biztime,sys_gmt_modified,business_type,parcelled_order_num,warehouse_id)\n" + + "select\n" + + " concat(20190115,'_',ifnull(businessType, '#null#') ,'_',ifnull(warehouseId, '#null#') ) as sys_pk,\n" + + " cast(20190115 as bigint) as sys_ds,\n" + + " str_to_date('2019-01-15 21:51:00', '%Y-%m-%d %H:%i:%s') as sys_biztime,\n" + + " now() as sys_gmt_modified,\n" + + " cast(businessType as varchar) as business_type,\n" + + " cast(parcelledOrderNum as bigint) as parcelled_order_num,\n" + + " cast(warehouseId as varchar) as warehouse_id\n" + + "from (\n" + + "\n" + + "\n" + + "select cast(t1.warehouse_id as varchar) as warehouseId\n" + + " , t2.businessType\n" + + " , count(1) as parcelledOrderNum\n" + + "from sales_order t1\n" + + "join (\n" + + " select t2_1.warehouse_id\n" + + " , t2_1.external_batch_code\n" + + " ,(case\n" + + " when t2_2.operation_type = 2 or t2_2.operation_type is null then '2'\n" + + " when t2_2.operation_type = 3 then '800'\n" + + " when t2_2.operation_type = 1 then '900'\n" + + " end) as businessType\n" + + " from batch_order t2_1\n" + + " join wave_order t2_2\n" + + " on t2_1.wave_id = t2_2.id\n" + + " and t2_1.warehouse_id = t2_2.warehouse_id\n" + + " and t2_2.wave_status in (5,6)\n" + + " and t2_1.ds >= (201901 - 1)\n" + + " and t2_2.ds >= (201901 - 1)\n" + + " and t2_1.gmt_create >= date_add(now(), interval -3 day)\n" + + " and t2_1.gmt_create <= now()\n" + + " and t2_2.gmt_create >= date_add(now(), interval -3 day)\n" + + " and t2_2.gmt_create <= now()\n" + + "\n" + + ") t2 on t1.out_batch_code = t2.external_batch_code\n" + + " and t1.warehouse_id = t2.warehouse_id\n" + + " and t1.out_operation_mode = 3\n" + + " and t1.gmt_create >= CURDATE()\n" + + " and t1.gmt_create <= now()\n" + + " and t1.ds >= 201901\n" + + " and t2.businessType is not null\n" + + "group by t1.warehouse_id, t2.businessType\n" + + ") a\n"; + + MySqlStatementParser parser = new MySqlStatementParser(sql, false, true); + parser.config(SQLParserFeature.KeepInsertValueClauseOriginalString, true); + + List statementList = parser.parseStatementList(); + SQLStatement stmt = statementList.get(0); + + MySqlInsertStatement insertStmt = (MySqlInsertStatement) stmt; + assertEquals("INSERT INTO adl_indication_ums_warehouse_ebax_a (sys_pk, sys_ds, sys_biztime, sys_gmt_modified, business_type\n" + + "\t, parcelled_order_num, warehouse_id)\n" + + "SELECT concat(20190115, '_', ifnull(businessType, '#null#'), '_', ifnull(warehouseId, '#null#')) AS sys_pk\n" + + "\t, CAST(20190115 AS bigint) AS sys_ds, str_to_date('2019-01-15 21:51:00', '%Y-%m-%d %H:%i:%s') AS sys_biztime, now() AS sys_gmt_modified\n" + + "\t, CAST(businessType AS varchar) AS business_type, CAST(parcelledOrderNum AS bigint) AS parcelled_order_num, CAST(warehouseId AS varchar) AS warehouse_id\n" + + "FROM (\n" + + "\tSELECT CAST(t1.warehouse_id AS varchar) AS warehouseId, t2.businessType, COUNT(1) AS parcelledOrderNum\n" + + "\tFROM sales_order t1\n" + + "\t\tJOIN (\n" + + "\t\t\tSELECT t2_1.warehouse_id, t2_1.external_batch_code\n" + + "\t\t\t\t, CASE \n" + + "\t\t\t\t\tWHEN t2_2.operation_type = 2\n" + + "\t\t\t\t\tOR t2_2.operation_type IS NULL THEN '2'\n" + + "\t\t\t\t\tWHEN t2_2.operation_type = 3 THEN '800'\n" + + "\t\t\t\t\tWHEN t2_2.operation_type = 1 THEN '900'\n" + + "\t\t\t\tEND AS businessType\n" + + "\t\t\tFROM batch_order t2_1\n" + + "\t\t\t\tJOIN wave_order t2_2\n" + + "\t\t\t\tON t2_1.wave_id = t2_2.id\n" + + "\t\t\t\t\tAND t2_1.warehouse_id = t2_2.warehouse_id\n" + + "\t\t\t\t\tAND t2_2.wave_status IN (5, 6)\n" + + "\t\t\t\t\tAND t2_1.ds >= 201901 - 1\n" + + "\t\t\t\t\tAND t2_2.ds >= 201901 - 1\n" + + "\t\t\t\t\tAND t2_1.gmt_create >= date_add(now(), INTERVAL -3 DAY)\n" + + "\t\t\t\t\tAND t2_1.gmt_create <= now()\n" + + "\t\t\t\t\tAND t2_2.gmt_create >= date_add(now(), INTERVAL -3 DAY)\n" + + "\t\t\t\t\tAND t2_2.gmt_create <= now()\n" + + "\t\t) t2\n" + + "\t\tON t1.out_batch_code = t2.external_batch_code\n" + + "\t\t\tAND t1.warehouse_id = t2.warehouse_id\n" + + "\t\t\tAND t1.out_operation_mode = 3\n" + + "\t\t\tAND t1.gmt_create >= CURDATE()\n" + + "\t\t\tAND t1.gmt_create <= now()\n" + + "\t\t\tAND t1.ds >= 201901\n" + + "\t\t\tAND t2.businessType IS NOT NULL\n" + + "\tGROUP BY t1.warehouse_id, t2.businessType\n" + + ") a", insertStmt.toString()); + + ParameterizedOutputVisitorUtils.parameterize(sql, JdbcConstants.MYSQL, null, null); + } + +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/mysql/select/MySqlSelectTest_ads_keywords.java b/src/test/java/com/alibaba/druid/bvt/sql/mysql/select/MySqlSelectTest_ads_keywords.java new file mode 100644 index 0000000000..2dbb789d24 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/mysql/select/MySqlSelectTest_ads_keywords.java @@ -0,0 +1,59 @@ +/* + * Copyright 1999-2017 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alibaba.druid.bvt.sql.mysql.select; + +import com.alibaba.druid.sql.MysqlTest; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.ast.expr.SQLNotExpr; +import com.alibaba.druid.sql.ast.statement.SQLSelectStatement; +import com.alibaba.druid.sql.dialect.mysql.parser.MySqlStatementParser; +import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlSchemaStatVisitor; + +import java.util.List; + +public class MySqlSelectTest_ads_keywords extends MysqlTest { + + public void test_0() throws Exception { + String sql = "select label from a where not id > 50"; + + + MySqlStatementParser parser = new MySqlStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement stmt = statementList.get(0); + + assertEquals(1, statementList.size()); + + assertEquals("SELECT label\n" + + "FROM a\n" + + "WHERE NOT id > 50", // + stmt.toString()); + + MySqlSchemaStatVisitor visitor = new MySqlSchemaStatVisitor(); + stmt.accept(visitor); + + assertEquals(1, visitor.getTables().size()); + assertEquals(2, visitor.getColumns().size()); + assertEquals(1, visitor.getConditions().size()); + assertEquals(0, visitor.getOrderByColumns().size()); + + SQLNotExpr notExpr = (SQLNotExpr) ((SQLSelectStatement) stmt).getSelect().getQueryBlock().getWhere(); + assertNotNull(notExpr.getParent()); + assertNotNull(notExpr.getExpr().getParent()); + + + } + +} diff --git a/src/test/java/com/alibaba/druid/postgresql/PG_getCreateTableScriptTest.java b/src/test/java/com/alibaba/druid/postgresql/PG_getCreateTableScriptTest.java index 6ffe893830..7e14da15ce 100644 --- a/src/test/java/com/alibaba/druid/postgresql/PG_getCreateTableScriptTest.java +++ b/src/test/java/com/alibaba/druid/postgresql/PG_getCreateTableScriptTest.java @@ -2,6 +2,7 @@ package com.alibaba.druid.postgresql; import com.alibaba.druid.DbTestCase; import com.alibaba.druid.benckmark.proxy.BenchmarkExecutor; +import com.alibaba.druid.pool.vendor.PGValidConnectionChecker; import com.alibaba.druid.util.JdbcConstants; import com.alibaba.druid.util.JdbcUtils; @@ -22,6 +23,10 @@ public class PG_getCreateTableScriptTest extends DbTestCase { public void test_oracle() throws Exception { Connection conn = getConnection(); + PGValidConnectionChecker checker = new PGValidConnectionChecker(); + Connection raw = conn.unwrap(Connection.class); + checker.isValidConnection(raw, "select 1", 100); + // 从Oracle通过DBMS_METADATA.GET_DDL获取CreateTable语句列表 //String createTableScript = JdbcUtils.getCreateTableScript(conn, JdbcConstants.ORACLE); //System.out.println(createTableScript);