From 9c2ff432f248fea4447656eb7a704a5e6e9a9dfc Mon Sep 17 00:00:00 2001 From: Jeroen Castelein Date: Fri, 17 Feb 2017 13:02:26 +0100 Subject: [PATCH 1/3] Solves issue #200, the THENs and ELSEs can now also hold Regular/SQLConditions besides SimpleExpressions. Swap Regular and SQL Condition around in Condition(). --- .../net/sf/jsqlparser/parser/JSqlParserCC.jjt | 29 +++++++++++++++---- .../sf/jsqlparser/test/select/SelectTest.java | 8 +++++ 2 files changed, 31 insertions(+), 6 deletions(-) diff --git a/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt b/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt index 6175799a8..42e591ba9 100644 --- a/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt +++ b/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt @@ -1698,8 +1698,8 @@ Expression Condition(): Token token; } { - (LOOKAHEAD(SQLCondition()) result=SQLCondition() - | LOOKAHEAD(RegularCondition()) result=RegularCondition() + (LOOKAHEAD(RegularCondition()) result=RegularCondition() + | LOOKAHEAD(SQLCondition()) result=SQLCondition() | LOOKAHEAD(Function()) result=Function() | result=Column() { result = new NotExpression(result); } | result=Column() @@ -1783,6 +1783,7 @@ Expression SQLCondition(): | LOOKAHEAD(Between()) result=Between() | LOOKAHEAD(IsNullExpression()) result=IsNullExpression() | LOOKAHEAD(ExistsExpression()) result=ExistsExpression() + | LOOKAHEAD(CaseWhenExpression()) result = CaseWhenExpression() | result=LikeExpression() ) { return result; } @@ -2442,11 +2443,19 @@ Expression CaseWhenExpression() #CaseWhenExpression: ( ( clause=WhenThenSearchCondition() { whenClauses.add(clause); } )+ - [ elseExp=SimpleExpression()] + [ ( + LOOKAHEAD(RegularCondition()) elseExp=RegularCondition() + | LOOKAHEAD(SQLCondition()) elseExp=SQLCondition() + | elseExp=SimpleExpression() + )] | (LOOKAHEAD(RegularCondition()) switchExp=RegularCondition() | switchExp=BitwiseAndOr()) ( clause=WhenThenValue() { whenClauses.add(clause); } )+ - [ elseExp=SimpleExpression()] + [ ( + LOOKAHEAD(RegularCondition()) elseExp=RegularCondition() + | LOOKAHEAD(SQLCondition()) elseExp=SQLCondition() + | elseExp=SimpleExpression() + )] ) { @@ -2464,7 +2473,11 @@ WhenClause WhenThenSearchCondition(): Expression thenExp = null; } { - whenExp=Expression() thenExp=SimpleExpression() + whenExp=Expression() ( + LOOKAHEAD(RegularCondition()) thenExp=RegularCondition() + | LOOKAHEAD(SQLCondition()) thenExp=SQLCondition() + | thenExp=SimpleExpression() + ) { whenThen.setWhenExpression(whenExp); whenThen.setThenExpression(thenExp); @@ -2479,7 +2492,11 @@ WhenClause WhenThenValue(): Expression thenExp = null; } { - whenExp=PrimaryExpression() thenExp=SimpleExpression() + whenExp=PrimaryExpression() ( + LOOKAHEAD(RegularCondition()) thenExp=RegularCondition() + | LOOKAHEAD(SQLCondition()) thenExp=SQLCondition() + | thenExp=SimpleExpression() + ) { whenThen.setWhenExpression(whenExp); whenThen.setThenExpression(thenExp); diff --git a/src/test/java/net/sf/jsqlparser/test/select/SelectTest.java b/src/test/java/net/sf/jsqlparser/test/select/SelectTest.java index dea64478a..99e5c6d6a 100644 --- a/src/test/java/net/sf/jsqlparser/test/select/SelectTest.java +++ b/src/test/java/net/sf/jsqlparser/test/select/SelectTest.java @@ -2451,4 +2451,12 @@ public void testKeyWorkInsertIssue393() throws JSQLParserException { public void testKeyWorkReplaceIssue393() throws JSQLParserException { assertSqlCanBeParsedAndDeparsed("SELECT replace(\"aaaabbb\", 4, 4, \"****\")"); } + + public void testCaseExpressionAsConditionIssue200() throws JSQLParserException { + assertSqlCanBeParsedAndDeparsed("SELECT * FROM t1 WHERE CASE WHEN t1.a = 1 THEN t1.b = 2 ELSE t1.b = 3 END"); + } + + public void testCaseExpressionNestedConditionIssue200() throws JSQLParserException { + assertSqlCanBeParsedAndDeparsed("SELECT * FROM t1 WHERE CASE WHEN t1.a = 1 THEN CASE WHEN t1.b = 2 THEN t1.c = 3 ELSE t1.c = 5 END ELSE t1.b = 3 END"); + } } From 4c92e9305f010cd711dbf46d154bd56feecffb38 Mon Sep 17 00:00:00 2001 From: Jeroen Castelein Date: Fri, 17 Feb 2017 13:26:50 +0100 Subject: [PATCH 2/3] Redefine Expression to contain SimpleExpression, THENs and ELSEs also become Expressions. Add Columns to SimpleExpression. --- .../net/sf/jsqlparser/parser/JSqlParserCC.jjt | 31 +++++-------------- .../sf/jsqlparser/test/select/SelectTest.java | 13 +++----- 2 files changed, 12 insertions(+), 32 deletions(-) diff --git a/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt b/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt index 42e591ba9..79f4bd2e5 100644 --- a/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt +++ b/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt @@ -1701,9 +1701,8 @@ Expression Condition(): (LOOKAHEAD(RegularCondition()) result=RegularCondition() | LOOKAHEAD(SQLCondition()) result=SQLCondition() | LOOKAHEAD(Function()) result=Function() - | result=Column() { result = new NotExpression(result); } - | result=Column() - | LOOKAHEAD({ "0".equals(getToken(1).image) || "1".equals(getToken(1).image) }) token= { result = new LongValue(token.image); } + | result=SimpleExpression() { result = new NotExpression(result); } + | result=SimpleExpression() ) { return result; } @@ -2179,6 +2178,8 @@ Expression PrimaryExpression(): | "{ts" token= "}" { retval = new TimestampValue(token.image); } + | retval = Column() + | retval = IntervalExpression() ) @@ -2443,19 +2444,11 @@ Expression CaseWhenExpression() #CaseWhenExpression: ( ( clause=WhenThenSearchCondition() { whenClauses.add(clause); } )+ - [ ( - LOOKAHEAD(RegularCondition()) elseExp=RegularCondition() - | LOOKAHEAD(SQLCondition()) elseExp=SQLCondition() - | elseExp=SimpleExpression() - )] + [ elseExp=Expression()] | (LOOKAHEAD(RegularCondition()) switchExp=RegularCondition() | switchExp=BitwiseAndOr()) ( clause=WhenThenValue() { whenClauses.add(clause); } )+ - [ ( - LOOKAHEAD(RegularCondition()) elseExp=RegularCondition() - | LOOKAHEAD(SQLCondition()) elseExp=SQLCondition() - | elseExp=SimpleExpression() - )] + [ elseExp=Expression()] ) { @@ -2473,11 +2466,7 @@ WhenClause WhenThenSearchCondition(): Expression thenExp = null; } { - whenExp=Expression() ( - LOOKAHEAD(RegularCondition()) thenExp=RegularCondition() - | LOOKAHEAD(SQLCondition()) thenExp=SQLCondition() - | thenExp=SimpleExpression() - ) + whenExp=Expression() thenExp=Expression() { whenThen.setWhenExpression(whenExp); whenThen.setThenExpression(thenExp); @@ -2492,11 +2481,7 @@ WhenClause WhenThenValue(): Expression thenExp = null; } { - whenExp=PrimaryExpression() ( - LOOKAHEAD(RegularCondition()) thenExp=RegularCondition() - | LOOKAHEAD(SQLCondition()) thenExp=SQLCondition() - | thenExp=SimpleExpression() - ) + whenExp=PrimaryExpression() thenExp=Expression() { whenThen.setWhenExpression(whenExp); whenThen.setThenExpression(thenExp); diff --git a/src/test/java/net/sf/jsqlparser/test/select/SelectTest.java b/src/test/java/net/sf/jsqlparser/test/select/SelectTest.java index 99e5c6d6a..0954c7a5a 100644 --- a/src/test/java/net/sf/jsqlparser/test/select/SelectTest.java +++ b/src/test/java/net/sf/jsqlparser/test/select/SelectTest.java @@ -2318,15 +2318,6 @@ public void testWhereIssue240_0() throws JSQLParserException { assertSqlCanBeParsedAndDeparsed("SELECT count(*) FROM mytable WHERE 0"); } - public void testWhereIssue240_notBoolean() { - try { - CCJSqlParserUtil.parse("SELECT count(*) FROM mytable WHERE 5"); - fail("should not be parsed"); - } catch (JSQLParserException ex) { - - } - } - public void testWhereIssue240_true() throws JSQLParserException { assertSqlCanBeParsedAndDeparsed("SELECT count(*) FROM mytable WHERE true"); } @@ -2459,4 +2450,8 @@ public void testCaseExpressionAsConditionIssue200() throws JSQLParserException { public void testCaseExpressionNestedConditionIssue200() throws JSQLParserException { assertSqlCanBeParsedAndDeparsed("SELECT * FROM t1 WHERE CASE WHEN t1.a = 1 THEN CASE WHEN t1.b = 2 THEN t1.c = 3 ELSE t1.c = 5 END ELSE t1.b = 3 END"); } + + public void testCaseExpressionHoldsAndIssue200() throws JSQLParserException { + assertSqlCanBeParsedAndDeparsed("SELECT * FROM t1 WHERE CASE WHEN t1.a = 1 THEN '2017-02-27' NOT IN ('2017-02-19', '2017-02-26', '2017-02-12', '2017-02-05') AND '2017-02-27' BETWEEN to_date AND from_date END"); + } } From a990675ba5ddcd7de4eee75897c2d6601973c575 Mon Sep 17 00:00:00 2001 From: Jeroen Castelein Date: Fri, 17 Feb 2017 13:37:16 +0100 Subject: [PATCH 3/3] Add test --- src/test/java/net/sf/jsqlparser/test/select/SelectTest.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/test/java/net/sf/jsqlparser/test/select/SelectTest.java b/src/test/java/net/sf/jsqlparser/test/select/SelectTest.java index 0954c7a5a..fdedba020 100644 --- a/src/test/java/net/sf/jsqlparser/test/select/SelectTest.java +++ b/src/test/java/net/sf/jsqlparser/test/select/SelectTest.java @@ -2454,4 +2454,8 @@ public void testCaseExpressionNestedConditionIssue200() throws JSQLParserExcepti public void testCaseExpressionHoldsAndIssue200() throws JSQLParserException { assertSqlCanBeParsedAndDeparsed("SELECT * FROM t1 WHERE CASE WHEN t1.a = 1 THEN '2017-02-27' NOT IN ('2017-02-19', '2017-02-26', '2017-02-12', '2017-02-05') AND '2017-02-27' BETWEEN to_date AND from_date END"); } + + public void testCaseExpressionWithMoreCondsIssue200() throws JSQLParserException { + assertSqlCanBeParsedAndDeparsed("SELECT * FROM t1 WHERE t2.name = t1.leave_type AND t2.is_lwp = 1 AND t1.docstatus = 1 AND t1.employee = 'EMP-0001' AND CASE WHEN t1.a = 1 THEN '2017-02-27' NOT IN ('2017-02-19', '2017-02-26', '2017-02-12', '2017-02-05') AND '2017-02-27' BETWEEN to_date AND from_date WHEN t2.include_holiday THEN '2017-02-27' BETWEEN from_date AND to_date END"); + } }