Skip to content

[5.0] Fix aggregate function to deal with group by sql #8113

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 11 commits into from
42 changes: 26 additions & 16 deletions src/Illuminate/Database/Query/Builder.php
Original file line number Diff line number Diff line change
Expand Up @@ -1388,7 +1388,7 @@ public function paginate($perPage = 15, $columns = ['*'])
{
$page = Paginator::resolveCurrentPage();

$total = $this->getCountForPagination();
$total = $this->getCountForPagination($columns);

$results = $this->forPage($page, $perPage)->get($columns);

Expand Down Expand Up @@ -1420,17 +1420,27 @@ public function simplePaginate($perPage = 15, $columns = ['*'])
/**
* Get the count of the total records for the paginator.
*
* @param array $columns
* @return int
*/
public function getCountForPagination()
public function getCountForPagination($columns = ['*'])
{
$this->backupFieldsForCount();

$total = $this->count();
$this->aggregate = ['function' => 'count', 'columns' => $columns];

$results = $this->get();

$this->aggregate = null;

$this->restoreFieldsForCount();

return $total;
if (isset($results[0]))
{
if (isset($this->groups)) return count($results);

return (int) array_change_key_case((array) $results[0])['aggregate'];
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this valid syntax for php 5.4?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, it's valid

Function array dereferencing has been added, e.g. foo()[0].

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, good. I couldn't remember if it was added in 5.4, or 5.5. :) I only use 5.5/5.6 on prod.

}
}

/**
Expand All @@ -1440,7 +1450,7 @@ public function getCountForPagination()
*/
protected function backupFieldsForCount()
{
foreach (['orders', 'limit', 'offset'] as $field)
foreach (['orders', 'limit', 'offset', 'columns'] as $field)
{
$this->backups[$field] = $this->{$field};

Expand All @@ -1455,7 +1465,7 @@ protected function backupFieldsForCount()
*/
protected function restoreFieldsForCount()
{
foreach (['orders', 'limit', 'offset'] as $field)
foreach (['orders', 'limit', 'offset', 'columns'] as $field)
{
$this->{$field} = $this->backups[$field];
}
Expand Down Expand Up @@ -1568,7 +1578,7 @@ public function count($columns = '*')
{
if ( ! is_array($columns))
{
$columns = array($columns);
$columns = [$columns];
}

return (int) $this->aggregate(__FUNCTION__, $columns);
Expand All @@ -1578,33 +1588,33 @@ public function count($columns = '*')
* Retrieve the minimum value of a given column.
*
* @param string $column
* @return mixed
* @return float|int
*/
public function min($column)
{
return $this->aggregate(__FUNCTION__, array($column));
return $this->aggregate(__FUNCTION__, [$column]);
}

/**
* Retrieve the maximum value of a given column.
*
* @param string $column
* @return mixed
* @return float|int
*/
public function max($column)
{
return $this->aggregate(__FUNCTION__, array($column));
return $this->aggregate(__FUNCTION__, [$column]);
}

/**
* Retrieve the sum of the values of a given column.
*
* @param string $column
* @return mixed
* @return float|int
*/
public function sum($column)
{
$result = $this->aggregate(__FUNCTION__, array($column));
$result = $this->aggregate(__FUNCTION__, [$column]);

return $result ?: 0;
}
Expand All @@ -1613,11 +1623,11 @@ public function sum($column)
* Retrieve the average of the values of a given column.
*
* @param string $column
* @return mixed
* @return float|int
*/
public function avg($column)
{
return $this->aggregate(__FUNCTION__, array($column));
return $this->aggregate(__FUNCTION__, [$column]);
}

/**
Expand All @@ -1627,7 +1637,7 @@ public function avg($column)
* @param array $columns
* @return mixed
*/
public function aggregate($function, $columns = array('*'))
public function aggregate($function, $columns = ['*'])
{
$this->aggregate = compact('function', 'columns');

Expand Down
13 changes: 13 additions & 0 deletions tests/Database/DatabaseEloquentIntegrationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,19 @@ public function testPaginatedModelCollectionRetrieval()
}


public function testCountForPaginationWithGrouping()
{
EloquentTestUser::create(['id' => 1, 'email' => 'taylorotwell@gmail.com']);
EloquentTestUser::create(['id' => 2, 'email' => 'abigailotwell@gmail.com']);
EloquentTestUser::create(['id' => 3, 'email' => 'foo@gmail.com']);
EloquentTestUser::create(['id' => 4, 'email' => 'foo@gmail.com']);

$query = EloquentTestUser::groupBy('email')->getQuery();

$this->assertEquals(3, $query->getCountForPagination());
}


public function testListsRetrieval()
{
EloquentTestUser::create(['id' => 1, 'email' => 'taylorotwell@gmail.com']);
Expand Down