diff --git a/src/main/java/com/alibaba/druid/sql/parser/SQLExprParser.java b/src/main/java/com/alibaba/druid/sql/parser/SQLExprParser.java index 3da6ed0b16..b55d5cacf3 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/SQLExprParser.java +++ b/src/main/java/com/alibaba/druid/sql/parser/SQLExprParser.java @@ -783,12 +783,15 @@ public class SQLExprParser extends SQLParser { } public final SQLExpr andRest(SQLExpr expr) throws ParserException { - if (lexer.token() == Token.AND || lexer.token() == Token.AMPAMP) { - lexer.nextToken(); - SQLExpr rightExp = relational(); + for (;;) { + if (lexer.token() == Token.AND || lexer.token() == Token.AMPAMP) { + lexer.nextToken(); + SQLExpr rightExp = relational(); - expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.BooleanAnd, rightExp); - expr = andRest(expr); + expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.BooleanAnd, rightExp); + } else { + break; + } } return expr; @@ -800,18 +803,21 @@ public class SQLExprParser extends SQLParser { } public final SQLExpr orRest(SQLExpr expr) throws ParserException { - if (lexer.token() == Token.OR) { - lexer.nextToken(); - SQLExpr rightExp = and(); - expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.BooleanOr, rightExp); - expr = orRest(expr); - } else if (lexer.token() == Token.XOR) { - lexer.nextToken(); - SQLExpr rightExp = and(); + for (;;) { + if (lexer.token() == Token.OR) { + lexer.nextToken(); + SQLExpr rightExp = and(); - expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.BooleanXor, rightExp); - expr = orRest(expr); + expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.BooleanOr, rightExp); + } else if (lexer.token() == Token.XOR) { + lexer.nextToken(); + SQLExpr rightExp = and(); + + expr = new SQLBinaryOpExpr(expr, SQLBinaryOperator.BooleanXor, rightExp); + } else { + break; + } } return expr; diff --git a/src/test/java/com/alibaba/druid/sql/oracle/bvt/LargeOrTest.java b/src/test/java/com/alibaba/druid/sql/oracle/bvt/LargeOrTest.java new file mode 100644 index 0000000000..61cdfeb9ba --- /dev/null +++ b/src/test/java/com/alibaba/druid/sql/oracle/bvt/LargeOrTest.java @@ -0,0 +1,43 @@ +package com.alibaba.druid.sql.oracle.bvt; + +import junit.framework.Assert; +import junit.framework.TestCase; + +import com.alibaba.druid.sql.ast.expr.SQLBinaryOpExpr; +import com.alibaba.druid.sql.ast.expr.SQLBinaryOperator; +import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock; +import com.alibaba.druid.sql.ast.statement.SQLSelectStatement; +import com.alibaba.druid.sql.dialect.oracle.parser.OracleStatementParser; + +public class LargeOrTest extends TestCase { + + public void test_largeOr() throws Exception { + StringBuffer buf = new StringBuffer(); + buf.append("SELECT 1 FROM T WHERE ID = ?"); + for (int i = 0; i < 10000; ++i) { + buf.append(" OR ID = ?"); + } + String sql = buf.toString(); + OracleStatementParser parser = new OracleStatementParser(sql); + SQLSelectStatement stmt = (SQLSelectStatement) parser.parseStatementList().get(0); + SQLSelectQueryBlock select = (SQLSelectQueryBlock) stmt.getSelect().getQuery(); + SQLBinaryOpExpr where = (SQLBinaryOpExpr) select.getWhere(); + SQLBinaryOpExpr last = (SQLBinaryOpExpr) where.getRight(); + Assert.assertEquals(SQLBinaryOperator.Equality, last.getOperator()); + } + + public void test_largeAnd() throws Exception { + StringBuffer buf = new StringBuffer(); + buf.append("SELECT 1 FROM T WHERE ID = ?"); + for (int i = 0; i < 10000; ++i) { + buf.append(" AND ID = ?"); + } + String sql = buf.toString(); + OracleStatementParser parser = new OracleStatementParser(sql); + SQLSelectStatement stmt = (SQLSelectStatement) parser.parseStatementList().get(0); + SQLSelectQueryBlock select = (SQLSelectQueryBlock) stmt.getSelect().getQuery(); + SQLBinaryOpExpr where = (SQLBinaryOpExpr) select.getWhere(); + SQLBinaryOpExpr last = (SQLBinaryOpExpr) where.getRight(); + Assert.assertEquals(SQLBinaryOperator.Equality, last.getOperator()); + } +}