Skip to content

Commit 18c926d

Browse files
authored
Support builder as param on whereExists (#45341)
1 parent bee4fd6 commit 18c926d

File tree

2 files changed

+41
-13
lines changed

2 files changed

+41
-13
lines changed

src/Illuminate/Database/Query/Builder.php

+17-13
Original file line numberDiff line numberDiff line change
@@ -1617,54 +1617,58 @@ protected function whereSub($column, $operator, Closure $callback, $boolean)
16171617
/**
16181618
* Add an exists clause to the query.
16191619
*
1620-
* @param \Closure $callback
1620+
* @param \Closure|\Illuminate\Database\Query\Builder|\Illuminate\Database\Eloquent\Builder $callback
16211621
* @param string $boolean
16221622
* @param bool $not
16231623
* @return $this
16241624
*/
1625-
public function whereExists(Closure $callback, $boolean = 'and', $not = false)
1625+
public function whereExists($callback, $boolean = 'and', $not = false)
16261626
{
1627-
$query = $this->forSubQuery();
1627+
if ($callback instanceof Closure) {
1628+
$query = $this->forSubQuery();
16281629

1629-
// Similar to the sub-select clause, we will create a new query instance so
1630-
// the developer may cleanly specify the entire exists query and we will
1631-
// compile the whole thing in the grammar and insert it into the SQL.
1632-
$callback($query);
1630+
// Similar to the sub-select clause, we will create a new query instance so
1631+
// the developer may cleanly specify the entire exists query and we will
1632+
// compile the whole thing in the grammar and insert it into the SQL.
1633+
$callback($query);
1634+
} else {
1635+
$query = $callback;
1636+
}
16331637

16341638
return $this->addWhereExistsQuery($query, $boolean, $not);
16351639
}
16361640

16371641
/**
16381642
* Add an or exists clause to the query.
16391643
*
1640-
* @param \Closure $callback
1644+
* @param \Closure|\Illuminate\Database\Query\Builder|\Illuminate\Database\Eloquent\Builder $callback
16411645
* @param bool $not
16421646
* @return $this
16431647
*/
1644-
public function orWhereExists(Closure $callback, $not = false)
1648+
public function orWhereExists($callback, $not = false)
16451649
{
16461650
return $this->whereExists($callback, 'or', $not);
16471651
}
16481652

16491653
/**
16501654
* Add a where not exists clause to the query.
16511655
*
1652-
* @param \Closure $callback
1656+
* @param \Closure|\Illuminate\Database\Query\Builder|\Illuminate\Database\Eloquent\Builder $callback
16531657
* @param string $boolean
16541658
* @return $this
16551659
*/
1656-
public function whereNotExists(Closure $callback, $boolean = 'and')
1660+
public function whereNotExists($callback, $boolean = 'and')
16571661
{
16581662
return $this->whereExists($callback, $boolean, true);
16591663
}
16601664

16611665
/**
16621666
* Add a where not exists clause to the query.
16631667
*
1664-
* @param \Closure $callback
1668+
* @param \Closure|\Illuminate\Database\Query\Builder|\Illuminate\Database\Eloquent\Builder $callback
16651669
* @return $this
16661670
*/
1667-
public function orWhereNotExists(Closure $callback)
1671+
public function orWhereNotExists($callback)
16681672
{
16691673
return $this->orWhereExists($callback, true);
16701674
}

tests/Database/DatabaseQueryBuilderTest.php

+24
Original file line numberDiff line numberDiff line change
@@ -2032,6 +2032,30 @@ public function testWhereExists()
20322032
$q->select('*')->from('products')->where('products.id', '=', new Raw('"orders"."id"'));
20332033
});
20342034
$this->assertSame('select * from "orders" where "id" = ? or not exists (select * from "products" where "products"."id" = "orders"."id")', $builder->toSql());
2035+
2036+
$builder = $this->getBuilder();
2037+
$builder->select('*')->from('orders')->whereExists(
2038+
$this->getBuilder()->select('*')->from('products')->where('products.id', '=', new Raw('"orders"."id"'))
2039+
);
2040+
$this->assertSame('select * from "orders" where exists (select * from "products" where "products"."id" = "orders"."id")', $builder->toSql());
2041+
2042+
$builder = $this->getBuilder();
2043+
$builder->select('*')->from('orders')->whereNotExists(
2044+
$this->getBuilder()->select('*')->from('products')->where('products.id', '=', new Raw('"orders"."id"'))
2045+
);
2046+
$this->assertSame('select * from "orders" where not exists (select * from "products" where "products"."id" = "orders"."id")', $builder->toSql());
2047+
2048+
$builder = $this->getBuilder();
2049+
$builder->select('*')->from('orders')->where('id', '=', 1)->orWhereExists(
2050+
$this->getBuilder()->select('*')->from('products')->where('products.id', '=', new Raw('"orders"."id"'))
2051+
);
2052+
$this->assertSame('select * from "orders" where "id" = ? or exists (select * from "products" where "products"."id" = "orders"."id")', $builder->toSql());
2053+
2054+
$builder = $this->getBuilder();
2055+
$builder->select('*')->from('orders')->where('id', '=', 1)->orWhereNotExists(
2056+
$this->getBuilder()->select('*')->from('products')->where('products.id', '=', new Raw('"orders"."id"'))
2057+
);
2058+
$this->assertSame('select * from "orders" where "id" = ? or not exists (select * from "products" where "products"."id" = "orders"."id")', $builder->toSql());
20352059
}
20362060

20372061
public function testBasicJoins()

0 commit comments

Comments
 (0)