Permalink
Browse files

Merge pull request #304 from yethee/dbal-442

Fix for DBAL-442
  • Loading branch information...
2 parents a666b34 + 9e4d207 commit 99574240f332a814ec193b6e7a88abb6a457f061 @guilhermeblanco guilhermeblanco committed Apr 14, 2013
Showing with 48 additions and 25 deletions.
  1. +29 −24 lib/Doctrine/DBAL/Query/QueryBuilder.php
  2. +19 −1 tests/Doctrine/Tests/DBAL/Query/QueryBuilderTest.php
@@ -946,35 +946,22 @@ private function getSQLForSelect()
$query = 'SELECT ' . implode(', ', $this->sqlParts['select']) . ' FROM ';
$fromClauses = array();
- $joinsPending = true;
- $joinAliases = array();
-
+ $knownAliases = array();
+
// Loop through all FROM clauses
foreach ($this->sqlParts['from'] as $from) {
- $fromClause = $from['table'] . ' ' . $from['alias'];
-
- if ($joinsPending && isset($this->sqlParts['join'][$from['alias']])) {
- 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;
- }
-
+ $knownAliases[$from['alias']] = true;
+ $fromClause = $from['table'] . ' ' . $from['alias']
+ . $this->getSQLForJoins($from['alias'], $knownAliases);
+
$fromClauses[$from['alias']] = $fromClause;
}
- // loop through all JOIN clauses for validation purpose
- $knownAliases = array_merge($fromClauses,$joinAliases);
- foreach ($this->sqlParts['join'] as $fromAlias => $joins) {
- if ( ! isset($knownAliases[$fromAlias]) ) {
- throw QueryException::unknownAlias($fromAlias, array_keys($knownAliases));
- }
- }
+ foreach ($this->sqlParts['join'] as $fromAlias => $joins) {
+ if ( ! isset($knownAliases[$fromAlias]) ) {
+ throw QueryException::unknownAlias($fromAlias, array_keys($knownAliases));
+ }
+ }
$query .= implode(', ', $fromClauses)
. ($this->sqlParts['where'] !== null ? ' WHERE ' . ((string) $this->sqlParts['where']) : '')
@@ -1091,4 +1078,22 @@ public function createPositionalParameter($value, $type = \PDO::PARAM_STR)
$this->setParameter($this->boundCounter, $value, $type);
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 @@ public function testReferenceJoinFromJoin()
->innerJoin('nt', 'node', 'n', 'nt.node = n.id')
->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());
}
@@ -584,4 +584,22 @@ public function testSelectFromMasterWithWhereOnJoinedTables()
$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());
+ }
}

0 comments on commit 9957424

Please sign in to comment.