SONARPLSQL-805 S3921: Update RSPEC to mention data dictionary (#4544)
This commit is contained in:
parent
d04661341c
commit
0a7e283d1b
@ -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
|
||||||
|
@ -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
30
rules/S3641/how.adoc
Normal 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)
|
||||||
|
----
|
@ -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
|
|
||||||
----
|
|
@ -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[]
|
||||||
|
|
||||||
|
@ -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[]
|
||||||
|
|
||||||
|
@ -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[]
|
||||||
|
@ -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[]
|
||||||
|
3
shared_content/plsql/data_dictionary.adoc
Normal file
3
shared_content/plsql/data_dictionary.adoc
Normal 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/
|
Loading…
x
Reference in New Issue
Block a user