nodedb_sql/planner/index_ddl/
drop.rs1use sqlparser::ast;
6
7use crate::SqlPlan;
8use crate::error::{Result, SqlError};
9use crate::parser::normalize::normalize_object_name_checked;
10
11pub fn plan_drop_index(stmt: &ast::Statement) -> Result<SqlPlan> {
17 let ast::Statement::Drop {
18 object_type: ast::ObjectType::Index,
19 names,
20 if_exists,
21 table,
22 ..
23 } = stmt
24 else {
25 return Err(SqlError::Parse {
26 detail: "DROP INDEX: unexpected statement shape".into(),
27 });
28 };
29
30 let name = names.first().ok_or_else(|| SqlError::Parse {
31 detail: "DROP INDEX: an index name is required".into(),
32 })?;
33 let index_name = normalize_object_name_checked(name)?;
34 if index_name.is_empty() {
35 return Err(SqlError::Parse {
36 detail: "DROP INDEX: empty index name".into(),
37 });
38 }
39
40 let collection = match table.as_ref() {
41 Some(t) => Some(normalize_object_name_checked(t)?),
42 None => None,
43 };
44
45 Ok(SqlPlan::DropIndex {
46 index_name,
47 collection,
48 if_exists: *if_exists,
49 })
50}
51
52#[cfg(test)]
53mod tests {
54 use super::*;
55 use crate::parser::statement::parse_sql;
56
57 fn plan(sql: &str) -> Result<SqlPlan> {
58 let stmts = parse_sql(sql).expect("parse");
59 plan_drop_index(&stmts[0])
60 }
61
62 #[test]
63 fn basic_drop() {
64 let SqlPlan::DropIndex {
65 index_name,
66 collection,
67 if_exists,
68 } = plan("DROP INDEX idx_users_email").unwrap()
69 else {
70 panic!("expected DropIndex");
71 };
72 assert_eq!(index_name, "idx_users_email");
73 assert!(collection.is_none());
74 assert!(!if_exists);
75 }
76
77 #[test]
78 fn if_exists_honored() {
79 let SqlPlan::DropIndex { if_exists, .. } = plan("DROP INDEX IF EXISTS idx").unwrap() else {
80 panic!("expected DropIndex");
81 };
82 assert!(if_exists);
83 }
84
85 #[test]
86 fn schema_qualified_name_rejected() {
87 let err = plan("DROP INDEX public.idx").unwrap_err();
88 assert!(matches!(err, SqlError::Unsupported { .. }), "{err:?}");
89 }
90}