risingwave_frontend/binder/
delete.rsuse risingwave_common::catalog::{Schema, TableVersionId};
use risingwave_sqlparser::ast::{Expr, ObjectName, SelectItem};
use super::statement::RewriteExprsRecursive;
use super::{Binder, BoundBaseTable};
use crate::catalog::TableId;
use crate::error::{ErrorCode, Result, RwError};
use crate::expr::ExprImpl;
use crate::user::UserId;
#[derive(Debug, Clone)]
pub struct BoundDelete {
pub table_id: TableId,
pub table_version_id: TableVersionId,
pub table_name: String,
pub owner: UserId,
pub table: BoundBaseTable,
pub selection: Option<ExprImpl>,
pub returning_list: Vec<ExprImpl>,
pub returning_schema: Option<Schema>,
}
impl RewriteExprsRecursive for BoundDelete {
fn rewrite_exprs_recursive(&mut self, rewriter: &mut impl crate::expr::ExprRewriter) {
self.selection =
std::mem::take(&mut self.selection).map(|expr| rewriter.rewrite_expr(expr));
let new_returning_list = std::mem::take(&mut self.returning_list)
.into_iter()
.map(|expr| rewriter.rewrite_expr(expr))
.collect::<Vec<_>>();
self.returning_list = new_returning_list;
}
}
impl Binder {
pub(super) fn bind_delete(
&mut self,
name: ObjectName,
selection: Option<Expr>,
returning_items: Vec<SelectItem>,
) -> Result<BoundDelete> {
let (schema_name, table_name) = Self::resolve_schema_qualified_name(&self.db_name, name)?;
let schema_name = schema_name.as_deref();
let table_catalog = self.resolve_dml_table(schema_name, &table_name, false)?;
if !returning_items.is_empty() && table_catalog.has_generated_column() {
return Err(RwError::from(ErrorCode::BindError(
"`RETURNING` clause is not supported for tables with generated columns".to_string(),
)));
}
let table_id = table_catalog.id;
let owner = table_catalog.owner;
let table_version_id = table_catalog.version_id().expect("table must be versioned");
let table = self.bind_table(schema_name, &table_name, None)?;
let (returning_list, fields) = self.bind_returning_list(returning_items)?;
let returning = !returning_list.is_empty();
let delete = BoundDelete {
table_id,
table_version_id,
table_name,
owner,
table,
selection: selection
.map(|expr| self.bind_expr(expr)?.enforce_bool_clause("WHERE"))
.transpose()?,
returning_list,
returning_schema: if returning {
Some(Schema { fields })
} else {
None
},
};
Ok(delete)
}
}