Skip to content

Conversation

tegos
Copy link
Contributor

@tegos tegos commented Sep 28, 2025

Problem

By default, Laravel silently ignores ORDER BY and LIMIT on DELETE … JOIN queries when using the MySQL grammar.
This results in unexpected behavior: instead of deleting rows in small batches, the query deletes all matching rows at once.

Example:

$batchSize = 500;
$totalDeleted = 0;

do {
	$deleted = DB::table('cross_product_references as cpr')
		->leftJoin('products as p1', fn($join) => $join
			->on('cpr.article', '=', 'p1.article')
			->on('cpr.brand_id', '=', 'p1.brand_id'))
		->leftJoin('products as p2', fn($join) => $join
			->on('cpr.cross_article', '=', 'p2.article')
			->on('cpr.cross_brand_id', '=', 'p2.brand_id'))
		->where(fn($query) => $query
			->whereNull('p1.id')
			->orWhereNull('p2.id'))
		->limit($batchSize)
		->orderBy('cpr.id')
		->delete();
	$totalDeleted += $deleted;
} while ($deleted > 0);

$this->line("Deleted <info>$totalDeleted</info> rows.");

Expected: delete in batches of 500
Actual: deletes all 500k+ rows in one query


Fix

  • Added compileDeleteWithJoins override in MySqlGrammar.
  • Now compiles full SQL with JOIN, ORDER BY, and LIMIT instead of stripping them.
  • Leaves it to the underlying MySQL/MariaDB/Vitess implementation to decide whether the query is valid.

Why

  • Avoids silent ignoring of ORDER BY and LIMIT, which could lead to accidental mass deletions.
  • Provides consistent behavior: Laravel now generates the full query requested by the developer.
  • Compatible with systems like Vitess, which do support DELETE … JOIN … ORDER BY/LIMIT.
  • On vanilla MySQL, developers will now get QueryException.

Copy link

Thanks for submitting a PR!

Note that draft PR's are not reviewed. If you would like a review, please mark your pull request as ready for review in the GitHub user interface.

Pull requests that are abandoned in draft may be closed due to inactivity.

@tegos
Copy link
Contributor Author

tegos commented Sep 28, 2025

Follow-up to previous PR, now targeting master with clean branch.

@tegos tegos marked this pull request as ready for review September 28, 2025 19:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant