Skip to content

Projects::deleteProject uses ->limit(1) on DELETE — MySQL-only, on Postgres compiles to ctid-subselect that can fail silently #3384

@cleanshiptech

Description

@cleanshiptech

Affected version: 3.7.3
Database: PostgreSQL 15

Bug: app/Domain/Projects/Repositories/Projects.php lines 807–817:

public function deleteProject($id): void
{
$this->connection->table('zp_projects')
->where('id', $id)
->limit(1) // <-- MySQL-only
->delete();
...
}
Laravel's PostgresGrammar::compileDeleteWithJoinsOrLimit rewrites DELETE ... LIMIT 1 as:

DELETE FROM "zp_projects" WHERE "ctid" IN (
SELECT "zp_projects"."ctid" FROM "zp_projects" WHERE "id" = ? LIMIT 1
)
Under various Laravel versions / configurations this subselect path returns 0 affected rows without raising an exception. The void return type on deleteProject swallows the result; the controller fires the success notification regardless; the row stays.

Since id is a primary key, ->limit(1) is always redundant — there can be at most one matching row.

Proposed fix: Drop ->limit(1):

$this->connection->table('zp_projects')
->where('id', $id)
->delete();
Identical behavior on MySQL (still a single-row DELETE because id is unique), correct simple DELETE ... WHERE id = ? SQL on Postgres.

Same pattern (->where('id', $id)->limit(1)->delete()) appears in a few other repositories; worth grep-and-fix across the codebase.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions