bug fixed for pg sql parser. for issue #1950

This commit is contained in:
wenshao
2018-03-22 16:41:51 +08:00
parent 39b88a2357
commit 720a857913
5 changed files with 184 additions and 5 deletions
@@ -183,16 +183,17 @@ public class PGExprParser extends SQLExprParser {
if (lexer.token() == Token.COMMA) {
return super.primaryRest(expr);
}
if ("TIMESTAMP".equalsIgnoreCase(ident)) {
if (lexer.token() != Token.LITERAL_ALIAS //
&& lexer.token() != Token.LITERAL_CHARS //
&& lexer.token() != Token.WITH) {
return new SQLIdentifierExpr("TIMESTAMP");
return super.primaryRest(
new SQLIdentifierExpr(ident));
}
SQLTimestampExpr timestamp = new SQLTimestampExpr();
if (lexer.token() == Token.WITH) {
lexer.nextToken();
acceptIdentifier("TIME");
@@ -214,8 +215,35 @@ public class PGExprParser extends SQLExprParser {
accept(Token.LITERAL_CHARS);
}
return primaryRest(timestamp);
return primaryRest(timestamp);
} else if ("TIMESTAMPTZ".equalsIgnoreCase(ident)) {
if (lexer.token() != Token.LITERAL_ALIAS //
&& lexer.token() != Token.LITERAL_CHARS //
&& lexer.token() != Token.WITH) {
return super.primaryRest(
new SQLIdentifierExpr(ident));
}
SQLTimestampExpr timestamp = new SQLTimestampExpr();
timestamp.setWithTimeZone(true);
String literal = lexer.stringVal();
timestamp.setLiteral(literal);
accept(Token.LITERAL_CHARS);
if (lexer.identifierEquals("AT")) {
lexer.nextToken();
acceptIdentifier("TIME");
acceptIdentifier("ZONE");
String timezone = lexer.stringVal();
timestamp.setTimeZone(timezone);
accept(Token.LITERAL_CHARS);
}
return primaryRest(timestamp);
} else if ("EXTRACT".equalsIgnoreCase(ident)) {
accept(Token.LPAREN);
@@ -1,5 +1,7 @@
package com.alibaba.druid.bvt.sql;
import com.alibaba.druid.sql.SQLUtils;
import com.alibaba.druid.sql.ast.statement.SQLSelectStatement;
import junit.framework.TestCase;
import org.junit.Assert;
@@ -67,4 +69,12 @@ public class PagerUtilsTest_Count_MySql_0 extends TestCase {
"\tFROM t2\n" +
") ALIAS_COUNT", result);
}
public void test_mysql_select() throws Exception {
SQLSelectStatement stmt = (SQLSelectStatement) SQLUtils.parseStatements("select * from t", JdbcConstants.MYSQL).get(0);
PagerUtils.limit(stmt.getSelect(), stmt.getDbType(), 10, 10);
assertEquals("SELECT *\n" +
"FROM t\n" +
"LIMIT 10, 10", stmt.toString());
}
}
@@ -56,4 +56,31 @@ public class MySqlInsertTest_26_special extends MysqlTest {
}
public void test_insert_special_1() throws Exception {
String sql = "INSERT INTO SUNTEST(ID,NAME) VALUES(1, \"Y\\\"'\")";
{
List<Object> outParameters = new ArrayList<Object>();
String psql = ParameterizedOutputVisitorUtils.parameterize(sql, JdbcConstants.MYSQL, outParameters);
assertEquals("INSERT INTO SUNTEST(ID, NAME)\n" +
"VALUES (?, ?)", psql);
assertEquals(2, outParameters.size());
String rsql = ParameterizedOutputVisitorUtils.restore(psql, JdbcConstants.MYSQL, outParameters);
assertEquals("INSERT INTO SUNTEST (ID, NAME)\n" +
"VALUES (1, 'Y\"''')", rsql);
}
MySqlStatementParser parser = new MySqlStatementParser(sql);
List<SQLStatement> statementList = parser.parseStatementList();
SQLStatement stmt = statementList.get(0);
MySqlInsertStatement insertStmt = (MySqlInsertStatement) stmt;
assertEquals("INSERT INTO SUNTEST (ID, NAME)\n" +
"VALUES (1, 'Y\"''')", SQLUtils.toMySqlString(insertStmt));
}
}
@@ -0,0 +1,55 @@
package com.alibaba.druid.bvt.sql.mysql.select;
import com.alibaba.druid.sql.MysqlTest;
import com.alibaba.druid.sql.SQLUtils;
import com.alibaba.druid.sql.ast.SQLStatement;
import com.alibaba.druid.sql.ast.expr.SQLCharExpr;
import com.alibaba.druid.sql.ast.statement.SQLInsertStatement;
import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock;
import com.alibaba.druid.sql.visitor.ParameterizedOutputVisitorUtils;
import com.alibaba.druid.sql.visitor.VisitorFeature;
import com.alibaba.druid.util.JdbcConstants;
import java.util.List;
public class MySqlSelectTest_147_huizhi extends MysqlTest {
public void test_0() throws Exception {
String sql = "INSERT INTO hz_dev_hb.tb_tmp_cda_opera_281c (target, appeartimes, source_id) SELECT\n" +
" VARCHAR20,\n" +
" count(1) AS appeartimes,\n" +
" 'resource_count1' as source_id\n" +
" FROM hz_dev_hb.tb_fxzx_large t1\n" +
" WHERE 1 = 1 AND VARCHAR20 IS NOT NULL AND\n" +
" MISSIONID =\n" +
" 'd2051b6549d9a028e83a8a9ab2c2'\n" +
" GROUP BY VARCHAR20";
List<SQLStatement> statementList = SQLUtils.parseStatements(sql, JdbcConstants.MYSQL);
SQLInsertStatement stmt = (SQLInsertStatement)statementList.get(0);
assertEquals(1, statementList.size());
assertEquals("INSERT INTO hz_dev_hb.tb_tmp_cda_opera_281c (target, appeartimes, source_id)\n" +
"SELECT VARCHAR20, COUNT(1) AS appeartimes, 'resource_count1' AS source_id\n" +
"FROM hz_dev_hb.tb_fxzx_large t1\n" +
"WHERE 1 = 1\n" +
"\tAND VARCHAR20 IS NOT NULL\n" +
"\tAND MISSIONID = 'd2051b6549d9a028e83a8a9ab2c2'\n" +
"GROUP BY VARCHAR20", stmt.toString());
assertEquals("INSERT INTO hz_dev_hb.tb_tmp_cda_opera_281c(target, appeartimes, source_id)\n" +
"SELECT VARCHAR20, COUNT(1) AS appeartimes, ? AS source_id\n" +
"FROM hz_dev_hb.tb_fxzx_large t1\n" +
"WHERE 1 = 1\n" +
"\tAND VARCHAR20 IS NOT NULL\n" +
"\tAND MISSIONID = ?\n" +
"GROUP BY VARCHAR20"
, ParameterizedOutputVisitorUtils.parameterize(sql, JdbcConstants.MYSQL));
SQLSelectQueryBlock queryBlock = stmt.getQuery().getQueryBlock();
assertEquals(3, queryBlock.getSelectList().size());
assertEquals(SQLCharExpr.class, queryBlock.getSelectList().get(2).getExpr().getClass());
}
}
@@ -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.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 PGSelectTest64 extends TestCase {
public void test_0() throws Exception {
String sql = "select * from public.newtable \n" +
"where EXTRACT(EPOCH FROM timestamptz (column1)) >= EXTRACT(EPOCH FROM timestamptz '2017-09-10 00:00:00') \n" +
"limit 10 offset 0";
System.out.println(sql);
List<SQLStatement> stmtList = SQLUtils.parseStatements(sql, JdbcConstants.POSTGRESQL);
SQLStatement stmt = stmtList.get(0);
assertEquals("SELECT *\n" +
"FROM public.newtable\n" +
"WHERE EXTRACT (EPOCH FROM timestamptz(column1)) >= EXTRACT (EPOCH FROM TIMESTAMP WITH TIME ZONE '2017-09-10 00:00:00')\n" +
"LIMIT 10 OFFSET 0", SQLUtils.toPGString(stmt));
assertEquals("select *\n" +
"from public.newtable\n" +
"where extract (EPOCH from timestamptz(column1)) >= extract (EPOCH from timestamp with time zone '2017-09-10 00:00:00')\n" +
"limit 10 offset 0", SQLUtils.toPGString(stmt, SQLUtils.DEFAULT_LCASE_FORMAT_OPTION));
assertEquals(1, stmtList.size());
SchemaStatVisitor visitor = SQLUtils.createSchemaStatVisitor(JdbcConstants.POSTGRESQL);
stmt.accept(visitor);
// System.out.println("Tables : " + visitor.getTables());
// System.out.println("fields : " + visitor.getColumns());
// System.out.println("coditions : " + visitor.getConditions());
assertEquals(2, visitor.getColumns().size());
assertEquals(1, visitor.getTables().size());
}
}