Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

gpi's avatar
Level 1

Eloquent closures insert to query - "SELECT *" and "is null"

After update Laravel from 5.5 to 8.0 I noticed strange SQL errors: General error: 1096 No tables used. I found out that it was caused by the closers on the Eloquent model like this:

$results = Product::where('products.id', '=', 10)->where(function($query) {
	
 });

generate SQL Query like this ($results->toSql()):

select * from `products` where `products`.`id` = ? and (select *) is null

The closure generates automatically select * and add is null. Is it a bug in Eloquent/QueryBuilder ?

0 likes
8 replies
gpi's avatar
Level 1

This was the only simplified example to show where this select * is inserting. I used the closer to grouping OR WHERE statement, so:

This code:

$results = Product::where('category', '=', 'Trousers')->where(function($query) {
	$query->orWhere('color', '=', 'Red')->orWhere('color', '=', 'Black')
 });

should genetate SQL like this:

select * from `products` where `products`.`category` = 'Trousers' and (select * `products`.`color` =  'Red' or `products`.`color` =  'Black')

while I'm getting this:

select * from `products` where `products`.`category` = 'Trousers' and (select * `products`.`color` =  'Red' or `products`.`color` =  'Black') is null

So as you see this select * inside the brackets is not needed.

Here in the documentation is the example about my scenario (group an "or" condition within parentheses) and it looks simillar: https://laravel.com/docs/8.x/queries#or-where-clauses

1 like
gpi's avatar
Level 1

One more observation I tested now. If I do the same this way:

$users = DB::table('products')
->where('category', '=', 'Trousers')
->where(function($query) {
	$query->orWhere('color', '=', 'Red')->orWhere('color', '=', 'Black')
 });

the SQL output is correct. Why it's a dirret now for Eloquent models?

1 like
maqduni's avatar

@gpi I just upgraded version 5.8 to 8 and have the exact same problem. It's been 2 years since you posted it here, but I'll still ask if you found out why it's happening. Would highly appreciate any help.

maqduni's avatar

@gpi I found the problem, you are probably using sofa/eloquence package. Its query builder class reassigns the $operator parameter to '=' prior to passing the control back to the Eloquent query builder because of which Eloquent treats the query as a regular select on a column and correspondingly adds the missing select clause. I'm submitting a bug to the sofa/eloquence repo right now.

gpi's avatar
Level 1

@maqduni Yeah, I found the same and I had to eliminate sofa/eloquence package from the project.

MostafaGamal's avatar

Subquerie compares the results of a subquery to the value you give to the where as a second parameter. since you didn't pass a second parameter to where , the sebquery result compared to null and your subquery do nothing

Please or to participate in this conversation.