You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/customRulesSetup.md
+9-6Lines changed: 9 additions & 6 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,14 +1,15 @@
1
1
# Wiki #
2
2
## Custom rules ##
3
-
Currently, plugin supports ability to match code against custom rules defined in xml files with specific format. Below are the details how to start using and creating custom rules.
3
+
Currently, plugin supports ability to match code against custom rules defined in xml files in specific format. Below are the details how to use and create custom rules.
4
4
5
5
6
6
### Usage ###
7
-
8
-
- Create an xml file with custom rules defined, there is an [example file](https://github.com/gretard/sonar-sql-plugin/blob/master/examples/1-tsql/myExampleRepo.customRules). Each file defines a single repository.
9
-
- Put custom file into your base directory of the project or you can specify absolute path to the file.
7
+
To get started using custom rules:
8
+
- Create an xml file with custom rules defined. There is an [example project](https://github.com/gretard/sonar-sql-plugin/blob/master/examples/6-pssql-with-custom-rules). Each xml file defines a single rule repository. You can try scanning example project first.
9
+
- Put custom file into your base directory of the project or you can specify relative/absolute path to the file by setting _sonar.sql.rules.path_ property. You can check _sonar-project.properties_ file for further reference at the [example project](https://github.com/gretard/sonar-sql-plugin/blob/master/examples/6-pssql-with-custom-rules)
10
10
- Run sonar scanner
11
11
12
+
> Please check sections below for information on how custom rules are defined.
12
13
13
14
14
15
### Creating custom rules ###
@@ -64,10 +65,12 @@ Mandatory fields for rule:
64
65
- More - checks if node's distance to parent node is more than expected value
65
66
- Less - checks if node's distance to parent node is less than expected value
66
67
- Equals - checks if node's distance to parent node is equal to the expected value
68
+
- ruleAppliesTo - can be code or comments
69
+
- ruleReportsOn - can be line or file. If file is selected - then violation will be reported once.
67
70
68
71
Schema can be found at [/sonar-sql-plugin/src/main/resources/schemas/customRules.xsd](https://github.com/gretard/sonar-sql-plugin/blob/master/src/sonar-sql-plugin/src/main/resources/schemas/customRules.xsd).
69
72
70
-
Below is an example of an xml file contents for with rules:
73
+
Below is an example of an xml file contents with rules:
2. As rule mode is set to *SINGLE* and *FailIfFound* - all nodes are checked if any of the nodes contain child where its text value is equal to * as text check mode is set to *Strict*. Then such nodes are reported as having issues. If mode would be set to *Contains*, then statements such as *SELECT 1 * 3* would be reported as well.
315
318
316
-
### Creating more complex custom rule with distance ###
319
+
### Creating more complex custom rule with distance checks###
317
320
318
321
For example, if you wanted to create a rule requiring that each SELECT statement ends with semicolon, you could use the following definition:
SLEEP/WAITFOR is used<h2>Code examples</h2><h3>Non-compliant</h3><pre><code>WAITFOR '10:00:00';</code></pre>
4
4
5
5
## C002 - SELECT * is used
6
-
<p>Supported dialects: MYSQL,TSQL</p>
6
+
<p>Supported dialects: MYSQL,PSSQLV2,TSQL</p>
7
7
<h2>Description</h2><p>SELECT * is used. Please list names.</p><h2>Code examples</h2><h3>Non-compliant</h3><pre><code>SELECT t1.*, t2.* from dbo.test as t1 inner join dbo.test2 as t2 on t1.id=t2.id;</code></pre><h3>Compliant</h3><pre><code>SELECT name, surname from dbo.test;</code></pre><pre><code>SELECT name, surname, 1 * 3 from dbo.test;</code></pre>
8
8
9
9
## C003 - INSERT statement without columns listed
10
-
<p>Supported dialects: MYSQL,TSQL</p>
11
-
<h2>Description</h2><p>INSERT statement does not have columns listed. Always use a column list in your INSERT statements.</p><h2>Code examples</h2><h3>Non-compliant</h3><pre><code>INSERT INTO dbo.test VALUES (1,2);</code></pre><h3>Compliant</h3><pre><code>INSERT INTO dbo.test (a,b) VALUES (1,2);</code></pre>
10
+
<p>Supported dialects: MYSQL,PSSQLV2,TSQL</p>
11
+
<h2>Description</h2><p>INSERT statement does not have columns listed. Always use a column list in your INSERT statements.</p><h2>Code examples</h2><h3>Non-compliant</h3><pre><code>INSERT INTO dbo.test VALUES (1,2);
12
+
INSERT INTO dbo.test2 VALUES (1,2);</code></pre><h3>Compliant</h3><pre><code>INSERT INTO dbo.test (a,b) VALUES (1,2);</code></pre>
12
13
13
14
## C004 - ORDER BY clause contains positional references
<h2>Description</h2><p>Do not use column numbers in the ORDER BY clause. Always use column names in an order by clause. Avoid positional references.</p><h2>Code examples</h2><h3>Non-compliant</h3><pre><code>SELECT * from dbo.test order by 1, 2;</code></pre><h3>Compliant</h3><pre><code>SELECT * from dbo.test order by name;</code></pre>
16
17
17
18
## C005 - EXECUTE/EXEC for dynamic query is used
@@ -23,7 +24,7 @@ SLEEP/WAITFOR is used<h2>Code examples</h2><h3>Non-compliant</h3><pre><code>WAIT
23
24
<h2>Description</h2><p>Use of NOLOCK might cause data inconsistency problems.</p><h2>Code examples</h2><h3>Non-compliant</h3><pre><code>SELECT name, surname from dbo.test WITH (NOLOCK);</code></pre><h3>Compliant</h3><pre><code>SELECT name, surname from dbo.test;</code></pre>
<h2>Description</h2><p>Use of non-sargeable arguments might cause performance problems.</p><h2>Code examples</h2><h3>Non-compliant</h3><pre><code>SELECT name, surname from dbo.test where year(date) > 2008 and month = 12;</code></pre><pre><code>SELECT name, surname from dbo.test where name like '%red' </code></pre><h3>Compliant</h3><pre><code>SELECT MAX(RateChangeDate) FROM HumanResources.EmployeePayHistory WHERE BusinessEntityID = 1</code></pre><pre><code>SELECT name, surname from dbo.test where date between 2008-10-10 and 2010-10-10;</code></pre><pre><code>SELECT max(price) from dbo.items;</code></pre>
28
29
29
30
## C010 - Defined primary key is not using recommended naming convention
@@ -43,26 +44,41 @@ PRIMARY KEY (Id)
43
44
<h2>Description</h2><p>Defined foreign key is not using recommended naming convention to start with FK_.</p><h2>Code examples</h2><h3>Non-compliant</h3><pre><code>ALTER TABLE dbo.Orders ADD CONSTRAINT ClientId FOREIGN KEY (ClientId) REFERENCES dbo.Clients(Id); </code></pre><h3>Compliant</h3><pre><code>ALTER TABLE dbo.Orders ADD CONSTRAINT FK_ClientId FOREIGN KEY (ClientId) REFERENCES dbo.Clients(Id); </code></pre>
44
45
45
46
## C012 - Comparison operator (=, <>, !=) to check if value is null used
<h2>Description</h2><p>It is not advisable to use comparison operator to check if value is null as comparison operators return UNKNOWN when either or both arguments are NULL. Please use IS NULL or IS NOT NULL instead.</p><h2>Code examples</h2><h3>Non-compliant</h3><pre><code>SELECT * from dbo.test where name = null and surname = 'Test' ;</code></pre><pre><code>SELECT * from dbo.test where name != null;</code></pre><pre><code>SELECT * from dbo.test where name <> null;</code></pre><h3>Compliant</h3><pre><code>SELECT * from dbo.test where name IS NULL;</code></pre><pre><code>SELECT * from dbo.test where name IS NOT NULL;</code></pre><pre><code>SELECT * from dbo.test where name = 'test';</code></pre>
48
49
49
50
## C013 - Defined index name is not using recommended naming convention
50
51
<p>Supported dialects: TSQL</p>
51
52
<h2>Description</h2><p>Defined index name is not using recommended naming convention to start with IX_.</p><h2>Code examples</h2><h3>Non-compliant</h3><pre><code>CREATE UNIQUE INDEX Test_Name on dbo.test (Name);</code></pre><h3>Compliant</h3><pre><code>CREATE UNIQUE INDEX IX_Test_Name on dbo.test (Name);</code></pre>
<h2>Description</h2><p>It is advisable to consider using UNION/UNION ALL operator instead of OR verb in the WHERE clause.</p><h2>Code examples</h2><h3>Non-compliant</h3><pre><code>SELECT name, surname, count from dbo.test where name = 'Test' OR surname = 'Testor';</code></pre><h3>Compliant</h3><pre><code>SELECT name, surname, count from dbo.test where name = 'or' and surname = 'TestOR';</code></pre>
<h2>Description</h2><p>It is advisable to consider using UNION ALL operator instead of UNION.</p><h2>Code examples</h2><h3>Non-compliant</h3><pre><code>SELECT name, surname, count from dbo.test union SELECT name, surname, count from dbo.test2;</code></pre><h3>Compliant</h3><pre><code>SELECT name, surname, count from dbo.test union all SELECT name, surname, count from dbo.test2;</code></pre>
<h2>Description</h2><p>Consider using EXISTS/NOT EXISTS operator instead of IN for a subquery.</p><h2>Code examples</h2><h3>Non-compliant</h3><pre><code>SELECT name, surname, count from dbo.test where locationID in (select id from dbo.locations);</code></pre><h3>Compliant</h3><pre><code>SELECT name, surname, count from dbo.test where locationID in (1,2,3);</code></pre><pre><code>SELECT name, surname, count from dbo.test where exists (select 1 from dbo.locations where id = locationID);</code></pre>
64
65
65
66
## C017 - ORDER BY clause does not contain order (ASC/DESC)
<h2>Description</h2><p>It is advisable to specidy order how rows should be ordered.</p><h2>Code examples</h2><h3>Non-compliant</h3><pre><code>SELECT name, surname from dbo.test order by name, surname asc;</code></pre><h3>Compliant</h3><pre><code>SELECT name, surname from dbo.test order by name desc, surname asc;</code></pre>
68
69
70
+
## C020 - HINT is used
71
+
<p>Supported dialects: VSQL</p>
72
+
HINT is used. Consider rewriting this statement.<h2>Code examples</h2><h3>Non-compliant</h3><pre><code>SELECT /*+DIRECT*/ * FROM test_table1;</code></pre><pre><code>CREATE TABLE test_table2 AS SELECT /*+DIRECT*/ * FROM test_table1;</code></pre><h3>Compliant</h3><pre><code>SELECT * FROM test_table1;</code></pre>
73
+
74
+
## C021 - COMMIT is missing
75
+
<p>Supported dialects: VSQL</p>
76
+
COMMIT is missing after UPDATE/DELETE statement. If you run script without autocommit - your changes might be lost.<h2>Code examples</h2><h3>Non-compliant</h3><pre><code>SELECT 1; DELETE FROM temp1; SELECT 2;</code></pre><pre><code>COMMIT; DELETE FROM temp1;</code></pre><h3>Compliant</h3><pre><code>SELECT 1; DELETE FROM temp1; COMMIT; SELECT 2; </code></pre>
77
+
78
+
## C030 - File does not start with multiline/header comment
79
+
<p>Supported dialects: null</p>
80
+
File does not start with multiline/header comment.<h2>Code examples</h2><h3>Non-compliant</h3><pre><code>SELECT * FROM test_table1;</code></pre><pre><code>SELECT * FROM test_table1; /*additionalComment*/ </code></pre><h3>Compliant</h3><pre><code>/* AUTHOR: test
0 commit comments