Skip to content

Commit

Permalink
fix postgresql parenthesized bug
Browse files Browse the repository at this point in the history
example:
1、(select * from a)
2、(select * from a) union all select * from b;
pg以括号开头的select语句会陷入死循环。
  • Loading branch information
huangtiande committed Feb 5, 2015
1 parent 883d1fd commit 947190c
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ public class SQLSelectQueryBlock extends SQLObjectImpl implements SQLSelectQuery
protected SQLExprTableSource into;
protected SQLExpr where;
protected SQLSelectGroupByClause groupBy;
protected boolean parenthesized = false;

public SQLSelectQueryBlock(){

Expand Down Expand Up @@ -90,7 +91,15 @@ public void setFrom(SQLTableSource from) {
this.from = from;
}

@Override
public boolean isParenthesized() {
return parenthesized;
}

public void setParenthesized(boolean parenthesized) {
this.parenthesized = parenthesized;
}

@Override
protected void accept0(SQLASTVisitor visitor) {
if (visitor.visit(this)) {
acceptChild(visitor, this.selectList);
Expand All @@ -105,6 +114,7 @@ protected void accept0(SQLASTVisitor visitor) {
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + (Boolean.valueOf(parenthesized).hashCode());
result = prime * result + distionOption;
result = prime * result + ((from == null) ? 0 : from.hashCode());
result = prime * result + ((groupBy == null) ? 0 : groupBy.hashCode());
Expand All @@ -120,6 +130,7 @@ public boolean equals(Object obj) {
if (obj == null) return false;
if (getClass() != obj.getClass()) return false;
SQLSelectQueryBlock other = (SQLSelectQueryBlock) obj;
if (parenthesized ^ other.parenthesized) return false;
if (distionOption != other.distionOption) return false;
if (from == null) {
if (other.from != null) return false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
import com.alibaba.druid.sql.ast.statement.SQLExprTableSource;
import com.alibaba.druid.sql.ast.statement.SQLSelectQuery;
import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock;
import com.alibaba.druid.sql.ast.statement.SQLTableSource;
import com.alibaba.druid.sql.dialect.postgresql.ast.expr.PGParameter;
import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGFunctionTableSource;
Expand Down Expand Up @@ -58,6 +59,18 @@ public SQLSelectQuery query() {
return queryRest(valuesQuery);
}

if (lexer.token() == Token.LPAREN) {
lexer.nextToken();

SQLSelectQuery select = query();
if (select instanceof SQLSelectQueryBlock) {
((SQLSelectQueryBlock) select).setParenthesized(true);
}
accept(Token.RPAREN);

return queryRest(select);
}

PGSelectQueryBlock queryBlock = new PGSelectQueryBlock();

if (lexer.token() == Token.SELECT) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@

import com.alibaba.druid.sql.PGTest;
import com.alibaba.druid.sql.ast.SQLStatement;
import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock;
import com.alibaba.druid.sql.ast.statement.SQLUnionQuery;
import com.alibaba.druid.sql.dialect.postgresql.ast.stmt.PGSelectStatement;
import com.alibaba.druid.sql.dialect.postgresql.parser.PGSQLStatementParser;
import com.alibaba.druid.sql.dialect.postgresql.visitor.PGSchemaStatVisitor;

Expand All @@ -46,6 +49,26 @@ public void test_0() throws Exception {
Assert.assertEquals(0, visitor.getColumns().size());
Assert.assertEquals(2, visitor.getTables().size());
}

public void test_1() throws Exception {
String sql = "(select * from a) union select * from b";
PGSQLStatementParser parser = new PGSQLStatementParser(sql);
List<SQLStatement> statementList = parser.parseStatementList();
SQLStatement statemen = statementList.get(0);
print(statementList);

Assert.assertEquals(1, statementList.size());
assertTrue(statemen instanceof PGSelectStatement);
PGSelectStatement select = (PGSelectStatement) statemen;
assertTrue(select.getSelect().getQuery() instanceof SQLUnionQuery);
SQLUnionQuery unionQuery = (SQLUnionQuery) select.getSelect()
.getQuery();
assertTrue(unionQuery.getLeft() instanceof SQLSelectQueryBlock);
assertTrue(unionQuery.getRight() instanceof SQLSelectQueryBlock);
SQLSelectQueryBlock leftQueryBlock = (SQLSelectQueryBlock) unionQuery
.getLeft();
assertTrue(leftQueryBlock.isParenthesized());
}

}

Expand Down

0 comments on commit 947190c

Please sign in to comment.