Treat unquotable identifiers as unquoted in PLSQL

This commit is contained in:
Clément Fournier
2024-04-21 12:53:50 +02:00
parent b56925f419
commit f4e75410f8
7 changed files with 104 additions and 18 deletions

View File

@ -5222,21 +5222,14 @@ TOKEN :
"\\"
>
|
< #ID_SIMPLE: ("$" | ":" | <LETTER>) ( <LETTER> | <DIGIT> | "$" | "_" | "#" )* >
|
< IDENTIFIER:
( ("$" | ":" | <LETTER>) ( <LETTER> | <DIGIT> | "$" | "_" | "#" )* ) // 2006-05-17 - Matthias Hendler - Bind variablen werden nun als Identifier akzeptiert.
//SRT Does NOT seem to like identifiers 2 or fewer characters( <LETTER> ( <LETTER> ) )
//( <LETTER> ( <DIGIT> ) )
//( <LETTER> ( "$" ) )
//( <LETTER> ( "_" ) )
//( <LETTER> ( "#" ) )
<ID_SIMPLE>
|
(
<LEXICAL_PARAMETER> ( <LETTER> | <DIGIT> | "$" | "_" | "#" )*
)
( <LEXICAL_PARAMETER> ( <LETTER> | <DIGIT> | "$" | "_" | "#" )* )
|
( (<LETTER> | "$" ) ( <LETTER> | <DIGIT> | "$" | "_" | "#" )* )
|
( "\"" <LETTER> ( <LETTER> | <DIGIT> | "$" | "_" | "#" )* "\"" )
( "\"" <ID_SIMPLE> "\"" )
>
|
< #LEXICAL_PARAMETER:

View File

@ -12,6 +12,7 @@ import net.sourceforge.pmd.lang.LanguagePropertyBundle;
import net.sourceforge.pmd.lang.TokenManager;
import net.sourceforge.pmd.lang.ast.impl.javacc.CharStream;
import net.sourceforge.pmd.lang.ast.impl.javacc.JavaccToken;
import net.sourceforge.pmd.lang.document.Chars;
import net.sourceforge.pmd.lang.document.TextDocument;
import net.sourceforge.pmd.lang.plsql.ast.PLSQLTokenKinds;
@ -36,7 +37,7 @@ public class PLSQLCpdLexer extends JavaccCpdLexer {
@Override
protected String getImage(JavaccToken plsqlToken) {
String image = plsqlToken.getImage();
String image;
if (ignoreIdentifiers && plsqlToken.kind == PLSQLTokenKinds.IDENTIFIER) {
image = "<identifier>";
@ -51,6 +52,15 @@ public class PLSQLCpdLexer extends JavaccCpdLexer {
} else if (plsqlToken.kind != PLSQLTokenKinds.CHARACTER_LITERAL
&& plsqlToken.kind != PLSQLTokenKinds.STRING_LITERAL
&& plsqlToken.kind != PLSQLTokenKinds.QUOTED_LITERAL) {
Chars imageCs = plsqlToken.getImageCs();
if (plsqlToken.kind == PLSQLTokenKinds.IDENTIFIER && imageCs.charAt(0) == '"') {
// remove quotes to make identical to bare ID
image = imageCs.substring(1, imageCs.length() - 1);
} else {
image = plsqlToken.getImage();
}
// PLSQL is case-insensitive, but the contents of
// string literals and the like are case-sensitive.
// Note: tokens are normalized to uppercase make CPD case-insensitive.
@ -58,6 +68,9 @@ public class PLSQLCpdLexer extends JavaccCpdLexer {
// will be returned unchanged (they are already uppercase, see PLSQLParser),
// therefore creating fewer strings in memory.
image = image.toUpperCase(Locale.ROOT);
} else {
image = plsqlToken.getImage();
}
return image;
}

View File

@ -32,6 +32,11 @@ class PLSQLCpdLexerTest extends CpdTextComparisonTest {
doTest("tabWidth");
}
@Test
void testIdentifiers() {
doTest("identifiers");
}
@Test
void anonymizeLiterals() {
doTest("sample-plsql", "_ignore-literals", ignoreLiterals());

View File

@ -0,0 +1,13 @@
DECLARE
qty_on_hand NUMBER(5);
BEGIN
SELECT quantity INTO qty_on_hand FROM inventory
WHERE product = 'TENNIS RACKET' -- product gets uppercased
AND "Product" = 'tennis racket' -- "Product" gets uppercased and quotes removed
AND Product = 'tennis racket' -- Product gets uppercased
AND "Product info" = 'tennis ' -- "Product info" stays the same
AND "an_id" = 'foo' -- an_id gets uppercased
AND " not an id" = 'foo' -- " not an id" stays the same
FOR UPDATE OF quantity;
COMMIT;
END;

View File

@ -0,0 +1,62 @@
[Image] or [Truncated image[ Bcol Ecol
L1
[DECLARE] 1 8
L2
[QTY_ON_HAND] 2 13
[NUMBER] 14 20
[(] 20 21
[5] 21 22
[)] 22 23
[;] 23 24
L3
[BEGIN] 1 6
L4
[SELECT] 2 8
[QUANTITY] 9 17
[INTO] 18 22
[QTY_ON_HAND] 23 34
[FROM] 35 39
[INVENTORY] 40 49
L5
[WHERE] 3 8
[PRODUCT] 9 16
[=] 17 18
['TENNIS RACKET'] 19 34
L6
[AND] 5 8
[PRODUCT] 9 18
[=] 19 20
['tennis racket'] 21 36
L7
[AND] 11 14
[PRODUCT] 15 22
[=] 23 24
['tennis racket'] 25 40
L8
[AND] 11 14
["Product info"] 15 29
[=] 30 31
['tennis '] 32 41
L9
[AND] 11 14
[AN_ID] 15 22
[=] 23 24
['foo'] 25 30
L10
[AND] 11 14
[" not an id"] 15 27
[=] 28 29
['foo'] 30 35
L11
[FOR] 3 6
[UPDATE] 7 13
[OF] 14 16
[QUANTITY] 17 25
[;] 25 26
L12
[COMMIT] 2 8
[;] 8 9
L13
[END] 1 4
[;] 4 5
EOF

View File

@ -5,9 +5,9 @@ L1
[REPLACE] 11 18
L2
[PACKAGE] 1 8
["TEST_SCHEMA"] 9 22
[TEST_SCHEMA] 9 22
[.] 22 23
["BANK_DATA"] 23 34
[BANK_DATA] 23 34
L3
[IS] 1 3
L19

View File

@ -5,9 +5,9 @@ L1
[REPLACE] 11 18
L2
[PACKAGE] 1 8
["TEST_SCHEMA"] 9 22
[TEST_SCHEMA] 9 22
[.] 22 23
["BANK_DATA"] 23 34
[BANK_DATA] 23 34
L3
[IS] 1 3
L19