diff --git a/datafusion/sql/src/statement.rs b/datafusion/sql/src/statement.rs index ed6eeab28445c..c89c2a622e038 100644 --- a/datafusion/sql/src/statement.rs +++ b/datafusion/sql/src/statement.rs @@ -1248,6 +1248,10 @@ impl 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")?; } @@ -1256,7 +1260,7 @@ impl 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), @@ -2346,7 +2350,6 @@ impl SqlToRel<'_, S> { &self, table_name: &ObjectName, predicate_expr: Option, - limit: Option, ) -> Result { // Do a table lookup to verify the table exists let table_ref = self.object_name_to_table_reference(table_name.clone())?; @@ -2360,7 +2363,7 @@ impl 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 = @@ -2377,14 +2380,6 @@ impl 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, diff --git a/datafusion/sql/tests/sql_integration.rs b/datafusion/sql/tests/sql_integration.rs index 3e683a54daf53..5a48c52ef570d 100644 --- a/datafusion/sql/tests/sql_integration.rs +++ b/datafusion/sql/tests/sql_integration.rs @@ -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 = diff --git a/datafusion/sqllogictest/test_files/delete.slt b/datafusion/sqllogictest/test_files/delete.slt index 5c2da467bb995..3be629e241ab3 100644 --- a/datafusion/sqllogictest/test_files/delete.slt +++ b/datafusion/sqllogictest/test_files/delete.slt @@ -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