Skip to content
Merged
17 changes: 6 additions & 11 deletions datafusion/sql/src/statement.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1248,6 +1248,10 @@ impl<S: ContextProvider> SqlToRel<'_, S> {
plan_err!("Delete-order-by clause not yet supported")?;
}

if limit.is_some() {
return plan_err!("Delete-limit clause is not supported");
}

if !optimizer_hints.is_empty() {
plan_err!("Optimizer hints not supported")?;
}
Expand All @@ -1256,7 +1260,7 @@ impl<S: ContextProvider> SqlToRel<'_, S> {
}

let table_name = self.get_delete_target(from)?;
self.delete_to_plan(&table_name, selection, limit)
self.delete_to_plan(&table_name, selection)
}

Statement::Merge(merge) => self.merge_to_plan(merge),
Expand Down Expand Up @@ -2346,7 +2350,6 @@ impl<S: ContextProvider> SqlToRel<'_, S> {
&self,
table_name: &ObjectName,
predicate_expr: Option<SQLExpr>,
limit: Option<SQLExpr>,
) -> Result<LogicalPlan> {
// Do a table lookup to verify the table exists
let table_ref = self.object_name_to_table_reference(table_name.clone())?;
Expand All @@ -2360,7 +2363,7 @@ impl<S: ContextProvider> SqlToRel<'_, S> {
.build()?;
let mut planner_context = PlannerContext::new();

let mut source = match predicate_expr {
let source = match predicate_expr {
None => scan,
Some(predicate_expr) => {
let filter_expr =
Expand All @@ -2377,14 +2380,6 @@ impl<S: ContextProvider> SqlToRel<'_, S> {
}
};

if let Some(limit) = limit {
let empty_schema = DFSchema::empty();
let limit = self.sql_to_expr(limit, &empty_schema, &mut planner_context)?;
source = LogicalPlanBuilder::from(source)
.limit_by_expr(None, Some(limit))?
.build()?
}

let plan = LogicalPlan::Dml(DmlStatement::new(
table_ref,
table_source,
Expand Down
11 changes: 11 additions & 0 deletions datafusion/sql/tests/sql_integration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -850,6 +850,17 @@ fn plan_delete() {
);
}

#[rstest]
#[case("delete from person limit 1")]
#[case("delete from person where id = 1 limit 1")]
fn plan_delete_rejects_limit(#[case] sql: &str) {
let err = logical_plan(sql).expect_err("DELETE LIMIT should be rejected");
assert_eq!(
err.strip_backtrace(),
"Error during planning: Delete-limit clause is not supported"
);
}

#[test]
fn plan_delete_quoted_identifier_case_sensitive() {
let sql =
Expand Down
26 changes: 4 additions & 22 deletions datafusion/sqllogictest/test_files/delete.slt
Original file line number Diff line number Diff line change
Expand Up @@ -117,29 +117,11 @@ physical_plan_error This feature is not implemented: Physical plan does not supp

# Delete with limit

query TT
explain delete from t1 limit 10
----
logical_plan
01)Dml: op=[Delete] table=[t1]
02)--Limit: skip=0, fetch=10
03)----TableScan: t1
physical_plan
01)CooperativeExec
02)--MemDeleteExec
statement error DataFusion error: Error during planning: Delete-limit clause is not supported
delete from t1 limit 10;


query TT
explain delete from t1 where a = 1 and b = '2' limit 10
----
logical_plan
01)Dml: op=[Delete] table=[t1]
02)--Limit: skip=0, fetch=10
03)----Filter: CAST(t1.a AS Int64) = Int64(1) AND t1.b = CAST(Utf8("2") AS Utf8View)
04)------TableScan: t1
physical_plan
01)CooperativeExec
02)--MemDeleteExec: predicate=[CAST(a@0 AS Int64) = 1, b@1 = CAST(2 AS Utf8View)]
statement error DataFusion error: Error during planning: Delete-limit clause is not supported
delete from t1 where a = 1 and b = '2' limit 10;

# Config reset
statement ok
Expand Down
Loading