Skip to content

Commit 54421e4

Browse files
authored
[10.x] Support providing subquery as value to where builder method (#48116)
* Add failing test * Allow $value to be query builder
1 parent 85ef845 commit 54421e4

File tree

2 files changed

+15
-7
lines changed

2 files changed

+15
-7
lines changed

src/Illuminate/Database/Query/Builder.php

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -803,7 +803,7 @@ public function where($column, $operator = null, $value = null, $boolean = 'and'
803803
// If the value is a Closure, it means the developer is performing an entire
804804
// sub-select within the query and we will need to compile the sub-select
805805
// within the where clause to get the appropriate query record results.
806-
if ($value instanceof Closure) {
806+
if ($this->isQueryable($value)) {
807807
return $this->whereSub($column, $operator, $value, $boolean);
808808
}
809809

@@ -1658,18 +1658,22 @@ public function addNestedWhereQuery($query, $boolean = 'and')
16581658
*
16591659
* @param \Illuminate\Contracts\Database\Query\Expression|string $column
16601660
* @param string $operator
1661-
* @param \Closure $callback
1661+
* @param \Closure||\Illuminate\Database\Query\Builder|\Illuminate\Database\Eloquent\Builder $callback
16621662
* @param string $boolean
16631663
* @return $this
16641664
*/
1665-
protected function whereSub($column, $operator, Closure $callback, $boolean)
1665+
protected function whereSub($column, $operator, $callback, $boolean)
16661666
{
16671667
$type = 'Sub';
16681668

1669-
// Once we have the query instance we can simply execute it so it can add all
1670-
// of the sub-select's conditions to itself, and then we can cache it off
1671-
// in the array of where clauses for the "main" parent query instance.
1672-
$callback($query = $this->forSubQuery());
1669+
if ($callback instanceof Closure) {
1670+
// Once we have the query instance we can simply execute it so it can add all
1671+
// of the sub-select's conditions to itself, and then we can cache it off
1672+
// in the array of where clauses for the "main" parent query instance.
1673+
$callback($query = $this->forSubQuery());
1674+
} else {
1675+
$query = $callback instanceof EloquentBuilder ? $callback->toBase() : $callback;
1676+
}
16731677

16741678
$this->wheres[] = compact(
16751679
'type', 'column', 'operator', 'query', 'boolean'

tests/Integration/Database/QueryBuilderTest.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,10 @@ public function testWhereValueSubQueryBuilder()
259259
$this->assertTrue(DB::table('posts')->where($subQuery, 'Sub query value')->exists());
260260
$this->assertFalse(DB::table('posts')->where($subQuery, 'Does not match')->exists());
261261
$this->assertTrue(DB::table('posts')->where($subQuery, '!=', 'Does not match')->exists());
262+
263+
$this->assertTrue(DB::table('posts')->where(DB::raw('\'Sub query value\''), $subQuery)->exists());
264+
$this->assertFalse(DB::table('posts')->where(DB::raw('\'Does not match\''), $subQuery)->exists());
265+
$this->assertTrue(DB::table('posts')->where(DB::raw('\'Does not match\''), '!=', $subQuery)->exists());
262266
}
263267

264268
public function testWhereNot()

0 commit comments

Comments
 (0)