From d243d1015ca17dc073d679c271b7474e5ecfba44 Mon Sep 17 00:00:00 2001 From: pedrocarlo Date: Thu, 29 May 2025 14:18:24 -0300 Subject: [PATCH] impl ToSqlString for Delete Plan --- core/translate/optimizer/mod.rs | 14 ++++---- core/translate/plan.rs | 60 +++++++++++++++++++++++++++++---- 2 files changed, 60 insertions(+), 14 deletions(-) diff --git a/core/translate/optimizer/mod.rs b/core/translate/optimizer/mod.rs index 5223fc861..2d02121b9 100644 --- a/core/translate/optimizer/mod.rs +++ b/core/translate/optimizer/mod.rs @@ -37,14 +37,7 @@ pub(crate) mod order; pub fn optimize_plan(plan: &mut Plan, schema: &Schema) -> Result<()> { match plan { - Plan::Select(plan) => { - optimize_select_plan(plan, schema)?; - // Context for everything is created inside the plan - tracing::debug!( - target = "optimized_plan", - plan = plan.to_sql_string(&crate::translate::plan::PlanContext(&[])) - ); - } + Plan::Select(plan) => optimize_select_plan(plan, schema)?, Plan::Delete(plan) => optimize_delete_plan(plan, schema)?, Plan::Update(plan) => optimize_update_plan(plan, schema)?, Plan::CompoundSelect { first, rest, .. } => { @@ -54,6 +47,11 @@ pub fn optimize_plan(plan: &mut Plan, schema: &Schema) -> Result<()> { } } } + // Context for everything is created inside the plan + tracing::debug!( + target = "optimized_plan", + plan = plan.to_sql_string(&crate::translate::plan::PlanContext(&[])) + ); Ok(()) } diff --git a/core/translate/plan.rs b/core/translate/plan.rs index 0cdc6bc36..ffee2449a 100644 --- a/core/translate/plan.rs +++ b/core/translate/plan.rs @@ -1420,12 +1420,10 @@ impl ToSqlContext for PlanContext<'_> { } impl ToSqlString for Plan { - fn to_sql_string(&self, _context: &C) -> String { + fn to_sql_string(&self, context: &C) -> String { // Make the Plans pass their own context match self { - Self::Select(select) => select.to_sql_string(&PlanContext( - &select.table_references.iter().collect::>(), - )), + Self::Select(select) => select.to_sql_string(context), Self::CompoundSelect { first, rest, @@ -1473,6 +1471,7 @@ impl ToSqlString for Plan { } ret.join(" ") } + Self::Delete(delete) => delete.to_sql_string(context), _ => todo!(), } } @@ -1514,12 +1513,15 @@ impl ToSqlString for TableReference { } } -// TODO: currently cannot print the original CTE as it is +// TODO: currently cannot print the original CTE as it is optimized into a subquery impl ToSqlString for SelectPlan { fn to_sql_string( &self, - context: &C, + _context: &C, ) -> String { + let context = self.table_references.iter().collect::>(); + let context = &PlanContext(&context); + let mut ret = Vec::new(); // VALUES SELECT statement if !self.values.is_empty() { @@ -1631,3 +1633,49 @@ impl ToSqlString for SelectPlan { ret.join(" ") } } + +impl ToSqlString for DeletePlan { + fn to_sql_string(&self, _context: &C) -> String { + let table_ref = self + .table_references + .first() + .expect("Delete Plan should have only one table reference"); + let context = &[table_ref]; + let context = &PlanContext(context); + let mut ret = Vec::new(); + + ret.push(format!("DELETE FROM {}", table_ref.table.get_name())); + + if !self.where_clause.is_empty() { + ret.push("WHERE".to_string()); + ret.push( + self.where_clause + .iter() + .map(|where_clause| where_clause.expr.to_sql_string(context)) + .collect::>() + .join(" AND "), + ); + } + if let Some(order_by) = &self.order_by { + ret.push(format!( + "ORDER BY {}", + order_by + .iter() + .map(|(expr, order)| format!( + "{} {}", + expr.to_sql_string(context), + order.to_sql_string(context) + )) + .collect::>() + .join(", ") + )); + } + if let Some(limit) = &self.limit { + ret.push(format!("LIMIT {}", limit)); + } + if let Some(offset) = &self.offset { + ret.push(format!("OFFSET {}", offset)); + } + ret.join(" ") + } +}