-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[plsql] Ampersand '&' causes PMD processing error in sql file - Lexical error in file #195
Comments
As far as I can tell, the variable substitution is a feature purely of SQL*Plus, and not part of the PL/SQL language, and running such code directly on the database server would produce a similar error. As such, it's technically correct for the violation being reported. Maybe we could allow such extensions by flagging some files as SQL*Plus... We would need to think this carefully though, SQL grammars vary wildly and this could open up way too many new issues / over complicate the grammar, plus we currently have no way of doing such flagging.... Maybe adding "sqlplus" as a "language version" for PLSQL? |
We often use lexical variables for defining the version number in a comment and in a constant. For example, our code looks like this:
or for types in a slightly different way:
The & inside the package comment does not cause any problems with PMD, but the comment inside the REM (SQL*Plus) comment causes the TokenMgrError. Of course, it is not easy for the parser to handle lexical variable references like this. This is even more true if one keeps in mind that the interpretation of the characters & and \ depends on the SQL*Plus settings SET DEFINE and SET ESCAPE. But is it perhaps possible to just ignore the & inside comments REM ... -- ... and /* ... */ ? |
Regarding the dependency of "" and "&" from the environment (e.g. the SQ*Plus settings for DEFINE and ESCAPE), I came to the conclusion that probably the best way to avoid problems with these characters is to run a pre-processor to before presenting the source to PMD. The pre-processor is probably out of the scope of PMD - or is there a standard way to pre-process file within PMD before presenting it to the parser? - I don't know, I'm a PMD noob.
The SPP maintains the following state:
This state is initialized with SQLPlus factory defaults for DEFINE and ESCAPE. The SPP processes file 1 (definitions.sql), then saves its state. Processing a file, the SPP scans the file line by line. When substituting lexical variables in the first step, this works the same as in SQL*Plus, including the special handling of a dot to terminate the variable name. If the preprocessor finds a &NAME at a given time when defineActive is set and NAME is not a key in d, it emits a warning (because this means that the SQL script is depending on unknown conditions) and produces the same output as if the variable is empty. The developer should then add a DEFINE NAME=somevalue to the defines.sql script. The only case (I think) where the behaviour of the SPP differs from SQLPlus is the command The SPP would solve the OP's problem with the start &filename.sql command and several of our problems (e.g. we use DEFINEs in some for our scripts to achieve the same effect as conditional compilation with $IF). However, a & in a comment is still valid and this is independent of whether DEFINE is ON or OFF. E.G. we have a & in our company name and thus the & is present in comments of the form
after pre-processing (the original line could be Flourish&Blotts with DEFINE ON and ESCAPE ). A side-effect of the SPP is that the columns in the pre-processed file may be different from the original file in those line that were actually modified by the SPP. However, this only matters if PMD finds errors in these lines, and I think that a developer should be clever enough to cope with this. |
Thanks for looking into this!
Yes, that's definitely the first step. As far as I see, we should already ignore "&" inside "/* .../" and "/** .../" and "-- single line" style comments. We also have obviously some minimal support for some? SQLPlus commands, e.g. we support "REMARK", but not "REM". I think, that should be not too difficult, to add support for "REM" additionally (the doc is here: https://docs.oracle.com/en/database/oracle/oracle-database/19/sqpug/REMARK.html#GUID-F4BF8426-AFE4-49C9-B073-57CB91B440F8). Your idea about the preprocessor is interesting. Currently this would be outside of PMD - that's not something we support at the moment. Maybe we can support something like this in the future (some kind of additional configurable processing stage before parsing). You also found the side-effect, which is my concern, when adding a preprocessor - PMD would report violations on the preprocessed files and not on the original files. Yes, developers should be able to trace that back to the original file, but computers might not be, e.g. if this is used in a automated CI tool (code climate, etc.). This effect needs to have some thought. Not sure, what the solution would be here. The preprocessed files could be published as well for the PMD report, or if the preprocessor stage is integrated in PMD, we might be able to keep a mapping between original locations and preprocessed locations. This mapping could be actually created by the preprocessor outside of PMD as well - then a postprocessor for the PMD report is needed to change the reported locations back to the original. |
When using PMD for [PLSQL] I am getting a Lexical error when parsing files with &.
Rule Set:
Description:
It seems to be caused by the ampersand, since if I remove it, the script is processed without issues.
I do, however need the ampersand for variable inclusion.
Several places on oracle.com this is being used:
https://blogs.oracle.com/opal/entry/sqlplus_101_substitution_varia#9_4
Code Sample demonstrating the issue:
Running PMD through:
CLI
Using this command
Gives this error
The text was updated successfully, but these errors were encountered: