From 5a92f04b0287c609d025cd8ea87829b9c7b3e290 Mon Sep 17 00:00:00 2001 From: Adrien Foulon <6115458+Tofandel@users.noreply.github.com> Date: Wed, 26 May 2021 14:29:00 +0200 Subject: [PATCH] fix #37483 (aggregates with having) (#37487) --- src/Illuminate/Database/Query/Builder.php | 4 ++-- .../Database/Query/Grammars/Grammar.php | 2 +- tests/Database/DatabaseQueryBuilderTest.php | 16 ++++++++++++++++ 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/src/Illuminate/Database/Query/Builder.php b/src/Illuminate/Database/Query/Builder.php index 9df7d46eec43..0ef10ac1c28b 100755 --- a/src/Illuminate/Database/Query/Builder.php +++ b/src/Illuminate/Database/Query/Builder.php @@ -2826,8 +2826,8 @@ public function average($column) */ public function aggregate($function, $columns = ['*']) { - $results = $this->cloneWithout($this->unions ? [] : ['columns']) - ->cloneWithoutBindings($this->unions ? [] : ['select']) + $results = $this->cloneWithout($this->unions || $this->havings ? [] : ['columns']) + ->cloneWithoutBindings($this->unions || $this->havings ? [] : ['select']) ->setAggregate($function, $columns) ->get($columns); diff --git a/src/Illuminate/Database/Query/Grammars/Grammar.php b/src/Illuminate/Database/Query/Grammars/Grammar.php index b7305e8ea382..d7bc534da120 100755 --- a/src/Illuminate/Database/Query/Grammars/Grammar.php +++ b/src/Illuminate/Database/Query/Grammars/Grammar.php @@ -45,7 +45,7 @@ class Grammar extends BaseGrammar */ public function compileSelect(Builder $query) { - if ($query->unions && $query->aggregate) { + if (($query->unions || $query->havings) && $query->aggregate) { return $this->compileUnionAggregate($query); } diff --git a/tests/Database/DatabaseQueryBuilderTest.php b/tests/Database/DatabaseQueryBuilderTest.php index 5adc3a6d9bb4..7e5adbad4cd3 100755 --- a/tests/Database/DatabaseQueryBuilderTest.php +++ b/tests/Database/DatabaseQueryBuilderTest.php @@ -1034,6 +1034,22 @@ public function testUnionAggregate() $builder->from('posts')->union($this->getSqlServerBuilder()->from('videos'))->count(); } + public function testHavingAggregate() + { + $expected = 'select count(*) as aggregate from (select (select `count(*)` from `videos` where `posts`.`id` = `videos`.`post_id`) as `videos_count` from `posts` having `videos_count` > ?) as `temp_table`'; + $builder = $this->getMySqlBuilder(); + $builder->getConnection()->shouldReceive('getDatabaseName'); + $builder->getConnection()->shouldReceive('select')->once()->with($expected, [0 => 1], true)->andReturn([['aggregate' => 1]]); + $builder->getProcessor()->shouldReceive('processSelect')->once()->andReturnUsing(function ($builder, $results) { + return $results; + }); + + $builder->from('posts')->selectSub(function ($query) { + $query->from('videos')->select('count(*)')->whereColumn('posts.id', '=', 'videos.post_id'); + }, 'videos_count')->having('videos_count', '>', 1); + $builder->count(); + } + public function testSubSelectWhereIns() { $builder = $this->getBuilder();