quill_sql/execution/physical_plan/
drop_table.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;
6use crate::utils::table_ref::TableReference;
7
8#[derive(Debug)]
9pub struct PhysicalDropTable {
10    table: TableReference,
11    if_exists: bool,
12}
13
14impl PhysicalDropTable {
15    pub fn new(table: TableReference, if_exists: bool) -> Self {
16        Self { table, if_exists }
17    }
18
19    fn qualified_name(&self) -> String {
20        self.table.to_string()
21    }
22}
23
24impl VolcanoExecutor for PhysicalDropTable {
25    fn init(&self, _context: &mut ExecutionContext) -> QuillSQLResult<()> {
26        Ok(())
27    }
28
29    fn next(&self, context: &mut ExecutionContext) -> QuillSQLResult<Option<Tuple>> {
30        if context.catalog.try_table_heap(&self.table).is_none() {
31            if self.if_exists {
32                return Ok(None);
33            }
34            return Err(QuillSQLError::Execution(format!(
35                "table {} does not exist",
36                self.qualified_name()
37            )));
38        }
39
40        context.ensure_writable(&self.table, "DROP TABLE")?;
41        context.lock_table(self.table.clone(), LockMode::Exclusive)?;
42
43        let dropped = context.catalog.drop_table(&self.table)?;
44        if !dropped && !self.if_exists {
45            return Err(QuillSQLError::Execution(format!(
46                "table {} does not exist",
47                self.qualified_name()
48            )));
49        }
50
51        Ok(None)
52    }
53
54    fn output_schema(&self) -> SchemaRef {
55        EMPTY_SCHEMA_REF.clone()
56    }
57}
58
59impl std::fmt::Display for PhysicalDropTable {
60    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
61        write!(f, "DropTable: {}", self.table)
62    }
63}