Skip to content
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

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

Merged
merged 6 commits into from
Nov 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 36 additions & 24 deletions rules/S3618/plsql/rule.adoc
Original file line number Diff line number Diff line change
@@ -1,42 +1,54 @@
== 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]
----
INSERT INTO MY_TABLE -- Noncompliant; N2 value omitted
(
N1
)
VALUES
(
1
)
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
(
N1
)
VALUES
(
1
)
----

=== Compliant solution

[source,sql]
[source,sql,diff-id=1,diff-type=compliant]
----
INSERT INTO MY_TABLE -- Compliant even though N3 value not supplied
(
N1,
N2
)
VALUES
(
1,
'Paul'
)
INSERT INTO MY_TABLE -- Compliant; N3 has a default value
(
N1,
N2
)
VALUES
(
1,
'Paul'
)
----

ifdef::env-github,rspecator-view[]
Expand Down
15 changes: 0 additions & 15 deletions rules/S3641/compliant.adoc

This file was deleted.

30 changes: 30 additions & 0 deletions rules/S3641/how.adoc
Original file line number Diff line number Diff line change
@@ -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)
----
8 changes: 0 additions & 8 deletions rules/S3641/noncompliant.adoc

This file was deleted.

13 changes: 4 additions & 9 deletions rules/S3641/plsql/rule.adoc
Original file line number Diff line number Diff line change
@@ -1,17 +1,12 @@
== 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*

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[]
include::../how.adoc[]

ifdef::env-github,rspecator-view[]

Expand Down
4 changes: 1 addition & 3 deletions rules/S3641/tsql/rule.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -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.

include::../noncompliant.adoc[]

include::../compliant.adoc[]
include::../how.adoc[]

ifdef::env-github,rspecator-view[]

Expand Down
48 changes: 33 additions & 15 deletions rules/S3651/plsql/rule.adoc
Original file line number Diff line number Diff line change
@@ -1,27 +1,45 @@
== 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
Tim-Pohlmann marked this conversation as resolved.
Show resolved Hide resolved

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]
----
CREATE TABLE product
(id INT,
name VARCHAR(6) NOT NULL,
mfg_name VARCHAR(6),
mfg_id INT
...
SELECT name, price
FROM product
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
CREATE TABLE Product
(
Id INT,
Name VARCHAR(6),
Price INT NOT NULL
)
----


==== Noncompliant code example

[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[]
Expand Down
64 changes: 42 additions & 22 deletions rules/S3921/plsql/rule.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -2,41 +2,61 @@

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]
----
create table persons (id number, name varchar2(4));
== How to fix it

insert into persons (id, name) values (1, 'Alice'); -- Noncompliant, raises ORA-12899
Ensure that the size of the variable or column is large enough to hold the value.

create or replace procedure sp1
is
foo varchar2(2);
begin
select name into foo from persons where id = 1; -- Noncompliant, may raise ORA-06502
end;
----
=== Code examples

=== Compliant solution
==== Noncompliant code example

[source,sql]
[source,sql,diff-id=1,diff-type=noncompliant]
----
CREATE TABLE Persons
(
Id NUMBER,
Name VARCHAR2(4)
);
INSERT INTO Persons (Id, Name) VALUES (1, 'Alice'); -- Noncompliant, raises ORA-12899
CREATE OR REPLACE PROCEDURE sp1
IS
foo VARCHAR2(2);
BEGIN
SELECT Name INTO foo FROM Persons WHERE Id = 1; -- Noncompliant, may raise ORA-06502
END;
----
create table persons (id number, name varchar2(8));

insert into persons (id, name) values (1, 'Alice');
==== Compliant solution

create or replace procedure sp1
is
foo varchar2(8);
begin
select name into foo from persons where id = 1;
end;
[source,sql,diff-id=1,diff-type=compliant]
----
CREATE TABLE Persons
(
Id NUMBER,
Name VARCHAR2(8)
);
INSERT INTO Persons (Id, Name) VALUES (1, 'Alice');
CREATE OR REPLACE PROCEDURE sp1
IS
foo VARCHAR2(8);
BEGIN
SELECT Name INTO foo FROM Persons WHERE Id = 1;
END;
----

== Resources

=== Documentation

* 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[]
Expand Down
3 changes: 3 additions & 0 deletions shared_content/plsql/data_dictionary.adoc
Original file line number Diff line number Diff line change
@@ -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/