From adfc8511e64ac5c8d277d1812de65ed43d8732cd Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Sat, 9 Feb 2019 22:51:33 +0100 Subject: [PATCH] [plsql] FunctionCall is now used again for user defined functions --- pmd-plsql/etc/grammar/PldocAST.jjt | 46 +++++++++++++------ .../plsql/ast/PLSQLParserVisitorAdapter.java | 5 ++ .../lang/plsql/rule/AbstractPLSQLRule.java | 5 ++ .../pmd/lang/plsql/ast/WhereClauseTest.java | 7 ++- 4 files changed, 44 insertions(+), 19 deletions(-) diff --git a/pmd-plsql/etc/grammar/PldocAST.jjt b/pmd-plsql/etc/grammar/PldocAST.jjt index 91d39a0938..2a308d2d6c 100644 --- a/pmd-plsql/etc/grammar/PldocAST.jjt +++ b/pmd-plsql/etc/grammar/PldocAST.jjt @@ -1421,19 +1421,44 @@ ASTSqlExpression SqlExpression() : } /** - * Built-in function call + * 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 + * See https://docs.oracle.com/en/database/oracle/oracle-database/18/sqlrf/About-User-Defined-Functions.html#GUID-4EB3E236-8216-471C-BA44-23D87BDFEA67 + * + * A function reference/name might be: + * function_name + * package.function_name + * package.schema.function_name + * optional: @ dblink + * */ ASTFunctionCall FunctionCall() : { - ASTID id; + ASTFunctionName name; } { - id = ID() + name = FunctionName() Arguments() { - jjtThis.setImage(id.getImage()); + jjtThis.setImage(name.getImage()); + return jjtThis; + } +} + +ASTFunctionName FunctionName() : +{ + ASTID id; + StringBuilder name = new StringBuilder(); +} +{ + id = ID() { name.append(id.getImage()); } + [ "." id = ID() { name.append('.').append(id.getImage()); } + [ "." id = ID() { name.append('.').append(id.getImage()); } ] + ] + [ "@" id = ID() { name.append('@').append(id.getImage()); } ] + { + jjtThis.setImage(name.toString()); return jjtThis; } } @@ -2797,14 +2822,6 @@ ASTIsOfTypeCondition IsOfTypeCondition() #IsOfTypeCondition(>1) : * 2006-05-23 - Matthias Hendler - Added lookahead otherwise warning encountered. * Warning arised while adding methode triggerUnit(). * 2011-04-27 - SRT - Add optional NEW Keyword to cope with Object Type constructors - * - * See also https://docs.oracle.com/en/database/oracle/oracle-database/18/sqlrf/About-User-Defined-Functions.html#GUID-4EB3E236-8216-471C-BA44-23D87BDFEA67 - * - * A function reference might be: - * function_name - * package.function_name - * package.schema.function_name - * optional: @ dblink . */ ASTPrimaryExpression PrimaryExpression() #PrimaryExpression(>1) : { Token thisToken ; PLSQLNode simpleNode = null; StringBuilder sb = new StringBuilder() ; @@ -2835,9 +2852,8 @@ ASTPrimaryPrefix PrimaryPrefix() : } { ( - LOOKAHEAD(2) ( - LOOKAHEAD(2) simpleNode = FunctionCall() -| LOOKAHEAD(2) simpleNode = Literal() ) { sb.append(simpleNode.getImage()) ; } + LOOKAHEAD(FunctionName() "(") simpleNode = FunctionCall() +| LOOKAHEAD(Literal()) simpleNode = Literal() { sb.append(simpleNode.getImage()) ; } | LOOKAHEAD(MultiSetCondition()) simpleNode = MultiSetCondition() | LOOKAHEAD(TrimExpression()) simpleNode = TrimExpression() //SRT 20110613.3 | LOOKAHEAD(CaseExpression()) ( simpleNode =CaseExpression() ) { sb.append(simpleNode.getImage()) ; } //SRT 20110520 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 6cfacdb9b3..8d98a27d55 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 @@ -991,4 +991,9 @@ public class PLSQLParserVisitorAdapter implements PLSQLParserVisitor { public Object visit(ASTHierarchicalQueryClause node, Object data) { return visit((PLSQLNode) node, data); } + + @Override + public Object visit(ASTFunctionName 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 28a593edac..1161473e1b 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 @@ -1085,6 +1085,11 @@ public abstract class AbstractPLSQLRule extends AbstractRule implements PLSQLPar return visit((PLSQLNode) node, data); } + @Override + public Object visit(ASTFunctionName 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 7edba49d3b..717637f721 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 @@ -25,10 +25,9 @@ public class WhereClauseTest extends AbstractPLSQLParserTst { ASTFunctionCall functionCall = selectStatements.get(0).getFirstDescendantOfType(ASTFunctionCall.class); Assert.assertEquals("UPPER", functionCall.getImage()); - - ASTPrimaryPrefix primaryPrefix = selectStatements.get(2).getFirstDescendantOfType(ASTWhereClause.class) - .findDescendantsOfType(ASTPrimaryPrefix.class).get(1); - Assert.assertEquals("utils.get_colname", primaryPrefix.getImage()); + + ASTFunctionCall functionCall2 = selectStatements.get(2).getFirstDescendantOfType(ASTFunctionCall.class); + Assert.assertEquals("utils.get_colname", functionCall2.getImage()); } @Test