Skip to content

Commit

Permalink
Optimize query builder's pluck implementation
Browse files Browse the repository at this point in the history
Because we don't need all the features of data_get() - such as
dot access - there is no need to use the function, which can
become expensive when doing this with many, many rows in a loop.
  • Loading branch information
franzliedke committed Mar 16, 2018
1 parent 374db82 commit e9e939f
Showing 1 changed file with 54 additions and 18 deletions.
72 changes: 54 additions & 18 deletions src/Illuminate/Database/Query/Builder.php
Original file line number Diff line number Diff line change
Expand Up @@ -1996,31 +1996,21 @@ function () {
}
);

if (empty($queryResult)) {
return collect();
}

// If the columns are qualified with a table or have an alias, we cannot use
// those directly in the "pluck" operations since the results from the DB
// are only keyed by the column itself. We'll strip the table out here.
$column = $this->stripTableForPluck($column);
$key = $this->stripTableForPluck($key);

$results = [];

foreach ($queryResult as $row) {
$itemValue = data_get($row, $column);

if (is_null($key)) {
$results[] = $itemValue;
} else {
$itemKey = data_get($row, $key);

if (is_object($itemKey) && method_exists($itemKey, '__toString')) {
$itemKey = (string) $itemKey;
}

$results[$itemKey] = $itemValue;
}
if (is_array($queryResult[0])) {
return $this->pluckFromArrayColumn($queryResult, $column, $key);
} else {
return $this->pluckFromObjectColumn($queryResult, $column, $key);
}

return collect($results);
}

/**
Expand Down Expand Up @@ -2056,6 +2046,52 @@ protected function stripTableForPluck($column)
return is_null($column) ? $column : last(preg_split('~\.| ~', $column));
}

/**
* Retrieve column values from rows represented as objects.
*
* @param array $queryResult
* @param string $column
* @param string $key
* @return \Illuminate\Support\Collection
*/
protected function pluckFromObjectColumn($queryResult, $column, $key)
{
$results = [];

foreach ($queryResult as $row) {
if (is_null($key)) {
$results[] = $row->$column;
} else {
$results[$row->$key] = $row->$column;
}
}

return collect($results);
}

/**
* Retrieve column values from rows represented as arrays.
*
* @param array $queryResult
* @param string $column
* @param string $key
* @return \Illuminate\Support\Collection
*/
protected function pluckFromArrayColumn($queryResult, $column, $key)
{
$results = [];

foreach ($queryResult as $row) {
if (is_null($key)) {
$results[] = $row[$column];
} else {
$results[$row[$key]] = $row[$column];
}
}

return collect($results);
}

/**
* Concatenate values of a given column as a string.
*
Expand Down

0 comments on commit e9e939f

Please sign in to comment.