From 06eb3e24ebef27b231cf6caa240cc5e235f649ad Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 24 Jan 2019 18:53:14 +0100 Subject: [PATCH] [plsql] Parse Exception with EXISTS Fixes #1587 --- docs/pages/release_notes.md | 2 ++ pmd-plsql/etc/grammar/PldocAST.jjt | 12 +++++++++- .../plsql/ast/PLSQLParserVisitorAdapter.java | 5 ++++ .../lang/plsql/rule/AbstractPLSQLRule.java | 5 ++++ .../pmd/lang/plsql/ast/WhereClauseTest.java | 7 ++++++ .../pmd/lang/plsql/ast/WhereClauseExists.pls | 24 +++++++++++++++++++ 6 files changed, 54 insertions(+), 1 deletion(-) create mode 100644 pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/WhereClauseExists.pls diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index ee410dcd04..51de4955c2 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -37,6 +37,8 @@ This is a {{ site.pmd.release_type }} release. * [#1633](https://github.com/pmd/pmd/issues/1633): \[java] UnsynchronizedStaticFormatter reports commons lang FastDateFormat * java-performance * [#1632](https://github.com/pmd/pmd/issues/1632): \[java] ConsecutiveLiteralAppends false positive over catch +* plsql + * [#1587](https://github.com/pmd/pmd/issues/1587): \[plsql] Parse Exception with EXISTS ### API Changes diff --git a/pmd-plsql/etc/grammar/PldocAST.jjt b/pmd-plsql/etc/grammar/PldocAST.jjt index f08f27c0cc..97d3b6e4c4 100644 --- a/pmd-plsql/etc/grammar/PldocAST.jjt +++ b/pmd-plsql/etc/grammar/PldocAST.jjt @@ -1314,6 +1314,8 @@ void Condition2() #void : LOOKAHEAD(4) IsNullCondition() | LOOKAHEAD(4) IsOfTypeCondition() + | + ExistsCondition() ) } @@ -1338,6 +1340,14 @@ ASTLikeCondition LikeCondition() : { return jjtThis; } } +ASTExistsCondition ExistsCondition() : +{} +{ + "(" Subquery() ")" + + { return jjtThis; } +} + ASTCompoundCondition CompoundCondition() : {} { @@ -5848,7 +5858,7 @@ ASTID ID(): {} | //SYNTAX | //SYNTAX //RESERVED WORD | //SYNTAX - | //SYNTAX //RESERVED WORD + //| //SYNTAX //RESERVED WORD //| //SYNTAX //20120501 | | //SYNTAX diff --git a/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/ast/PLSQLParserVisitorAdapter.java b/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/ast/PLSQLParserVisitorAdapter.java index 9d86b884b8..82887774e0 100644 --- a/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/ast/PLSQLParserVisitorAdapter.java +++ b/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/ast/PLSQLParserVisitorAdapter.java @@ -986,4 +986,9 @@ public class PLSQLParserVisitorAdapter implements PLSQLParserVisitor { public Object visit(ASTValuesClause node, Object data) { return visit((PLSQLNode) node, data); } + + @Override + public Object visit(ASTExistsCondition node, Object data) { + return visit((PLSQLNode) node, data); + } } diff --git a/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/rule/AbstractPLSQLRule.java b/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/rule/AbstractPLSQLRule.java index f43818e62d..2bbc0f5b03 100644 --- a/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/rule/AbstractPLSQLRule.java +++ b/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/rule/AbstractPLSQLRule.java @@ -1080,6 +1080,11 @@ public abstract class AbstractPLSQLRule extends AbstractRule implements PLSQLPar return visit((PLSQLNode) node, data); } + @Override + public Object visit(ASTExistsCondition node, Object data) { + return visit((PLSQLNode) node, data); + } + /* * Treat all Executable Code */ diff --git a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/WhereClauseTest.java b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/WhereClauseTest.java index 18d549472a..7524bcea6f 100644 --- a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/WhereClauseTest.java +++ b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/WhereClauseTest.java @@ -68,4 +68,11 @@ public class WhereClauseTest extends AbstractPLSQLParserTst { StandardCharsets.UTF_8); ASTInput input = parsePLSQL(code); } + + @Test + public void testExistsCondition() throws Exception { + String code = IOUtils.toString(this.getClass().getResourceAsStream("WhereClauseExists.pls"), + StandardCharsets.UTF_8); + ASTInput input = parsePLSQL(code); + } } diff --git a/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/WhereClauseExists.pls b/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/WhereClauseExists.pls new file mode 100644 index 0000000000..e300dfb7a0 --- /dev/null +++ b/pmd-plsql/src/test/resources/net/sourceforge/pmd/lang/plsql/ast/WhereClauseExists.pls @@ -0,0 +1,24 @@ +-- +-- Where Clause With Exists Condition +-- https://docs.oracle.com/en/database/oracle/oracle-database/18/sqlrf/EXISTS-Condition.html#GUID-20259A83-C42B-4E0D-8DF4-9A2A66ACA8E7 +-- + +BEGIN + +SELECT id + INTO id_out + FROM some_table + WHERE EXISTS + (SELECT NULL + FROM other_table + WHERE other_id = other_id_in); + +DELETE FROM some_table + WHERE id = id_in + AND NOT EXISTS + (SELECT NULL + FROM other_table + WHERE id = id_in); + +END; +/