mirror of
https://github.com/alibaba/druid.git
synced 2023-03-04 19:17:16 +00:00
bug fixed for sql server parser. for issue #1795
This commit is contained in:
@@ -404,7 +404,8 @@ public class PagerUtils {
|
||||
|
||||
SQLSelectQueryBlock queryBlock = (SQLSelectQueryBlock) query;
|
||||
|
||||
if (queryBlock.getGroupBy() != null && queryBlock.getGroupBy().getItems().size() > 0) {
|
||||
if (queryBlock.getGroupBy() != null
|
||||
&& queryBlock.getGroupBy().getItems().size() > 0) {
|
||||
return createCountUseSubQuery(select, dbType);
|
||||
}
|
||||
|
||||
@@ -489,16 +490,8 @@ public class PagerUtils {
|
||||
private static void clearOrderBy(SQLSelectQuery query) {
|
||||
if (query instanceof SQLSelectQueryBlock) {
|
||||
SQLSelectQueryBlock queryBlock = (SQLSelectQueryBlock) query;
|
||||
if (queryBlock instanceof MySqlSelectQueryBlock) {
|
||||
MySqlSelectQueryBlock mysqlQueryBlock = (MySqlSelectQueryBlock) queryBlock;
|
||||
if (mysqlQueryBlock.getOrderBy() != null) {
|
||||
mysqlQueryBlock.setOrderBy(null);
|
||||
}
|
||||
} else if (queryBlock instanceof PGSelectQueryBlock) {
|
||||
PGSelectQueryBlock pgQueryBlock = (PGSelectQueryBlock) queryBlock;
|
||||
if (pgQueryBlock.getOrderBy() != null) {
|
||||
pgQueryBlock.setOrderBy(null);
|
||||
}
|
||||
if (queryBlock.getOrderBy() != null) {
|
||||
queryBlock.setOrderBy(null);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
+2
@@ -163,6 +163,8 @@ public class SQLServerSelectParser extends SQLSelectParser {
|
||||
|
||||
parseGroupBy(queryBlock);
|
||||
|
||||
queryBlock.setOrderBy(this.exprParser.parseOrderBy());
|
||||
|
||||
parseFetchClause(queryBlock);
|
||||
|
||||
return queryRest(queryBlock);
|
||||
|
||||
+10
-2
@@ -16,6 +16,7 @@
|
||||
package com.alibaba.druid.sql.dialect.sqlserver.visitor;
|
||||
|
||||
import com.alibaba.druid.sql.ast.SQLName;
|
||||
import com.alibaba.druid.sql.ast.SQLOrderBy;
|
||||
import com.alibaba.druid.sql.ast.SQLSetQuantifier;
|
||||
import com.alibaba.druid.sql.ast.SQLStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.*;
|
||||
@@ -82,9 +83,16 @@ public class SQLServerOutputVisitor extends SQLASTOutputVisitor implements SQLSe
|
||||
x.getWhere().accept(this);
|
||||
}
|
||||
|
||||
if (x.getGroupBy() != null) {
|
||||
SQLSelectGroupByClause groupBy = x.getGroupBy();
|
||||
if (groupBy != null) {
|
||||
println();
|
||||
x.getGroupBy().accept(this);
|
||||
groupBy.accept(this);
|
||||
}
|
||||
|
||||
SQLOrderBy orderBy = x.getOrderBy();
|
||||
if (orderBy != null) {
|
||||
println();
|
||||
orderBy.accept(this);
|
||||
}
|
||||
|
||||
printFetchFirst(x);
|
||||
|
||||
@@ -620,7 +620,8 @@ public class SQLSelectParser extends SQLParser {
|
||||
|
||||
if (lexer.token() == Token.FETCH) {
|
||||
lexer.nextToken();
|
||||
if (lexer.token() == Token.FIRST) {
|
||||
if (lexer.token() == Token.FIRST
|
||||
|| identifierEquals("NEXT")) {
|
||||
lexer.nextToken();
|
||||
} else {
|
||||
acceptIdentifier("FIRST");
|
||||
|
||||
@@ -1370,14 +1370,16 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet
|
||||
|
||||
printHierarchical(x);
|
||||
|
||||
if (x.getGroupBy() != null) {
|
||||
SQLSelectGroupByClause groupBy = x.getGroupBy();
|
||||
if (groupBy != null) {
|
||||
println();
|
||||
x.getGroupBy().accept(this);
|
||||
groupBy.accept(this);
|
||||
}
|
||||
|
||||
if (x.getOrderBy() != null) {
|
||||
|
||||
SQLOrderBy orderBy = x.getOrderBy();
|
||||
if (orderBy != null) {
|
||||
println();
|
||||
x.getOrderBy().accept(this);
|
||||
orderBy.accept(this);
|
||||
}
|
||||
|
||||
if (!JdbcConstants.INFORMIX.equals(dbType)) {
|
||||
@@ -1430,11 +1432,21 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet
|
||||
if (offset != null) {
|
||||
print0(ucase ? "OFFSET " : "offset ");
|
||||
offset.accept(this);
|
||||
print0(ucase ? " ROWS " : " rows ");
|
||||
print0(ucase ? " ROWS" : " rows");
|
||||
}
|
||||
|
||||
if (first != null) {
|
||||
if (offset != null) {
|
||||
print(' ');
|
||||
}
|
||||
if (JdbcConstants.SQL_SERVER.equals(dbType) && offset != null) {
|
||||
print0(ucase ? "FETCH NEXT " : "fetch next ");
|
||||
} else {
|
||||
print0(ucase ? "FETCH FIRST " : "fetch first ");
|
||||
}
|
||||
first.accept(this);
|
||||
print0(ucase ? " ROWS ONLY" : " rows only");
|
||||
}
|
||||
print0(ucase ? "FETCH FIRST " : "fetch first ");
|
||||
first.accept(this);
|
||||
print0(ucase ? " ROWS ONLY" : " rows only");
|
||||
} else {
|
||||
println();
|
||||
limit.accept(this);
|
||||
|
||||
@@ -12,28 +12,28 @@ public class PagerUtilsTest_Count_SQLServer_0 extends TestCase {
|
||||
public void test_sqlserver_0() throws Exception {
|
||||
String sql = "select * from t";
|
||||
String result = PagerUtils.count(sql, JdbcConstants.SQL_SERVER);
|
||||
Assert.assertEquals("SELECT COUNT(*)\n" + //
|
||||
assertEquals("SELECT COUNT(*)\n" + //
|
||||
"FROM t", result);
|
||||
}
|
||||
|
||||
public void test_sqlserver_1() throws Exception {
|
||||
String sql = "select id, name from t";
|
||||
String result = PagerUtils.count(sql, JdbcConstants.SQL_SERVER);
|
||||
Assert.assertEquals("SELECT COUNT(*)\n" + //
|
||||
assertEquals("SELECT COUNT(*)\n" + //
|
||||
"FROM t", result);
|
||||
}
|
||||
|
||||
public void test_sqlserver_2() throws Exception {
|
||||
String sql = "select id, name from t order by id";
|
||||
String result = PagerUtils.count(sql, JdbcConstants.SQL_SERVER);
|
||||
Assert.assertEquals("SELECT COUNT(*)\n" + //
|
||||
assertEquals("SELECT COUNT(*)\n" + //
|
||||
"FROM t", result);
|
||||
}
|
||||
|
||||
public void test_sqlserver_group_0() throws Exception {
|
||||
String sql = "select type, count(*) from t group by type";
|
||||
String result = PagerUtils.count(sql, JdbcConstants.SQL_SERVER);
|
||||
Assert.assertEquals("SELECT COUNT(*)\n" +
|
||||
assertEquals("SELECT COUNT(*)\n" +
|
||||
"FROM (\n" +
|
||||
"\tSELECT type, COUNT(*)\n" +
|
||||
"\tFROM t\n" +
|
||||
@@ -44,7 +44,7 @@ public class PagerUtilsTest_Count_SQLServer_0 extends TestCase {
|
||||
public void test_sqlserver_union_0() throws Exception {
|
||||
String sql = "select id, name from t1 union select id, name from t2 order by id";
|
||||
String result = PagerUtils.count(sql, JdbcConstants.SQL_SERVER);
|
||||
Assert.assertEquals("SELECT COUNT(*)\n" +
|
||||
assertEquals("SELECT COUNT(*)\n" +
|
||||
"FROM (\n" +
|
||||
"\tSELECT id, name\n" +
|
||||
"\tFROM t1\n" +
|
||||
|
||||
@@ -0,0 +1,151 @@
|
||||
/*
|
||||
* 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.sqlserver;
|
||||
|
||||
import com.alibaba.druid.sql.SQLUtils;
|
||||
import com.alibaba.druid.sql.ast.SQLStatement;
|
||||
import com.alibaba.druid.sql.dialect.sqlserver.parser.SQLServerStatementParser;
|
||||
import junit.framework.TestCase;
|
||||
import org.junit.Assert;
|
||||
|
||||
public class SQLServerSelectTest24 extends TestCase {
|
||||
|
||||
public void test_simple() throws Exception {
|
||||
String sql = //
|
||||
"SELECT TOP 100 *\n" +
|
||||
"FROM\n" +
|
||||
"(SELECT ROW_NUMBER()\n" +
|
||||
"OVER (ORDER BY DateUpdated DESC) PAGE_ROW_NUMBER, *\n" +
|
||||
"FROM\n" +
|
||||
"(SELECT x.*\n" +
|
||||
"FROM\n" +
|
||||
"(SELECT TOP 2000 a.*\n" +
|
||||
"FROM pk_Battle a\n" +
|
||||
"WHERE a.RequestUserId = 33460323\n" +
|
||||
"AND a.IsActive = 1\n" +
|
||||
"AND a.BattleType <> 2\n" +
|
||||
"AND a.Status NOT IN (0, 2)\n" +
|
||||
"AND EXISTS\n" +
|
||||
"(SELECT TOP 1 1\n" +
|
||||
"FROM pk_BattleExt\n" +
|
||||
"WHERE BattleId = a.Id\n" +
|
||||
"AND RequestIsViewResults = 0)\n" +
|
||||
"ORDER BY a.Id DESC\n" +
|
||||
"UNION\n" +
|
||||
"SELECT TOP 1000 a.*\n" +
|
||||
"FROM pk_Battle a\n" +
|
||||
"WHERE a.ResponseUserId = 33460323\n" +
|
||||
"AND a.IsActive = 1\n" +
|
||||
"AND a.BattleType = 1\n" +
|
||||
"AND a.Status NOT IN (0, 2)\n" +
|
||||
"AND EXISTS\n" +
|
||||
"(SELECT TOP 1 1\n" +
|
||||
"FROM pk_BattleExt\n" +
|
||||
"WHERE BattleId = a.Id\n" +
|
||||
"AND ResponseIsViewResults = 0)\n" +
|
||||
"ORDER BY a.Id DESC) x) AS PAGE_TABLE_ALIAS) AS PAGE_TABLE_ALIAS\n" +
|
||||
"WHERE PAGE_ROW_NUMBER > 0\n" +
|
||||
"ORDER BY PAGE_ROW_NUMBER"; //
|
||||
|
||||
SQLServerStatementParser parser = new SQLServerStatementParser(sql);
|
||||
SQLStatement stmt = parser.parseStatementList().get(0);
|
||||
|
||||
{
|
||||
String text = SQLUtils.toSQLServerString(stmt);
|
||||
|
||||
Assert.assertEquals("SELECT TOP 100 *\n" +
|
||||
"FROM (\n" +
|
||||
"\tSELECT ROW_NUMBER() OVER (ORDER BY DateUpdated DESC) AS PAGE_ROW_NUMBER, *\n" +
|
||||
"\tFROM (\n" +
|
||||
"\t\tSELECT x.*\n" +
|
||||
"\t\tFROM (\n" +
|
||||
"\t\t\tSELECT TOP 2000 a.*\n" +
|
||||
"\t\t\tFROM pk_Battle a\n" +
|
||||
"\t\t\tWHERE a.RequestUserId = 33460323\n" +
|
||||
"\t\t\t\tAND a.IsActive = 1\n" +
|
||||
"\t\t\t\tAND a.BattleType <> 2\n" +
|
||||
"\t\t\t\tAND a.Status NOT IN (0, 2)\n" +
|
||||
"\t\t\t\tAND EXISTS (\n" +
|
||||
"\t\t\t\t\tSELECT TOP 1 1\n" +
|
||||
"\t\t\t\t\tFROM pk_BattleExt\n" +
|
||||
"\t\t\t\t\tWHERE BattleId = a.Id\n" +
|
||||
"\t\t\t\t\t\tAND RequestIsViewResults = 0\n" +
|
||||
"\t\t\t\t)\n" +
|
||||
"\t\t\tORDER BY a.Id DESC\n" +
|
||||
"\t\t\tUNION\n" +
|
||||
"\t\t\tSELECT TOP 1000 a.*\n" +
|
||||
"\t\t\tFROM pk_Battle a\n" +
|
||||
"\t\t\tWHERE a.ResponseUserId = 33460323\n" +
|
||||
"\t\t\t\tAND a.IsActive = 1\n" +
|
||||
"\t\t\t\tAND a.BattleType = 1\n" +
|
||||
"\t\t\t\tAND a.Status NOT IN (0, 2)\n" +
|
||||
"\t\t\t\tAND EXISTS (\n" +
|
||||
"\t\t\t\t\tSELECT TOP 1 1\n" +
|
||||
"\t\t\t\t\tFROM pk_BattleExt\n" +
|
||||
"\t\t\t\t\tWHERE BattleId = a.Id\n" +
|
||||
"\t\t\t\t\t\tAND ResponseIsViewResults = 0\n" +
|
||||
"\t\t\t\t)\n" +
|
||||
"\t\t\tORDER BY a.Id DESC\n" +
|
||||
"\t\t) x\n" +
|
||||
"\t) PAGE_TABLE_ALIAS\n" +
|
||||
") PAGE_TABLE_ALIAS\n" +
|
||||
"WHERE PAGE_ROW_NUMBER > 0\n" +
|
||||
"ORDER BY PAGE_ROW_NUMBER", text);
|
||||
}
|
||||
{
|
||||
String text = SQLUtils.toSQLServerString(stmt, SQLUtils.DEFAULT_LCASE_FORMAT_OPTION);
|
||||
|
||||
Assert.assertEquals("select top 100 *\n" +
|
||||
"from (\n" +
|
||||
"\tselect row_number() over (order by DateUpdated desc) as PAGE_ROW_NUMBER, *\n" +
|
||||
"\tfrom (\n" +
|
||||
"\t\tselect x.*\n" +
|
||||
"\t\tfrom (\n" +
|
||||
"\t\t\tselect top 2000 a.*\n" +
|
||||
"\t\t\tfrom pk_Battle a\n" +
|
||||
"\t\t\twhere a.RequestUserId = 33460323\n" +
|
||||
"\t\t\t\tand a.IsActive = 1\n" +
|
||||
"\t\t\t\tand a.BattleType <> 2\n" +
|
||||
"\t\t\t\tand a.Status not in (0, 2)\n" +
|
||||
"\t\t\t\tand exists (\n" +
|
||||
"\t\t\t\t\tselect top 1 1\n" +
|
||||
"\t\t\t\t\tfrom pk_BattleExt\n" +
|
||||
"\t\t\t\t\twhere BattleId = a.Id\n" +
|
||||
"\t\t\t\t\t\tand RequestIsViewResults = 0\n" +
|
||||
"\t\t\t\t)\n" +
|
||||
"\t\t\torder by a.Id desc\n" +
|
||||
"\t\t\tunion\n" +
|
||||
"\t\t\tselect top 1000 a.*\n" +
|
||||
"\t\t\tfrom pk_Battle a\n" +
|
||||
"\t\t\twhere a.ResponseUserId = 33460323\n" +
|
||||
"\t\t\t\tand a.IsActive = 1\n" +
|
||||
"\t\t\t\tand a.BattleType = 1\n" +
|
||||
"\t\t\t\tand a.Status not in (0, 2)\n" +
|
||||
"\t\t\t\tand exists (\n" +
|
||||
"\t\t\t\t\tselect top 1 1\n" +
|
||||
"\t\t\t\t\tfrom pk_BattleExt\n" +
|
||||
"\t\t\t\t\twhere BattleId = a.Id\n" +
|
||||
"\t\t\t\t\t\tand ResponseIsViewResults = 0\n" +
|
||||
"\t\t\t\t)\n" +
|
||||
"\t\t\torder by a.Id desc\n" +
|
||||
"\t\t) x\n" +
|
||||
"\t) PAGE_TABLE_ALIAS\n" +
|
||||
") PAGE_TABLE_ALIAS\n" +
|
||||
"where PAGE_ROW_NUMBER > 0\n" +
|
||||
"order by PAGE_ROW_NUMBER", text);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user