Merge pull request #1616 from adangel/issue-1588

[plsql] Parse Exception with function calls in WHERE clause
This commit is contained in:
Juan Martín Sotuyo Dodero
2019-01-26 19:26:24 -03:00
committed by GitHub
4 changed files with 39 additions and 4 deletions

View File

@ -83,6 +83,7 @@ This is a {{ site.pmd.release_type }} release.
* [#1511](https://github.com/pmd/pmd/issues/1511): \[plsql] Parse Exception with IS NOT NULL * [#1511](https://github.com/pmd/pmd/issues/1511): \[plsql] Parse Exception with IS NOT NULL
* [#1583](https://github.com/pmd/pmd/issues/1583): \[plsql] Update Set Clause should allow multiple columns * [#1583](https://github.com/pmd/pmd/issues/1583): \[plsql] Update Set Clause should allow multiple columns
* [#1586](https://github.com/pmd/pmd/issues/1586): \[plsql] Parse Exception when functions are used with LIKE * [#1586](https://github.com/pmd/pmd/issues/1586): \[plsql] Parse Exception when functions are used with LIKE
* [#1588](https://github.com/pmd/pmd/issues/1588): \[plsql] Parse Exception with function calls in WHERE clause
### API Changes ### API Changes

View File

@ -1414,16 +1414,38 @@ ASTSqlExpression SqlExpression() :
| |
LOOKAHEAD(2) <ROWNUM> LOOKAHEAD(2) <ROWNUM>
| |
LOOKAHEAD(2) AdditiveExpression() // this can be a literal or a simple expression, but no conditional AdditiveExpression() // this can be a literal or a simple expression, but no conditional
) )
{ return jjtThis; } { return jjtThis; }
} }
/**
* 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 .
*/
ASTFunctionCall FunctionCall() : ASTFunctionCall FunctionCall() :
{ ASTID id; }
{ {
id = ID() { jjtThis.setImage(id.getImage()); } Arguments() ASTID id;
{ return jjtThis; } 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()); } ]
Arguments()
{
jjtThis.setImage(name.toString());
return jjtThis;
}
} }
ASTColumn Column() : ASTColumn Column() :

View File

@ -5,8 +5,10 @@
package net.sourceforge.pmd.lang.plsql.ast; package net.sourceforge.pmd.lang.plsql.ast;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.List;
import org.apache.commons.io.IOUtils; import org.apache.commons.io.IOUtils;
import org.junit.Assert;
import org.junit.Test; import org.junit.Test;
import net.sourceforge.pmd.lang.plsql.AbstractPLSQLParserTst; import net.sourceforge.pmd.lang.plsql.AbstractPLSQLParserTst;
@ -18,6 +20,11 @@ public class WhereClauseTest extends AbstractPLSQLParserTst {
String code = IOUtils.toString(this.getClass().getResourceAsStream("WhereClauseFunctionCall.pls"), String code = IOUtils.toString(this.getClass().getResourceAsStream("WhereClauseFunctionCall.pls"),
StandardCharsets.UTF_8); StandardCharsets.UTF_8);
ASTInput input = parsePLSQL(code); ASTInput input = parsePLSQL(code);
List<ASTSelectIntoStatement> selectStatements = input.findDescendantsOfType(ASTSelectIntoStatement.class);
Assert.assertEquals(3, selectStatements.size());
ASTFunctionCall functionCall = selectStatements.get(2).getFirstDescendantOfType(ASTFunctionCall.class);
Assert.assertEquals("utils.get_colname", functionCall.getImage());
} }
@Test @Test

View File

@ -16,5 +16,10 @@ BEGIN
OR rgn.cny_code = street_cny_code_in) OR rgn.cny_code = street_cny_code_in)
AND UPPER(rgn.name) = UPPER(street_rgn_in); AND UPPER(rgn.name) = UPPER(street_rgn_in);
SELECT value
INTO v_value
FROM table
WHERE colname = utils.get_colname('COLUMN_ID');
END; END;
/ /