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 26bc99e3a3..a01360dcea 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 @@ -281,6 +281,11 @@ public class MySqlStatementParser extends SQLStatementParser { char markChar = lexer.current(); int markBp = lexer.bp(); + List comments = null; + if (lexer.isKeepComments() && lexer.hasComment()) { + comments = lexer.readAndResetComments(); + } + accept(Token.CREATE); boolean replace = false; @@ -299,6 +304,11 @@ public class MySqlStatementParser extends SQLStatementParser { MySqlCreateTableParser parser = new MySqlCreateTableParser(this.exprParser); MySqlCreateTableStatement stmt = parser.parseCrateTable(false); stmt.setHints(hints); + + if (comments != null) { + stmt.addBeforeComment(comments); + } + return stmt; } diff --git a/src/main/java/com/alibaba/druid/sql/parser/Lexer.java b/src/main/java/com/alibaba/druid/sql/parser/Lexer.java index 7643403f26..930d1b4740 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/Lexer.java +++ b/src/main/java/com/alibaba/druid/sql/parser/Lexer.java @@ -463,7 +463,12 @@ public class Lexer { token = Token.QUESQUES; } else if (ch == '|' && JdbcConstants.POSTGRESQL.equals(dbType)) { scanChar(); - token = Token.QUESBAR; + if (ch == '|') { + unscan(); + token = Token.QUES; + } else { + token = Token.QUESBAR; + } } else if (ch == '&' && JdbcConstants.POSTGRESQL.equals(dbType)) { scanChar(); token = Token.QUESAMP; diff --git a/src/main/java/com/alibaba/druid/sql/parser/SQLParserUtils.java b/src/main/java/com/alibaba/druid/sql/parser/SQLParserUtils.java index bd95e35f8b..0fcebd7f05 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/SQLParserUtils.java +++ b/src/main/java/com/alibaba/druid/sql/parser/SQLParserUtils.java @@ -43,7 +43,7 @@ public class SQLParserUtils { public static SQLStatementParser createSQLStatementParser(String sql, String dbType) { boolean keepComments; - if (JdbcConstants.ODPS.equals(dbType)) { + if (JdbcConstants.ODPS.equals(dbType) || JdbcConstants.MYSQL.equals(dbType)) { keepComments = true; } else { keepComments = false; diff --git a/src/test/java/com/alibaba/druid/bvt/bug/Issue1737.java b/src/test/java/com/alibaba/druid/bvt/bug/Issue1737.java new file mode 100644 index 0000000000..240a9364be --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/bug/Issue1737.java @@ -0,0 +1,33 @@ +package com.alibaba.druid.bvt.bug; + +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.dialect.oracle.parser.OracleStatementParser; +import com.alibaba.druid.sql.dialect.oracle.visitor.OracleExportParameterVisitor; +import com.alibaba.druid.sql.parser.SQLStatementParser; +import com.alibaba.druid.sql.visitor.ExportParameterVisitor; +import com.alibaba.fastjson.JSON; +import junit.framework.TestCase; + +import java.util.List; + +/** + * Created by wenshao on 25/06/2017. + */ +public class Issue1737 extends TestCase { + public void test_for_issue() throws Exception { + String sql = "select * from test_tab1 where name='name' and id in ('A','B')"; + final StringBuilder out = new StringBuilder(); + final ExportParameterVisitor visitor = new OracleExportParameterVisitor(out); + visitor.setParameterizedMergeInList(true); + SQLStatementParser parser = new OracleStatementParser(sql); + final SQLStatement parseStatement = parser.parseStatement(); + parseStatement.accept(visitor); + final List plist = visitor.getParameters(); + sql = out.toString(); + System.out.println("src:"+sql); + System.out.println("sql:"+sql); + System.out.println(" params: " + JSON.toJSONString(plist)); + + assertEquals("[\"name\",[\"A\",\"B\"]]", JSON.toJSONString(plist)); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/bug/Issue1762.java b/src/test/java/com/alibaba/druid/bvt/bug/Issue1762.java new file mode 100644 index 0000000000..e0d192579f --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/bug/Issue1762.java @@ -0,0 +1,52 @@ +package com.alibaba.druid.bvt.bug; + +import com.alibaba.druid.sql.SQLUtils; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.visitor.SchemaStatVisitor; +import com.alibaba.druid.util.JdbcConstants; +import junit.framework.TestCase; + +import java.util.List; + +/** + * Created by wenshao on 25/06/2017. + */ +public class Issue1762 extends TestCase { + private final String dbType = JdbcConstants.MYSQL; + + public void test_0() throws Exception { + String sql = "-- table-name-bean-name:some --\n" + + "CREATE TABLE `some_table` (\n" + + " `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键'\n" + + ")"; + + List stmtList = SQLUtils.parseStatements(sql, dbType); + SQLStatement stmt = stmtList.get(0); + List beforeComments = stmt.getBeforeCommentsDirect(); + assertNotNull(beforeComments); + assertEquals(1, beforeComments.size()); + assertEquals("-- table-name-bean-name:some --", beforeComments.get(0)); + + assertEquals("-- table-name-bean-name:some --\n" + + "CREATE TABLE `some_table` (\n" + + "\t`id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键'\n" + + ")", SQLUtils.toMySqlString(stmt)); + + assertEquals("-- table-name-bean-name:some --\n" + + "create table `some_table` (\n" + + "\t`id` bigint(20) unsigned not null auto_increment comment '主键'\n" + + ")", SQLUtils.toMySqlString(stmt, SQLUtils.DEFAULT_LCASE_FORMAT_OPTION)); + + assertEquals(1, stmtList.size()); + + SchemaStatVisitor visitor = SQLUtils.createSchemaStatVisitor(dbType); + stmt.accept(visitor); + +// System.out.println("Tables : " + visitor.getTables()); +// System.out.println("fields : " + visitor.getColumns()); +// System.out.println("coditions : " + visitor.getConditions()); + + assertEquals(1, visitor.getColumns().size()); + assertEquals(1, visitor.getTables().size()); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/postgresql/select/PGSelectTest51.java b/src/test/java/com/alibaba/druid/bvt/sql/postgresql/select/PGSelectTest51.java new file mode 100644 index 0000000000..f5c2425a18 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/postgresql/select/PGSelectTest51.java @@ -0,0 +1,117 @@ +/* + * 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.postgresql.select; + +import com.alibaba.druid.sql.SQLUtils; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.visitor.SchemaStatVisitor; +import com.alibaba.druid.util.JdbcConstants; +import junit.framework.TestCase; + +import java.util.List; + +public class PGSelectTest51 extends TestCase { + private final String dbType = JdbcConstants.POSTGRESQL; + + public void test_0() throws Exception { + String sql = "SELECT TMP_PAGE.*, ROWNUM ROW_ID FROM ( SELECT M.*, A.*\n" + + "\t\tFROM T_EW_MERCHANT M LEFT JOIN LP_ADDRESS A\n" + + "\t\tON\n" + + "\t\tM.ADDRESS_KEY = A.KEY\n" + + "\t\t \n" + + "\t\t\tWHERE M.MERCHANT_CODE LIKE '%'||?||'%'\n" + + "\t\t\tOR\n" + + "\t\t\tM.MERCHANT_NAME LIKE '%'||?||'%'\n" + + "\t\t\tOR M.MERCHANT_NAME LIKE\n" + + "\t\t\t'%'||?||'%'\n" + + "\t\t\tOR M.CERTIFICATE LIKE\n" + + "\t\t\t'%'||?||'%'\n" + + "\t\t\tOR M.OWNER\n" + + "\t\t\tLIKE\n" + + "\t\t\t'%'||?||'%'\n" + + "\t\t\tOR A.COUNTRY LIKE\n" + + "\t\t\t'%'||?||'%'\n" + + "\t\t\tOR\n" + + "\t\t\tA.PROVINCE LIKE\n" + + "\t\t\t'%'||?||'%'\n" + + "\t\t\tOR A.CITY LIKE\n" + + "\t\t\t'%'||?||'%'\n" + + "\t\t\tOR A.COUNTY LIKE\n" + + "\t\t\t'%'||?||'%'\n" + + "\t\t\tOR A.STREET_AREA LIKE\n" + + "\t\t\t'%'||?||'%'\n" + + "\t\t\tOR A.DETAILE LIKE\n" + + "\t\t\t'%'||?||'%'\n" + + "\t\t\tOR A.ZIPCODE\n" + + "\t\t\tLIKE\n" + + "\t\t\t'%'||?||'%' ) TMP_PAGE WHERE ROWNUM <= 10"; + + List stmtList = SQLUtils.parseStatements(sql, dbType); + SQLStatement stmt = stmtList.get(0); + + assertEquals("SELECT TMP_PAGE.*, ROWNUM AS ROW_ID\n" + + "FROM (\n" + + "\tSELECT M.*, A.*\n" + + "\tFROM T_EW_MERCHANT M\n" + + "\t\tLEFT JOIN LP_ADDRESS A ON M.ADDRESS_KEY = A.KEY\n" + + "\tWHERE M.MERCHANT_CODE LIKE ('%' || ? || '%')\n" + + "\t\tOR M.MERCHANT_NAME LIKE ('%' || ? || '%')\n" + + "\t\tOR M.MERCHANT_NAME LIKE ('%' || ? || '%')\n" + + "\t\tOR M.CERTIFICATE LIKE ('%' || ? || '%')\n" + + "\t\tOR M.OWNER LIKE ('%' || ? || '%')\n" + + "\t\tOR A.COUNTRY LIKE ('%' || ? || '%')\n" + + "\t\tOR A.PROVINCE LIKE ('%' || ? || '%')\n" + + "\t\tOR A.CITY LIKE ('%' || ? || '%')\n" + + "\t\tOR A.COUNTY LIKE ('%' || ? || '%')\n" + + "\t\tOR A.STREET_AREA LIKE ('%' || ? || '%')\n" + + "\t\tOR A.DETAILE LIKE ('%' || ? || '%')\n" + + "\t\tOR A.ZIPCODE LIKE ('%' || ? || '%')\n" + + ") TMP_PAGE\n" + + "WHERE ROWNUM <= 10", SQLUtils.toPGString(stmt)); + + assertEquals("select TMP_PAGE.*, ROWNUM as ROW_ID\n" + + "from (\n" + + "\tselect M.*, A.*\n" + + "\tfrom T_EW_MERCHANT M\n" + + "\t\tleft join LP_ADDRESS A on M.ADDRESS_KEY = A.KEY\n" + + "\twhere M.MERCHANT_CODE like ('%' || ? || '%')\n" + + "\t\tor M.MERCHANT_NAME like ('%' || ? || '%')\n" + + "\t\tor M.MERCHANT_NAME like ('%' || ? || '%')\n" + + "\t\tor M.CERTIFICATE like ('%' || ? || '%')\n" + + "\t\tor M.OWNER like ('%' || ? || '%')\n" + + "\t\tor A.COUNTRY like ('%' || ? || '%')\n" + + "\t\tor A.PROVINCE like ('%' || ? || '%')\n" + + "\t\tor A.CITY like ('%' || ? || '%')\n" + + "\t\tor A.COUNTY like ('%' || ? || '%')\n" + + "\t\tor A.STREET_AREA like ('%' || ? || '%')\n" + + "\t\tor A.DETAILE like ('%' || ? || '%')\n" + + "\t\tor A.ZIPCODE like ('%' || ? || '%')\n" + + ") TMP_PAGE\n" + + "where ROWNUM <= 10", SQLUtils.toPGString(stmt, SQLUtils.DEFAULT_LCASE_FORMAT_OPTION)); + + assertEquals(1, stmtList.size()); + + SchemaStatVisitor visitor = SQLUtils.createSchemaStatVisitor(dbType); + stmt.accept(visitor); + +// System.out.println("Tables : " + visitor.getTables()); +// System.out.println("fields : " + visitor.getColumns()); +// System.out.println("coditions : " + visitor.getConditions()); + + assertEquals(15, visitor.getColumns().size()); + assertEquals(2, visitor.getTables().size()); + } +}