Skip to content

Commit

Permalink
ResultSet: improved error message on duplicated names in select state…
Browse files Browse the repository at this point in the history
…ment
  • Loading branch information
Unlink authored and dg committed Jun 27, 2016
1 parent 077916c commit d9fd67a
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 7 deletions.
23 changes: 23 additions & 0 deletions src/Database/Helpers.php
Original file line number Diff line number Diff line change
Expand Up @@ -266,4 +266,27 @@ public static function toPairs(array $rows, $key = NULL, $value = NULL)
return $return;
}


/**
* Finds duplicate columns in select statement
* @param \PDOStatement
* @return string
*/
public static function findDuplicates(\PDOStatement $statement)
{
$cols = [];
for ($i = 0; $i < $statement->columnCount(); $i++) {
$meta = $statement->getColumnMeta($i);
$cols[$meta['name']][] = isset($meta['table']) ? $meta['table'] : '';
}
$duplicates = [];
foreach ($cols as $name => $tables) {
if (count($tables) > 1) {
$tables = array_filter(array_unique($tables));
$duplicates[] = "'$name'" . ($tables ? ' (from ' . implode(', ', $tables) . ')' : '');
}
}
return implode(', ', $duplicates);
}

}
8 changes: 4 additions & 4 deletions src/Database/ResultSet.php
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,10 @@ public function fetch()
if (!$data) {
$this->pdoStatement->closeCursor();
return FALSE;

} elseif ($this->result === NULL && count($data) !== $this->pdoStatement->columnCount()) {
$duplicates = Helpers::findDuplicates($this->pdoStatement);
trigger_error("Found duplicate columns in database result set: $duplicates.", E_USER_NOTICE);
}

$row = new Row;
Expand All @@ -262,10 +266,6 @@ public function fetch()
}
}

if ($this->result === NULL && count($data) !== $this->pdoStatement->columnCount()) {
trigger_error('Found duplicate columns in database result set.', E_USER_NOTICE);
}

$this->resultKey++;
return $this->result = $row;
}
Expand Down
45 changes: 42 additions & 3 deletions tests/Database/ResultSet.fetch().phpt
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,27 @@ require __DIR__ . '/connect.inc.php'; // create $connection
Nette\Database\Helpers::loadFromFile($connection, __DIR__ . "/files/{$driverName}-nette_test1.sql");


test(function () use ($context) {
test(function () use ($context, $driverName) {
$res = $context->query('SELECT name, name FROM author');

switch ($driverName) {
case 'mysql':
$message = "Found duplicate columns in database result set: 'name' (from author).";
break;
case 'pgsql':
$message = "Found duplicate columns in database result set: 'name'%a%";
break;
case 'sqlite':
$message = "Found duplicate columns in database result set: 'name' (from author).";
break;
case 'sqlsrv':
$message = "Found duplicate columns in database result set: 'name'.";
break;
default:
Assert::fail("Unsupported driver $driverName");
}
Assert::error(function () use ($res) {
$res->fetch();
}, E_USER_NOTICE, 'Found duplicate columns in database result set.');
}, E_USER_NOTICE, $message);

$res->fetch();
});
Expand All @@ -35,3 +50,27 @@ test(function () use ($context, $driverName) { // tests closeCursor()
foreach ($res as $row) {}
}
});


test(function () use ($context, $driverName) {
$res = $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)');
switch ($driverName) {
case 'mysql':
$message = "Found duplicate columns in database result set: 'id' (from book, author), 'name' (from author, translator).";
break;
case 'pgsql':
$message = "Found duplicate columns in database result set: 'id'%a% 'name'%a%";
break;
case 'sqlite':
$message = "Found duplicate columns in database result set: 'id' (from book, author), 'name' (from author).";
break;
case 'sqlsrv':
$message = "Found duplicate columns in database result set: 'id', 'name'.";
break;
default:
Assert::fail("Unsupported driver $driverName");
}
Assert::error(function() use ($res) {
$res->fetch();
}, E_USER_NOTICE, $message);
});

0 comments on commit d9fd67a

Please sign in to comment.