From 50d211eae49479015dc93be959efb8949d97ffeb Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Sat, 20 Jul 2019 17:32:31 +0200 Subject: [PATCH] [plsql] Introduce new node OuterJoinExpression --- pmd-plsql/etc/grammar/PldocAST.jjt | 17 +++++++++-- pmd-plsql/src/main/ant/alljavacc.xml | 1 - .../lang/plsql/ast/ASTSimpleExpression.java | 30 ------------------- .../plsql/ast/PLSQLParserVisitorAdapter.java | 5 ++++ .../lang/plsql/rule/AbstractPLSQLRule.java | 5 ++++ .../pmd/lang/plsql/ast/JoinClauseTest.java | 13 ++------ 6 files changed, 28 insertions(+), 43 deletions(-) delete mode 100644 pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/ast/ASTSimpleExpression.java diff --git a/pmd-plsql/etc/grammar/PldocAST.jjt b/pmd-plsql/etc/grammar/PldocAST.jjt index 88686f7b8f..6f3477722a 100644 --- a/pmd-plsql/etc/grammar/PldocAST.jjt +++ b/pmd-plsql/etc/grammar/PldocAST.jjt @@ -1556,13 +1556,26 @@ ASTSimpleExpression SimpleExpression() : LOOKAHEAD(2) ( "*" | Column() ) { sb.append(token.image); } ) - [LOOKAHEAD(3) "(" "+" ")" {jjtThis.setJoinOperator(true);} ] // JoinOperator { jjtThis.setImage(sb.toString()); return jjtThis; } } +ASTOuterJoinExpression OuterJoinExpression() : +{ StringBuilder sb = new StringBuilder(); } +{ + [ LOOKAHEAD(6) SchemaName() { sb.append(token.image); } "." { sb.append(token.image); } ] + [ LOOKAHEAD(4) TableName() { sb.append(token.image); } "." { sb.append(token.image); } ] + Column() { sb.append(token.image); } + "(" "+" ")" + + { + jjtThis.setImage(sb.toString()); + return jjtThis; + } +} + /** * Built-in function call or a user defined function call. * See https://docs.oracle.com/en/database/oracle/oracle-database/18/sqlrf/Functions.html#GUID-D079EFD3-C683-441F-977E-2C9503089982 @@ -3259,7 +3272,7 @@ ASTPrimaryPrefix PrimaryPrefix() : } { ( - LOOKAHEAD(ID() ("." ID())* "(" "+" ")") ( simpleNode = SimpleExpression() ) { sb.append(simpleNode.getImage()); } + LOOKAHEAD(OuterJoinExpression()) ( simpleNode = OuterJoinExpression() ) { sb.append(simpleNode.getImage()); } // Note: AnalyticClause and WithinClause are only allowed for specific functions, but this grammar allows it for all functions. | LOOKAHEAD(FunctionName() "(") ( simpleNode = FunctionCall() [ AnalyticClause() ] [ WithinClause() ] ) { sb.append(simpleNode.getImage()); } | LOOKAHEAD(MultiSetCondition()) simpleNode = MultiSetCondition() diff --git a/pmd-plsql/src/main/ant/alljavacc.xml b/pmd-plsql/src/main/ant/alljavacc.xml index 26b272ac49..d22c66587a 100644 --- a/pmd-plsql/src/main/ant/alljavacc.xml +++ b/pmd-plsql/src/main/ant/alljavacc.xml @@ -67,7 +67,6 @@ - diff --git a/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/ast/ASTSimpleExpression.java b/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/ast/ASTSimpleExpression.java deleted file mode 100644 index 497492e916..0000000000 --- a/pmd-plsql/src/main/java/net/sourceforge/pmd/lang/plsql/ast/ASTSimpleExpression.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * BSD-style license; for more info see http://pmd.sourceforge.net/license.html - */ - -package net.sourceforge.pmd.lang.plsql.ast; - -public class ASTSimpleExpression extends AbstractPLSQLNode { - private boolean joinOperator; - - ASTSimpleExpression(int id) { - super(id); - } - - ASTSimpleExpression(PLSQLParser p, int id) { - super(p, id); - } - - @Override - public Object jjtAccept(PLSQLParserVisitor visitor, Object data) { - return visitor.visit(this, data); - } - - void setJoinOperator(boolean joinOperator) { - this.joinOperator = joinOperator; - } - - public boolean hasJoinOperator() { - return joinOperator; - } -} 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 675d444b83..e70249f69d 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 @@ -1106,4 +1106,9 @@ public class PLSQLParserVisitorAdapter implements PLSQLParserVisitor { public Object visit(ASTXMLElement node, Object data) { return visit((PLSQLNode) node, data); } + + @Override + public Object visit(ASTOuterJoinExpression 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 7da4036f88..018dfb81f2 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 @@ -1200,6 +1200,11 @@ public abstract class AbstractPLSQLRule extends AbstractRule implements PLSQLPar return visit((PLSQLNode) node, data); } + @Override + public Object visit(ASTOuterJoinExpression 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/JoinClauseTest.java b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/JoinClauseTest.java index 5033394e47..a15ceaa7dd 100644 --- a/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/JoinClauseTest.java +++ b/pmd-plsql/src/test/java/net/sourceforge/pmd/lang/plsql/ast/JoinClauseTest.java @@ -5,7 +5,6 @@ package net.sourceforge.pmd.lang.plsql.ast; import java.nio.charset.StandardCharsets; -import java.util.ArrayList; import java.util.List; import org.apache.commons.io.IOUtils; @@ -136,14 +135,8 @@ public class JoinClauseTest extends AbstractPLSQLParserTst { String code = IOUtils.toString(this.getClass().getResourceAsStream("JoinOperator.pls"), StandardCharsets.UTF_8); ASTInput input = parsePLSQL(code); - List expressions = input.findDescendantsOfType(ASTSimpleExpression.class); - List expressionsWithJoinOperator = new ArrayList(); - for (ASTSimpleExpression exp : expressions) { - if (exp.hasJoinOperator()) { - expressionsWithJoinOperator.add(exp); - } - } - Assert.assertEquals(4, expressionsWithJoinOperator.size()); - Assert.assertEquals("h.opp_id", expressionsWithJoinOperator.get(3).getImage()); + List expressions = input.findDescendantsOfType(ASTOuterJoinExpression.class); + Assert.assertEquals(4, expressions.size()); + Assert.assertEquals("h.opp_id", expressions.get(3).getImage()); } }