Skip to content

Commit 24a9337

Browse files
authored
Ignore unique constraint on drop constraint (#161)
Ignore rule failures on `DROP CONSTRAINT...` for _disallowed-unique-constraint_ and _adding-serial-primary-key-field_. When running `squawk` against the recommended usage, ``` CREATE UNIQUE INDEX CONCURRENTLY dist_id_temp_idx ON distributors (dist_id); ALTER TABLE distributors DROP CONSTRAINT distributors_pkey, ADD CONSTRAINT distributors_pkey PRIMARY KEY USING INDEX dist_id_temp_idx; ``` we still get a warning.
1 parent dda7ae7 commit 24a9337

7 files changed

+49
-61
lines changed

linter/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ lazy_static! {
188188
func: prefer_robust_stmts,
189189
messages: vec![
190190
ViolationMessage::Help(
191-
"Consider wrapping in a transaction or adding a IF NOT EXISTS clause if the statment supports it.".into()
191+
"Consider wrapping in a transaction or adding a IF NOT EXISTS clause if the statement supports it.".into()
192192
),
193193
]
194194
},

linter/src/rules/adding_primary_key_constraint.rs

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::violations::{RuleViolation, RuleViolationKind};
22
use squawk_parser::ast::{
3-
AlterTableCmds, AlterTableDef, ColumnDefConstraint, ConstrType, RootStmt, Stmt,
3+
AlterTableCmds, AlterTableDef, AlterTableType, ColumnDefConstraint, ConstrType, RootStmt, Stmt,
44
};
55

66
#[must_use]
@@ -10,10 +10,26 @@ pub fn adding_primary_key_constraint(tree: &[RootStmt]) -> Vec<RuleViolation> {
1010
match &raw_stmt.stmt {
1111
Stmt::AlterTableStmt(stmt) => {
1212
for AlterTableCmds::AlterTableCmd(cmd) in &stmt.cmds {
13-
match &cmd.def {
14-
Some(AlterTableDef::ColumnDef(def)) => {
13+
match (&cmd.def, &cmd.subtype) {
14+
(
15+
Some(AlterTableDef::Constraint(constraint)),
16+
AlterTableType::AddConstraint,
17+
) => {
18+
if constraint.contype == ConstrType::Primary
19+
&& constraint.indexname.is_none()
20+
{
21+
errs.push(RuleViolation::new(
22+
RuleViolationKind::AddingSerialPrimaryKeyField,
23+
raw_stmt.into(),
24+
None,
25+
));
26+
}
27+
}
28+
(Some(AlterTableDef::ColumnDef(def)), _) => {
1529
for ColumnDefConstraint::Constraint(constraint) in &def.constraints {
16-
if constraint.contype == ConstrType::Primary {
30+
if constraint.contype == ConstrType::Primary
31+
&& constraint.indexname.is_none()
32+
{
1733
errs.push(RuleViolation::new(
1834
RuleViolationKind::AddingSerialPrimaryKeyField,
1935
raw_stmt.into(),
@@ -22,15 +38,6 @@ pub fn adding_primary_key_constraint(tree: &[RootStmt]) -> Vec<RuleViolation> {
2238
}
2339
}
2440
}
25-
Some(AlterTableDef::Constraint(constraint)) => {
26-
if constraint.contype == ConstrType::Primary {
27-
errs.push(RuleViolation::new(
28-
RuleViolationKind::AddingSerialPrimaryKeyField,
29-
raw_stmt.into(),
30-
None,
31-
));
32-
}
33-
}
3441
_ => continue,
3542
}
3643
}

linter/src/rules/disallow_unique_constraint.rs

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
use crate::rules::utils::tables_created_in_transaction;
22
use crate::violations::{RuleViolation, RuleViolationKind};
3-
use squawk_parser::ast::{AlterTableCmds, AlterTableDef, ConstrType, RelationKind, RootStmt, Stmt};
3+
use squawk_parser::ast::{
4+
AlterTableCmds, AlterTableDef, AlterTableType, ConstrType, RelationKind, RootStmt, Stmt,
5+
};
46

57
#[must_use]
68
pub fn disallow_unique_constraint(tree: &[RootStmt]) -> Vec<RuleViolation> {
@@ -12,8 +14,11 @@ pub fn disallow_unique_constraint(tree: &[RootStmt]) -> Vec<RuleViolation> {
1214
let RelationKind::RangeVar(range) = &stmt.relation;
1315
let tbl_name = &range.relname;
1416
for AlterTableCmds::AlterTableCmd(cmd) in &stmt.cmds {
15-
match &cmd.def {
16-
Some(AlterTableDef::Constraint(constraint)) => {
17+
match (&cmd.def, &cmd.subtype) {
18+
(
19+
Some(AlterTableDef::Constraint(constraint)),
20+
AlterTableType::AddConstraint,
21+
) => {
1722
if !tables_created.contains(tbl_name)
1823
&& constraint.contype == ConstrType::Unique
1924
&& constraint.indexname.is_none()
@@ -54,6 +59,10 @@ mod test_rules {
5459
fn test_adding_unique_constraint() {
5560
let bad_sql = r#"
5661
ALTER TABLE table_name ADD CONSTRAINT field_name_constraint UNIQUE (field_name);
62+
"#;
63+
64+
let ignored_sql = r#"
65+
ALTER TABLE table_name DROP CONSTRAINT field_name_constraint;
5766
"#;
5867

5968
let ok_sql = r#"
@@ -63,15 +72,16 @@ ADD CONSTRAINT distributors_pkey PRIMARY KEY USING INDEX dist_id_temp_idx;
6372
"#;
6473

6574
assert_debug_snapshot!(check_sql(bad_sql, &["prefer-robust-stmts".into()]));
75+
assert_debug_snapshot!(check_sql(ignored_sql, &["prefer-robust-stmts".into()]));
6676
assert_debug_snapshot!(check_sql(ok_sql, &["prefer-robust-stmts".into()]));
6777
}
6878

69-
/// Creating a UNQIUE constraint from an existing index should be considered
79+
/// Creating a UNIQUE constraint from an existing index should be considered
7080
/// safe
7181
#[test]
7282
fn test_unique_constraint_ok() {
7383
let sql = r#"
74-
CREATE UNIQUE INDEX CONCURRENTLY "legacy_questiongrouppg_mongo_id_1f8f47d9_uniq_idx"
84+
CREATE UNIQUE INDEX CONCURRENTLY "legacy_questiongrouppg_mongo_id_1f8f47d9_uniq_idx"
7585
ON "legacy_questiongrouppg" ("mongo_id");
7686
ALTER TABLE "legacy_questiongrouppg" ADD CONSTRAINT "legacy_questiongrouppg_mongo_id_1f8f47d9_uniq" UNIQUE USING INDEX "legacy_questiongrouppg_mongo_id_1f8f47d9_uniq_idx";
7787
"#;

linter/src/rules/prefer_robust_stmts.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ ALTER TABLE "core_foo" ADD COLUMN "answer_id" integer NULL;
216216
},
217217
messages: [
218218
Help(
219-
"Consider wrapping in a transaction or adding a IF NOT EXISTS clause if the statment supports it.",
219+
"Consider wrapping in a transaction or adding a IF NOT EXISTS clause if the statement supports it.",
220220
),
221221
],
222222
},
@@ -240,7 +240,7 @@ CREATE INDEX CONCURRENTLY "core_foo_idx" ON "core_foo" ("answer_id");
240240
},
241241
messages: [
242242
Help(
243-
"Consider wrapping in a transaction or adding a IF NOT EXISTS clause if the statment supports it.",
243+
"Consider wrapping in a transaction or adding a IF NOT EXISTS clause if the statement supports it.",
244244
),
245245
],
246246
},
@@ -264,7 +264,7 @@ CREATE TABLE "core_bar" ( "id" serial NOT NULL PRIMARY KEY, "bravo" text NOT NUL
264264
},
265265
messages: [
266266
Help(
267-
"Consider wrapping in a transaction or adding a IF NOT EXISTS clause if the statment supports it.",
267+
"Consider wrapping in a transaction or adding a IF NOT EXISTS clause if the statement supports it.",
268268
),
269269
],
270270
},
@@ -288,7 +288,7 @@ ALTER TABLE "core_foo" DROP CONSTRAINT "core_foo_idx";
288288
},
289289
messages: [
290290
Help(
291-
"Consider wrapping in a transaction or adding a IF NOT EXISTS clause if the statment supports it.",
291+
"Consider wrapping in a transaction or adding a IF NOT EXISTS clause if the statement supports it.",
292292
),
293293
],
294294
},

linter/src/rules/snapshots/squawk_linter__rules__adding_primary_key_constraint__test_rules__plain_primary_key-2.snap

Lines changed: 1 addition & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3,23 +3,5 @@ source: linter/src/rules/adding_primary_key_constraint.rs
33
expression: "check_sql(ok_sql, &[\"prefer-robust-stmts\".into()])"
44
---
55
Ok(
6-
[
7-
RuleViolation {
8-
kind: AddingSerialPrimaryKeyField,
9-
span: Span {
10-
start: 0,
11-
len: Some(
12-
75,
13-
),
14-
},
15-
messages: [
16-
Note(
17-
"Adding a PRIMARY KEY constraint results in locks and table rewrites",
18-
),
19-
Help(
20-
"Add the PRIMARY KEY constraint USING an index.",
21-
),
22-
],
23-
},
24-
],
6+
[],
257
)

linter/src/rules/snapshots/squawk_linter__rules__disallow_unique_constraint__test_rules__adding_unique_constraint-2.snap

Lines changed: 1 addition & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3,23 +3,5 @@ source: linter/src/rules/disallow_unique_constraint.rs
33
expression: "check_sql(ok_sql, &[\"prefer-robust-stmts\".into()])"
44
---
55
Ok(
6-
[
7-
RuleViolation {
8-
kind: AddingSerialPrimaryKeyField,
9-
span: Span {
10-
start: 77,
11-
len: Some(
12-
134,
13-
),
14-
},
15-
messages: [
16-
Note(
17-
"Adding a PRIMARY KEY constraint results in locks and table rewrites",
18-
),
19-
Help(
20-
"Add the PRIMARY KEY constraint USING an index.",
21-
),
22-
],
23-
},
24-
],
6+
[],
257
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
source: linter/src/rules/disallow_unique_constraint.rs
3+
expression: "check_sql(ignored_sql, &[\"prefer-robust-stmts\".into()])"
4+
---
5+
Ok(
6+
[],
7+
)

0 commit comments

Comments
 (0)