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 = context.catalog.find_index_owner(
46            self.catalog.as_deref(),
47            self.schema.as_deref(),
48            &self.name,
49        );
50
51        let Some(table_ref) = owner else {
52            if self.if_exists {
53                return Ok(None);
54            }
55            return Err(QuillSQLError::Execution(format!(
56                "index {} does not exist",
57                self.qualified_name()
58            )));
59        };
60
61        context.ensure_writable(&table_ref, "DROP INDEX")?;
62        context.lock_table(table_ref.clone(), LockMode::Exclusive)?;
63
64        let dropped = context.catalog.drop_index(&table_ref, &self.name)?;
65        if !dropped && !self.if_exists {
66            return Err(QuillSQLError::Execution(format!(
67                "index {} does not exist",
68                self.qualified_name()
69            )));
70        }
71
72        Ok(None)
73    }
74
75    fn output_schema(&self) -> SchemaRef {
76        EMPTY_SCHEMA_REF.clone()
77    }
78}
79
80impl std::fmt::Display for PhysicalDropIndex {
81    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
82        write!(f, "DropIndex: {}", self.qualified_name())
83    }
84}