From e9e939fc7178726227afc872ada7cd4247122ed3 Mon Sep 17 00:00:00 2001 From: Franz Liedke Date: Sat, 10 Mar 2018 15:52:46 +0100 Subject: [PATCH] Optimize query builder's pluck implementation 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. --- src/Illuminate/Database/Query/Builder.php | 72 +++++++++++++++++------ 1 file changed, 54 insertions(+), 18 deletions(-) diff --git a/src/Illuminate/Database/Query/Builder.php b/src/Illuminate/Database/Query/Builder.php index 386e8e780b13..47827763da17 100755 --- a/src/Illuminate/Database/Query/Builder.php +++ b/src/Illuminate/Database/Query/Builder.php @@ -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); } /** @@ -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. *