quill_sql/execution/physical_plan/
drop_index.rs1use 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}