Skip to content

Commit 5ed5dfd

Browse files
committed
ResultSet: improved error message on duplicated names in select statement
1 parent da6764d commit 5ed5dfd

File tree

4 files changed

+38
-4
lines changed

4 files changed

+38
-4
lines changed

src/Database/Helpers.php

+24
Original file line numberDiff line numberDiff line change
@@ -267,4 +267,28 @@ public static function toPairs(array $rows, $key = NULL, $value = NULL)
267267
return $return;
268268
}
269269

270+
271+
/**
272+
* Finds duplicate columns in select statement
273+
* @param \PDOStatement
274+
* @return string
275+
*/
276+
public static function findDuplicates(\PDOStatement $statement)
277+
{
278+
$cols = [];
279+
for ($i=0; $i<$statement->columnCount(); $i++) {
280+
$meta = $statement->getColumnMeta($i);
281+
$tableName = isset($meta['table']) ? $meta['table'] : '';
282+
$cols[$meta['name']][] = $tableName;
283+
}
284+
$duplicates = [];
285+
foreach ($cols as $name => $tables) {
286+
if (count($tables) > 1) {
287+
$tableNames = implode(', ', array_unique($tables));
288+
$duplicates[] = "'$name'".($tableNames !== '' ? " from $tableNames" : '');
289+
}
290+
}
291+
return implode('; ', $duplicates);
292+
}
293+
270294
}

src/Database/ResultSet.php

+2-1
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,8 @@ public function fetch()
266266
}
267267

268268
if ($this->result === NULL && count($data) !== $this->pdoStatement->columnCount()) {
269-
trigger_error('Found duplicate columns in database result set.', E_USER_NOTICE);
269+
$duplicates = Helpers::findDuplicates($this->pdoStatement);
270+
trigger_error("Found duplicate columns in database result set: $duplicates.", E_USER_NOTICE);
270271
}
271272

272273
$this->resultKey++;

tests/Database/ResultSet.fetch().phpt

+10-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ test(function () use ($context) {
1717

1818
Assert::error(function () use ($res) {
1919
$res->fetch();
20-
}, E_USER_NOTICE, 'Found duplicate columns in database result set.');
20+
}, E_USER_NOTICE);
2121

2222
$res->fetch();
2323
});
@@ -35,3 +35,12 @@ test(function () use ($context, $driverName) { // tests closeCursor()
3535
foreach ($res as $row) {}
3636
}
3737
});
38+
39+
test(function () use ($context, $driverName) {
40+
41+
$result = $context->query('SELECT book.id, author.id, author.name, translator.name FROM book JOIN author ON (author.id = book.author_id) JOIN author translator ON (translator.id = book.translator_id)');
42+
//Found duplicate columns in database result set: 'id' from book, author; 'name' from author, translator.
43+
Assert::error(function() use($result) {
44+
iterator_to_array($result);
45+
}, E_USER_NOTICE);
46+
});

tests/Database/Table/Table.join.phpt

+2-2
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ test(function () use ($context) {
8282
});
8383

8484

85-
test(function () use ($connection, $structure) {
85+
test(function () use ($connection, $structure, $driverName) {
8686
$context = new Nette\Database\Context(
8787
$connection,
8888
$structure,
@@ -92,5 +92,5 @@ test(function () use ($connection, $structure) {
9292
$books = $context->table('book')->select('book.*, author.name, translator.name');
9393
Assert::error(function() use($books) {
9494
iterator_to_array($books);
95-
}, E_USER_NOTICE, 'Found duplicate columns in database result set.');
95+
}, E_USER_NOTICE);
9696
});

0 commit comments

Comments
 (0)