felipebz / zpa

Parser and static code analysis tool for PL/SQL and Oracle SQL.
https://zpa.felipebz.com
GNU Lesser General Public License v3.0
211 stars 77 forks source link

Bad Message: Error -- even though it matches the expected message #178

Open csrvsk opened 7 months ago

csrvsk commented 7 months ago

Hi Filepe,

I am testing anew custom rule to check for CRETAE VIEW statements if it is not using OR REPLACE FORCE and report it as an issue with an error message.

Here is the error I am getting:

image

Here is my class,

import org.sonar.plugins.plsqlopen.api.annotations.Priority; import org.sonar.plugins.plsqlopen.api.annotations.Rule; import org.sonar.plugins.plsqlopen.api.annotations.ActivatedByDefault; import org.sonar.plugins.plsqlopen.api.checks.PlSqlCheck; import org.sonar.plugins.plsqlopen.api.sslr.AstNode; import org.sonar.plugins.plsqlopen.api.PlSqlGrammar; import java.util.logging.Logger;

@Rule( key = "CreateViewWithoutOrReplaceForce", name = "CREATE VIEW must include OR REPLACE FORCE", description = "Enforces the inclusion of OR REPLACE FORCE in CREATE VIEW statements.", priority = Priority.CRITICAL ) @ActivatedByDefault public class CreateOrReplaceForceViewCheck extends PlSqlCheck {

private static final Logger LOGGER = Logger.getLogger(CreateOrReplaceForceViewCheck.class.getName());

@Override
public void init() {
    subscribeTo(PlSqlGrammar.CREATE_VIEW);
    LOGGER.info("Subscribed to CREATE_VIEW nodes");
}

@Override
public void visitNode(AstNode node) {
    LOGGER.info("Visiting CREATE_VIEW node to check for OR REPLACE FORCE");

    boolean hasOrReplace = false;
    boolean hasForce = false;

    // Iterate over the children nodes to check for the OR REPLACE FORCE sequence
    for (AstNode child : node.getChildren()) {
        if ("OR".equals(child.getTokenValue()) && "REPLACE".equals(child.getNextSibling().getTokenValue())) {
            hasOrReplace = true;
        }
        if ("FORCE".equals(child.getTokenValue())) {
            hasForce = true;
        }
    }

    if (!hasOrReplace || !hasForce) {
        int lineNumber = node.getTokenLine();
        String message = String.format("CREATE VIEW statement missing 'OR REPLACE FORCE' clause at line %d.", lineNumber);
        LOGGER.warning(message);
        addIssue(node, message);
    }
}

}

here is my test sql file -- This is a compliant CREATE VIEW statement CREATE OR REPLACE FORCE VIEW valid_view AS SELECT employee_id, name, department FROM employee_table;

-- This is a non-compliant CREATE VIEW statement CREATE VIEW missing_or_replace_force AS -- Noncompliant {{CREATE VIEW statement missing 'OR REPLACE FORCE' clause at line #7.}} SELECT employee_id, name, department FROM employee_table;

-- Another non-compliant CREATE VIEW statement CREATE VIEW another_missing_clause AS -- Noncompliant {{CREATE VIEW statement missing 'OR REPLACE FORCE' clause at line #12.}} SELECT employee_id, name, department FROM employee_table;

-- This is compliant again CREATE OR REPLACE FORCE VIEW another_valid_view AS SELECT employee_id, name, department FROM employee_table;

please check and let me know what am I missing here.

Thanks csrvsk

felipebz commented 7 months ago

Hi,

It seems to be just a typo. The check register the text in the format "CREATE VIEW statement missing 'OR REPLACE FORCE' clause at line %d." but the text expects "CREATE VIEW statement missing 'OR REPLACE FORCE' clause at line #7" (notice the additional #).