Describe the issue
Fluent allows .limit() on delete operations and silently drops them from the Postgres query
Vapor version
4.12.0
Operating system and version
macOS 26.4.1
Swift version
Swift Package Manager - Swift 6.3.1
Steps to reproduce
Here is code from our application which triggered this issue:
let query = DomainResultModel.query(on: db)
.filter(\.$runTime < date)
.limit(1000)
let numToDelete = try await query.count()
span.attributes["numDeleted"] = numToDelete
try await query.delete()
Outcome
Reading the code, it looks like it should issue a delete of up to 1000 items.
Or, given that Postgres doesn't support limited deletes, I would expect the delete query to fail with a syntax error.
In reality, it issued an unlimited delete statement: DELETE FROM domain_results WHERE date < $1
Additional notes
Postgres does not support LIMIT on DELETE statements, so DELETE FROM mytable WHERE date < $1 LIMIT 100 is invalid syntax.
However, Fluent is happy to let you write: MyModel.query().filter(\.date < date).limit(100).delete()
Which will actually issue the query `DELETE FROM mytable WHERE date < $1 ', which can take an arbitrary amount of time and use arbitrary Postgres resources.
I had code in my app that did a periodic cleanup of stale data, with a limit to avoid doing large deletes in one go and bogging down the application. However, unbeknownst to me it was actually doing an unlimited DELETE statement. When I reduced the retention period on my data, this caused it to try to delete millions of rows at once, freezing my app and bogging down Postgres.
Describe the issue
Fluent allows .limit() on delete operations and silently drops them from the Postgres query
Vapor version
4.12.0
Operating system and version
macOS 26.4.1
Swift version
Swift Package Manager - Swift 6.3.1
Steps to reproduce
Here is code from our application which triggered this issue:
Outcome
Reading the code, it looks like it should issue a delete of up to 1000 items.
Or, given that Postgres doesn't support limited deletes, I would expect the delete query to fail with a syntax error.
In reality, it issued an unlimited delete statement:
DELETE FROM domain_results WHERE date < $1Additional notes
Postgres does not support LIMIT on DELETE statements, so
DELETE FROM mytable WHERE date < $1 LIMIT 100is invalid syntax.However, Fluent is happy to let you write:
MyModel.query().filter(\.date < date).limit(100).delete()Which will actually issue the query `DELETE FROM mytable WHERE date < $1 ', which can take an arbitrary amount of time and use arbitrary Postgres resources.
I had code in my app that did a periodic cleanup of stale data, with a limit to avoid doing large deletes in one go and bogging down the application. However, unbeknownst to me it was actually doing an unlimited DELETE statement. When I reduced the retention period on my data, this caused it to try to delete millions of rows at once, freezing my app and bogging down Postgres.