Skip to content

Commit f6f54d0

Browse files
authored
add new "ban-drop-column" rule (#132)
fixes #128
1 parent 6fecfd1 commit f6f54d0

File tree

8 files changed

+112
-4
lines changed

8 files changed

+112
-4
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1212
- link to website for tty reporter when there are lint errors. (#120)
1313
- `DROP INDEX` support for "require-concurrent-index-creation" and "prefer-robust-stmts". (#124)
1414
- github comment now includes Squawk's version number. (#131)
15+
- new `ban-drop-column` rule (#132)
1516

1617
### Changed
1718

docs/docs/ban-drop-column.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
id: ban-drop-column
3+
title: ban-drop-column
4+
---
5+
6+
Dropping a column may break existing clients.

linter/src/lib.rs

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,10 @@ extern crate lazy_static;
99
use crate::errors::CheckSQLError;
1010
use crate::rules::{
1111
adding_field_with_default, adding_foreign_key_constraint, adding_not_nullable_field,
12-
adding_primary_key_constraint, ban_char_type, ban_drop_database, changing_column_type,
13-
constraint_missing_not_valid, disallow_unique_constraint, prefer_robust_stmts,
14-
prefer_text_field, renaming_column, renaming_table, require_concurrent_index_creation,
12+
adding_primary_key_constraint, ban_char_type, ban_drop_column, ban_drop_database,
13+
changing_column_type, constraint_missing_not_valid, disallow_unique_constraint,
14+
prefer_robust_stmts, prefer_text_field, renaming_column, renaming_table,
15+
require_concurrent_index_creation,
1516
};
1617
use crate::violations::{RuleViolation, RuleViolationKind, ViolationMessage};
1718
use squawk_parser::ast::RootStmt;
@@ -92,6 +93,16 @@ lazy_static! {
9293
),
9394
]
9495
},
96+
SquawkRule {
97+
id: "ban-drop-column".into(),
98+
name: RuleViolationKind::BanDropColumn,
99+
func: ban_drop_column,
100+
messages: vec![
101+
ViolationMessage::Note(
102+
"Dropping a column may break existing clients.".into()
103+
),
104+
],
105+
},
95106
SquawkRule {
96107
id: "ban-drop-database".into(),
97108
name: RuleViolationKind::BanDropDatabase,
@@ -234,7 +245,7 @@ lazy_static! {
234245
"Create the index CONCURRENTLY.".into()
235246
),
236247
],
237-
},
248+
}
238249
];
239250

240251
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
use crate::violations::{RuleViolation, RuleViolationKind};
2+
use squawk_parser::ast::{AlterTableCmds, AlterTableType, ObjectType, RootStmt, Stmt};
3+
4+
#[must_use]
5+
pub fn ban_drop_column(tree: &[RootStmt]) -> Vec<RuleViolation> {
6+
let mut errs = vec![];
7+
for RootStmt::RawStmt(raw_stmt) in tree {
8+
match &raw_stmt.stmt {
9+
Stmt::RenameStmt(stmt) => match stmt.rename_type {
10+
ObjectType::Table => {
11+
errs.push(RuleViolation::new(
12+
RuleViolationKind::RenamingTable,
13+
raw_stmt.into(),
14+
None,
15+
));
16+
}
17+
_ => continue,
18+
},
19+
Stmt::AlterTableStmt(stmt) => {
20+
for cmd in &stmt.cmds {
21+
if let AlterTableCmds::AlterTableCmd(cmd) = cmd {
22+
if cmd.subtype == AlterTableType::DropColumn {
23+
errs.push(RuleViolation::new(
24+
RuleViolationKind::BanDropColumn,
25+
raw_stmt.into(),
26+
None,
27+
))
28+
}
29+
}
30+
}
31+
}
32+
_ => continue,
33+
}
34+
}
35+
errs
36+
}
37+
38+
#[cfg(test)]
39+
mod test_rules {
40+
use crate::check_sql;
41+
use insta::assert_debug_snapshot;
42+
43+
#[test]
44+
fn test_drop_column() {
45+
let sql = r#"
46+
ALTER TABLE "bar_tbl" DROP COLUMN "foo_col" CASCADE;
47+
"#;
48+
49+
assert_debug_snapshot!(check_sql(sql, &["prefer-robust-stmts".into()]));
50+
}
51+
}

linter/src/rules/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ pub mod renaming_column;
2020
pub use renaming_column::*;
2121
pub mod renaming_table;
2222
pub use renaming_table::*;
23+
pub mod ban_drop_column;
24+
pub use ban_drop_column::*;
2325
pub mod require_concurrent_index_creation;
2426
pub use require_concurrent_index_creation::*;
2527
pub mod ban_char_field;
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
---
2+
source: linter/src/rules/ban_drop_column.rs
3+
expression: "check_sql(sql, &[\"prefer-robust-stmts\".into()])"
4+
---
5+
Ok(
6+
[
7+
RuleViolation {
8+
kind: BanDropColumn,
9+
span: Span {
10+
start: 0,
11+
len: Some(
12+
52,
13+
),
14+
},
15+
messages: [
16+
Note(
17+
"Dropping a column may break existing clients.",
18+
),
19+
],
20+
},
21+
],
22+
)

linter/src/rules/snapshots/squawk_linter__rules__renaming_table__test_rules__renaming_table.snap

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,19 @@ Ok(
1818
),
1919
],
2020
},
21+
RuleViolation {
22+
kind: RenamingTable,
23+
span: Span {
24+
start: 0,
25+
len: Some(
26+
52,
27+
),
28+
},
29+
messages: [
30+
Note(
31+
"Renaming a table may break existing clients.",
32+
),
33+
],
34+
},
2135
],
2236
)

linter/src/violations.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ pub enum RuleViolationKind {
1818
PreferTextField,
1919
PreferRobustStmts,
2020
BanCharField,
21+
BanDropColumn,
2122
}
2223

2324
impl std::fmt::Display for RuleViolationKind {

0 commit comments

Comments
 (0)