From 7e63bc31e22067dff73f79ec903340136144d3d9 Mon Sep 17 00:00:00 2001 From: cdstarling Date: Wed, 28 Feb 2018 21:46:46 +0000 Subject: [PATCH] #23327 Moving code from the query builder to the eloquent builder A previous pull request #19013, which aimed to solve the issue of multiple select statements causing an SQL error within a withCount function, assumed a sub query would only need one select statement. This is not the case, so the code that removes excess filters is moved to the withCount method where the sub query does only need one select. --- .../Database/Eloquent/Concerns/QueriesRelationships.php | 8 ++++++-- src/Illuminate/Database/Query/Builder.php | 2 -- tests/Database/DatabaseQueryBuilderTest.php | 3 ++- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/Illuminate/Database/Eloquent/Concerns/QueriesRelationships.php b/src/Illuminate/Database/Eloquent/Concerns/QueriesRelationships.php index 289770375f94..5f2ec2dab7b9 100644 --- a/src/Illuminate/Database/Eloquent/Concerns/QueriesRelationships.php +++ b/src/Illuminate/Database/Eloquent/Concerns/QueriesRelationships.php @@ -210,14 +210,18 @@ public function withCount($relations) $query->callScope($constraints); - $query->mergeConstraintsFrom($relation->getQuery()); + $query = $query->mergeConstraintsFrom($relation->getQuery())->toBase(); + + if (count($query->columns) > 1) { + $query->columns = [$query->columns[0]]; + } // Finally we will add the proper result column alias to the query and run the subselect // statement against the query builder. Then we will return the builder instance back // to the developer for further constraint chaining that needs to take place on it. $column = $alias ?? Str::snake($name.'_count'); - $this->selectSub($query->toBase(), $column); + $this->selectSub($query, $column); } return $this; diff --git a/src/Illuminate/Database/Query/Builder.php b/src/Illuminate/Database/Query/Builder.php index 2bbddfd066f9..1025915ed919 100755 --- a/src/Illuminate/Database/Query/Builder.php +++ b/src/Illuminate/Database/Query/Builder.php @@ -279,8 +279,6 @@ public function selectSub($query, $as) protected function parseSubSelect($query) { if ($query instanceof self) { - $query->columns = [$query->columns[0]]; - return [$query->toSql(), $query->getBindings()]; } elseif (is_string($query)) { return [$query, []]; diff --git a/tests/Database/DatabaseQueryBuilderTest.php b/tests/Database/DatabaseQueryBuilderTest.php index ac5b228302e2..94d17e74e6f8 100755 --- a/tests/Database/DatabaseQueryBuilderTest.php +++ b/tests/Database/DatabaseQueryBuilderTest.php @@ -1449,10 +1449,11 @@ public function testAggregateWithSubSelect() return $results; }); $builder->from('users')->selectSub(function ($query) { - $query->from('posts')->select('foo')->where('title', 'foo'); + $query->from('posts')->select('foo', 'bar')->where('title', 'foo'); }, 'post'); $count = $builder->count(); $this->assertEquals(1, $count); + $this->assertEquals('(select "foo", "bar" from "posts" where "title" = ?) as "post"', $builder->columns[0]->getValue()); $this->assertEquals(['foo'], $builder->getBindings()); }