Skip to content

Commit 95ead5a

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

File tree

4 files changed

+50
-4
lines changed

4 files changed

+50
-4
lines changed

src/Database/Helpers.php

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,4 +267,32 @@ 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+
if (isset($cols[$meta['name']])) {
283+
$cols[$meta['name']][] = $tableName;
284+
}
285+
else {
286+
$cols[$meta['name']] = [$tableName];
287+
}
288+
}
289+
$duplicates = '';
290+
foreach ($cols as $name => $tables) {
291+
if (count($tables) > 1) {
292+
$duplicates .= ($duplicates === '' ? '' : '; ')."'$name'".(($tmp = implode(', ', array_unique($tables))) != '' ? " from $tmp" : '');
293+
}
294+
}
295+
return $duplicates;
296+
}
297+
270298
}

src/Database/ResultSet.php

Lines changed: 2 additions & 1 deletion
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

Lines changed: 18 additions & 1 deletion
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,20 @@ 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+
if ($driverName == 'mysql') {
43+
$errorMsg = "'id' from book, author; 'name' from author, translator";
44+
}
45+
else if ($driverName == 'sqlite') {
46+
$errorMsg = "'id' from book, author; 'name' from author";
47+
}
48+
else {
49+
$errorMsg = "'id'; 'name'";
50+
}
51+
Assert::error(function() use($result) {
52+
iterator_to_array($result);
53+
}, E_USER_NOTICE, "Found duplicate columns in database result set: $errorMsg.");
54+
});

tests/Database/Table/Table.join.phpt

Lines changed: 2 additions & 2 deletions
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)