Commit 9e4d207e authored by Deni's avatar Deni

Fix for DBAL-442

parent a666b341
...@@ -946,35 +946,22 @@ class QueryBuilder ...@@ -946,35 +946,22 @@ class QueryBuilder
$query = 'SELECT ' . implode(', ', $this->sqlParts['select']) . ' FROM '; $query = 'SELECT ' . implode(', ', $this->sqlParts['select']) . ' FROM ';
$fromClauses = array(); $fromClauses = array();
$joinsPending = true; $knownAliases = array();
$joinAliases = array();
// Loop through all FROM clauses // Loop through all FROM clauses
foreach ($this->sqlParts['from'] as $from) { foreach ($this->sqlParts['from'] as $from) {
$fromClause = $from['table'] . ' ' . $from['alias']; $knownAliases[$from['alias']] = true;
$fromClause = $from['table'] . ' ' . $from['alias']
if ($joinsPending && isset($this->sqlParts['join'][$from['alias']])) { . $this->getSQLForJoins($from['alias'], $knownAliases);
foreach ($this->sqlParts['join'] as $joins) {
foreach ($joins as $join) {
$fromClause .= ' ' . strtoupper($join['joinType'])
. ' JOIN ' . $join['joinTable'] . ' ' . $join['joinAlias']
. ' ON ' . ((string) $join['joinCondition']);
$joinAliases[$join['joinAlias']] = true;
}
}
$joinsPending = false;
}
$fromClauses[$from['alias']] = $fromClause; $fromClauses[$from['alias']] = $fromClause;
} }
// loop through all JOIN clauses for validation purpose foreach ($this->sqlParts['join'] as $fromAlias => $joins) {
$knownAliases = array_merge($fromClauses,$joinAliases); if ( ! isset($knownAliases[$fromAlias]) ) {
foreach ($this->sqlParts['join'] as $fromAlias => $joins) { throw QueryException::unknownAlias($fromAlias, array_keys($knownAliases));
if ( ! isset($knownAliases[$fromAlias]) ) { }
throw QueryException::unknownAlias($fromAlias, array_keys($knownAliases)); }
}
}
$query .= implode(', ', $fromClauses) $query .= implode(', ', $fromClauses)
. ($this->sqlParts['where'] !== null ? ' WHERE ' . ((string) $this->sqlParts['where']) : '') . ($this->sqlParts['where'] !== null ? ' WHERE ' . ((string) $this->sqlParts['where']) : '')
...@@ -1091,4 +1078,22 @@ class QueryBuilder ...@@ -1091,4 +1078,22 @@ class QueryBuilder
$this->setParameter($this->boundCounter, $value, $type); $this->setParameter($this->boundCounter, $value, $type);
return "?"; return "?";
} }
private function getSQLForJoins($fromAlias, array &$knownAliases)
{
$sql = '';
if (isset($this->sqlParts['join'][$fromAlias])) {
foreach ($this->sqlParts['join'][$fromAlias] as $join) {
$sql .= ' ' . strtoupper($join['joinType'])
. ' JOIN ' . $join['joinTable'] . ' ' . $join['joinAlias']
. ' ON ' . ((string) $join['joinCondition']);
$knownAliases[$join['joinAlias']] = true;
$sql .= $this->getSQLForJoins($join['joinAlias'], $knownAliases);
}
}
return $sql;
}
} }
...@@ -563,7 +563,7 @@ class QueryBuilderTest extends \Doctrine\Tests\DbalTestCase ...@@ -563,7 +563,7 @@ class QueryBuilderTest extends \Doctrine\Tests\DbalTestCase
->innerJoin('nt', 'node', 'n', 'nt.node = n.id') ->innerJoin('nt', 'node', 'n', 'nt.node = n.id')
->where('nt.lang = :lang AND n.deleted != 1'); ->where('nt.lang = :lang AND n.deleted != 1');
$this->setExpectedException('Doctrine\DBAL\Query\QueryException', "The given alias 'invalid' is not part of any FROM or JOIN clause table. The currently registered aliases are: news, nv, nt, n."); $this->setExpectedException('Doctrine\DBAL\Query\QueryException', "The given alias 'invalid' is not part of any FROM or JOIN clause table. The currently registered aliases are: news, nv.");
$this->assertEquals('', $qb->getSQL()); $this->assertEquals('', $qb->getSQL());
} }
...@@ -584,4 +584,22 @@ class QueryBuilderTest extends \Doctrine\Tests\DbalTestCase ...@@ -584,4 +584,22 @@ class QueryBuilderTest extends \Doctrine\Tests\DbalTestCase
$this->assertEquals("SELECT COUNT(DISTINCT news.id) FROM newspages news INNER JOIN nodeversion nv ON nv.refId = news.id AND nv.refEntityname='Entity\\News' INNER JOIN nodetranslation nt ON nv.nodetranslation = nt.id INNER JOIN node n ON nt.node = n.id WHERE (nt.lang = ?) AND (n.deleted = 0)", $qb->getSQL()); $this->assertEquals("SELECT COUNT(DISTINCT news.id) FROM newspages news INNER JOIN nodeversion nv ON nv.refId = news.id AND nv.refEntityname='Entity\\News' INNER JOIN nodetranslation nt ON nv.nodetranslation = nt.id INNER JOIN node n ON nt.node = n.id WHERE (nt.lang = ?) AND (n.deleted = 0)", $qb->getSQL());
} }
/**
* @group DBAL-442
*/
public function testSelectWithMultipleFromAndJoins()
{
$qb = new QueryBuilder($this->conn);
$qb->select('DISTINCT u.id')
->from('users', 'u')
->from('articles', 'a')
->innerJoin('u', 'permissions', 'p', 'p.user_id = u.id')
->innerJoin('a', 'comments', 'c', 'c.article_id = a.id')
->where('u.id = a.user_id')
->andWhere('p.read = 1');
$this->assertEquals('SELECT DISTINCT u.id FROM users u INNER JOIN permissions p ON p.user_id = u.id, articles a INNER JOIN comments c ON c.article_id = a.id WHERE (u.id = a.user_id) AND (p.read = 1)', $qb->getSQL());
}
} }
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment