SONARPLSQL-805 S3921: Update RSPEC to mention data dictionary (#4544)

This commit is contained in:
Sebastien Marichal 2024-11-27 14:11:29 +01:00 committed by GitHub
parent d04661341c
commit 0a7e283d1b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 146 additions and 93 deletions

View File

@ -1,18 +1,30 @@
== Why is this an issue? == Why is this an issue?
Any insert which omits a value for a ``++NOT NULL++`` column in a database table will be automatically rejected by the database unless a default value has been specified for the column. Any insert which omits a value for a `NOT NULL` column in a database table will be automatically rejected by the database unless a default value has been specified for the column.
include::../../../shared_content/plsql/data_dictionary.adoc[]
*Noteworthy* == How to fix it
This rule raises issues only when a *Data Dictionary* is provided during the analysis. See https://docs.sonarqube.org/latest/analysis/languages/plsql/ Ensure that all `NOT NULL` columns have a value specified in the `INSERT` statement.
=== Noncompliant code example === Code examples
With the table ``++MY_TABLE++`` having a ``++NOT NULL++`` column ``++N2++`` without default value and a ``++NOT NULL++`` column ``++N3++`` with default value: Given the following table:
[source,sql] [source,sql]
---- ----
CREATE TABLE MY_TABLE (
N1 NUMBER NOT NULL,
N2 VARCHAR2(50) NOT NULL,
N3 VARCHAR2(50) DEFAULT 'Default Value'
);
----
==== Noncompliant code example
[source,sql,diff-id=1,diff-type=noncompliant]
----
INSERT INTO MY_TABLE -- Noncompliant; N2 value omitted INSERT INTO MY_TABLE -- Noncompliant; N2 value omitted
( (
N1 N1
@ -25,9 +37,9 @@ With the table ``++MY_TABLE++`` having a ``++NOT NULL++`` column ``++N2++`` with
=== Compliant solution === Compliant solution
[source,sql] [source,sql,diff-id=1,diff-type=compliant]
---- ----
INSERT INTO MY_TABLE -- Compliant even though N3 value not supplied INSERT INTO MY_TABLE -- Compliant; N3 has a default value
( (
N1, N1,
N2 N2

View File

@ -1,15 +0,0 @@
=== Compliant solution
[source,text]
----
SELECT *
FROM my_table
WHERE NOT EXISTS (SELECT 1 FROM another_table WHERE nullable_column = my_table.my_column)
----
[source,text]
----
SELECT *
FROM my_table
WHERE my_column NOT IN (SELECT nullable_column FROM another_table WHERE nullable_column IS NOT NULL)
----

30
rules/S3641/how.adoc Normal file
View File

@ -0,0 +1,30 @@
== How to fix it
Use `NOT EXISTS` or `IS NOT NULL` instead of `NOT IN` when the subquery may return `NULL` values.
=== Code examples
==== Noncompliant code example
[source,sql]
----
SELECT *
FROM my_table
WHERE my_column NOT IN (SELECT nullable_column FROM another_table) -- Noncompliant; "nullable_column" may contain 'NULL' value and the whole SELECT query will return nothing
----
==== Compliant solution
[source,sql]
----
SELECT *
FROM my_table
WHERE NOT EXISTS (SELECT 1 FROM another_table WHERE nullable_column = my_table.my_column)
----
[source,sql]
----
SELECT *
FROM my_table
WHERE my_column NOT IN (SELECT nullable_column FROM another_table WHERE nullable_column IS NOT NULL)
----

View File

@ -1,8 +0,0 @@
=== Noncompliant code example
[source,text]
----
SELECT *
FROM my_table
WHERE my_column NOT IN (SELECT nullable_column FROM another_table) -- Noncompliant; "nullable_column" may contain 'NULL' value and the whole SELECT query will return nothing
----

View File

@ -1,17 +1,12 @@
== Why is this an issue? == Why is this an issue?
A WHERE clause condition that uses NOT IN with a subquery will have unexpected results if that subquery returns NULL. On the other hand NOT EXISTS subqueries work reliably under the same conditions. A `WHERE` clause condition that uses `NOT IN` with a subquery will have unexpected results if that subquery returns `NULL`. On the other hand `NOT EXISTS` subqueries work reliably under the same conditions.
This rule raises an issue when NOT IN is used with a subquery where the selected column is nullable. This rule raises an issue when `NOT IN` is used with a subquery where the selected column is nullable.
include::../../../shared_content/plsql/data_dictionary.adoc[]
*Noteworthy* include::../how.adoc[]
This rule raises issues only when a *Data Dictionary* is provided during the analysis. See https://docs.sonarqube.org/latest/analysis/languages/plsql/
include::../noncompliant.adoc[]
include::../compliant.adoc[]
ifdef::env-github,rspecator-view[] ifdef::env-github,rspecator-view[]

View File

@ -5,9 +5,7 @@ A ``++WHERE++`` clause condition that uses ``++NOT IN++`` with a subquery will h
This rule raises an issue when ``++NOT IN++`` is used with a subquery. This rule doesn't check if the selected column is a nullable column because the rules engine has no information about the table definition. It's up to the developer to review manually if the column is nullable. This rule raises an issue when ``++NOT IN++`` is used with a subquery. This rule doesn't check if the selected column is a nullable column because the rules engine has no information about the table definition. It's up to the developer to review manually if the column is nullable.
include::../noncompliant.adoc[] include::../how.adoc[]
include::../compliant.adoc[]
ifdef::env-github,rspecator-view[] ifdef::env-github,rspecator-view[]

View File

@ -1,27 +1,45 @@
== Why is this an issue? == Why is this an issue?
``++WHERE++`` clause conditions that reinforce or contradict the definitions of their columns are useless; they are always either unconditionally true or unconditionally false. For instance, there's no point in including ``++AND column IS NOT NULL++`` if the column is defined as non-null. Conditions in the `WHERE` clause that either reinforce or contradict the definitions of their columns are redundant, as they are always either unconditionally true or unconditionally false. For example, including `AND column IS NOT NULL` is unnecessary if the column is already defined as non-null.
include::../../../shared_content/plsql/data_dictionary.adoc[]
*Noteworthy* == How to fix it
This rule raises issues only when a *Data Dictionary* is provided during the analysis. See https://docs.sonarqube.org/latest/analysis/languages/plsql/ Ensure that the conditions in the `WHERE` clause are not always true or false.
=== Noncompliant code example === Code examples
Given the following table:
[source,sql] [source,sql]
---- ----
CREATE TABLE product CREATE TABLE Product
(id INT, (
name VARCHAR(6) NOT NULL, Id INT,
mfg_name VARCHAR(6), Name VARCHAR(6),
mfg_id INT Price INT NOT NULL
... )
----
SELECT name, price
FROM product ==== Noncompliant code example
WHERE name is not null -- Noncompliant; always true. This column is NOT NULL
AND mfg_name = 'Too long name' -- Noncompliant; always false. This column can contain only 6 characters [source,sql,diff-id=1,diff-type=noncompliant]
----
SELECT Name, Price FROM Product
WHERE
Name = 'Too long name' -- Noncompliant; always false. This column can contain only 6 characters
AND Price IS NOT NULL -- Noncompliant; always true. This column is NOT NULL
----
==== Compliant solution
[source,sql,diff-id=1,diff-type=compliant]
----
SELECT Name, Price FROM Product
WHERE
Name = 'Name'
---- ----
ifdef::env-github,rspecator-view[] ifdef::env-github,rspecator-view[]

View File

@ -2,41 +2,61 @@
Trying to assign a large character value to a smaller variable or column will raise an error. Trying to assign a large character value to a smaller variable or column will raise an error.
=== Noncompliant code example include::../../../shared_content/plsql/data_dictionary.adoc[]
[source,sql] == How to fix it
Ensure that the size of the variable or column is large enough to hold the value.
=== Code examples
==== Noncompliant code example
[source,sql,diff-id=1,diff-type=noncompliant]
---- ----
create table persons (id number, name varchar2(4)); CREATE TABLE Persons
(
Id NUMBER,
Name VARCHAR2(4)
);
insert into persons (id, name) values (1, 'Alice'); -- Noncompliant, raises ORA-12899 INSERT INTO Persons (Id, Name) VALUES (1, 'Alice'); -- Noncompliant, raises ORA-12899
create or replace procedure sp1 CREATE OR REPLACE PROCEDURE sp1
is IS
foo varchar2(2); foo VARCHAR2(2);
begin BEGIN
select name into foo from persons where id = 1; -- Noncompliant, may raise ORA-06502 SELECT Name INTO foo FROM Persons WHERE Id = 1; -- Noncompliant, may raise ORA-06502
end; END;
---- ----
=== Compliant solution ==== Compliant solution
[source,sql] [source,sql,diff-id=1,diff-type=compliant]
---- ----
create table persons (id number, name varchar2(8)); CREATE TABLE Persons
(
Id NUMBER,
Name VARCHAR2(8)
);
insert into persons (id, name) values (1, 'Alice'); INSERT INTO Persons (Id, Name) VALUES (1, 'Alice');
create or replace procedure sp1 CREATE OR REPLACE PROCEDURE sp1
is IS
foo varchar2(8); foo VARCHAR2(8);
begin BEGIN
select name into foo from persons where id = 1; SELECT Name INTO foo FROM Persons WHERE Id = 1;
end; END;
---- ----
== Resources == Resources
=== Documentation
* CWE - https://cwe.mitre.org/data/definitions/704[CWE-704 - Incorrect Type Conversion or Cast] * CWE - https://cwe.mitre.org/data/definitions/704[CWE-704 - Incorrect Type Conversion or Cast]
* Oracle Database - https://docs.oracle.com/en/error-help/db/ora-12899[ORA-12899]
* Oracle Database - https://docs.oracle.com/en/error-help/db/ora-06502[ORA-06502]
ifdef::env-github,rspecator-view[] ifdef::env-github,rspecator-view[]

View File

@ -0,0 +1,3 @@
=== Noteworthy
This rule raises issues only when a *Data Dictionary* is provided during the analysis. See{nbsp}https://docs.sonarqube.org/latest/analysis/languages/plsql/