quill_sql/execution/physical_plan/
drop_index.rs

1use crate::catalog::{SchemaRef, EMPTY_SCHEMA_REF};
2use crate::error::{QuillSQLError, QuillSQLResult};
3use crate::execution::{ExecutionContext, VolcanoExecutor};
4use crate::storage::tuple::Tuple;
5use crate::transaction::LockMode;
6
7#[derive(Debug)]
8pub struct PhysicalDropIndex {
9    pub name: String,
10    pub schema: Option<String>,
11    pub catalog: Option<String>,
12    pub if_exists: bool,
13}
14
15impl PhysicalDropIndex {
16    pub fn new(
17        name: String,
18        schema: Option<String>,
19        catalog: Option<String>,
20        if_exists: bool,
21    ) -> Self {
22        Self {
23            name,
24            schema,
25            catalog,
26            if_exists,
27        }
28    }
29
30    fn qualified_name(&self) -> String {
31        match (&self.catalog, &self.schema) {
32            (Some(catalog), Some(schema)) => format!("{catalog}.{schema}.{}", self.name),
33            (None, Some(schema)) => format!("{schema}.{}", self.name),
34            _ => self.name.clone(),
35        }
36    }
37}
38
39impl VolcanoExecutor for PhysicalDropIndex {
40    fn init(&self, _context: &mut ExecutionContext) -> QuillSQLResult<()> {
41        Ok(())
42    }
43
44    fn next(&self, context: &mut ExecutionContext) -> QuillSQLResult<Option<Tuple>> {
45        let owner =
46            context.find_index_owner(self.catalog.as_deref(), self.schema.as_deref(), &self.name);
47
48        let Some(table_ref) = owner else {
49            if self.if_exists {
50                return Ok(None);
51            }
52            return Err(QuillSQLError::Execution(format!(
53                "index {} does not exist",
54                self.qualified_name()
55            )));
56        };
57
58        context.ensure_writable(&table_ref, "DROP INDEX")?;
59        context.lock_table(table_ref.clone(), LockMode::Exclusive)?;
60
61        let dropped = context.drop_index(&table_ref, &self.name)?;
62        if !dropped && !self.if_exists {
63            return Err(QuillSQLError::Execution(format!(
64                "index {} does not exist",
65                self.qualified_name()
66            )));
67        }
68
69        Ok(None)
70    }
71
72    fn output_schema(&self) -> SchemaRef {
73        EMPTY_SCHEMA_REF.clone()
74    }
75}
76
77impl std::fmt::Display for PhysicalDropIndex {
78    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
79        write!(f, "DropIndex: {}", self.qualified_name())
80    }
81}