diff --git a/lib/Doctrine/ORM/Query/Parser.php b/lib/Doctrine/ORM/Query/Parser.php index 4caee210c..a5e1fa1ab 100644 --- a/lib/Doctrine/ORM/Query/Parser.php +++ b/lib/Doctrine/ORM/Query/Parser.php @@ -1328,6 +1328,10 @@ class Parser $token = $this->_lexer->lookahead; $identVariable = $this->IdentificationVariable(); + if (!isset($this->_queryComponents[$identVariable])) { + $this->semanticalError('Cannot group by undefined identification variable.'); + } + return $identVariable; } diff --git a/lib/Doctrine/ORM/Query/QueryException.php b/lib/Doctrine/ORM/Query/QueryException.php index f9dfd0823..aafe1e9d7 100644 --- a/lib/Doctrine/ORM/Query/QueryException.php +++ b/lib/Doctrine/ORM/Query/QueryException.php @@ -75,8 +75,7 @@ class QueryException extends \Doctrine\ORM\ORMException public static function invalidPathExpression($pathExpr) { return new self( - "Invalid PathExpression '" . $pathExpr->identificationVariable . - "." . implode('.', $pathExpr->parts) . "'." + "Invalid PathExpression '" . $pathExpr->identificationVariable . "." . $pathExpr->field . "'." ); } diff --git a/lib/Doctrine/ORM/Query/SqlWalker.php b/lib/Doctrine/ORM/Query/SqlWalker.php index 5be2ee287..84a4f8308 100644 --- a/lib/Doctrine/ORM/Query/SqlWalker.php +++ b/lib/Doctrine/ORM/Query/SqlWalker.php @@ -1254,9 +1254,25 @@ class SqlWalker implements TreeWalker */ public function walkGroupByClause($groupByClause) { - return ' GROUP BY ' . implode( - ', ', array_map(array($this, 'walkGroupByItem'), $groupByClause->groupByItems) - ); + $sql = ''; + foreach ($groupByClause->groupByItems AS $groupByItem) { + if (is_string($groupByItem)) { + foreach ($this->_queryComponents[$groupByItem]['metadata']->identifier AS $idField) { + if ($sql != '') { + $sql .= ', '; + } + $groupByItem = new AST\PathExpression(AST\PathExpression::TYPE_STATE_FIELD, $groupByItem, $idField); + $groupByItem->type = AST\PathExpression::TYPE_STATE_FIELD; + $sql .= $this->walkGroupByItem($groupByItem); + } + } else { + if ($sql != '') { + $sql .= ', '; + } + $sql .= $this->walkGroupByItem($groupByItem); + } + } + return ' GROUP BY ' . $sql; } /** diff --git a/tests/Doctrine/Tests/ORM/Query/LanguageRecognitionTest.php b/tests/Doctrine/Tests/ORM/Query/LanguageRecognitionTest.php index fae0d7350..ff9d94b1f 100644 --- a/tests/Doctrine/Tests/ORM/Query/LanguageRecognitionTest.php +++ b/tests/Doctrine/Tests/ORM/Query/LanguageRecognitionTest.php @@ -496,6 +496,30 @@ class LanguageRecognitionTest extends \Doctrine\Tests\OrmTestCase $this->assertInvalidDQL('SELECT g FROM Doctrine\Tests\Models\CMS\CmsUser u JOIN u.groups g'); } + /** + * @group DDC-1053 + */ + public function testGroupBy() + { + $this->assertValidDQL('SELECT g.id, count(u.id) FROM Doctrine\Tests\Models\CMS\CmsGroup g JOIN g.users u GROUP BY g.id'); + } + + /** + * @group DDC-1053 + */ + public function testGroupByIdentificationVariable() + { + $this->assertValidDQL('SELECT g, count(u.id) FROM Doctrine\Tests\Models\CMS\CmsGroup g JOIN g.users u GROUP BY g'); + } + + /** + * @group DDC-1053 + */ + public function testGroupByUnknownIdentificationVariable() + { + $this->assertInvalidDQL('SELECT g, count(u.id) FROM Doctrine\Tests\Models\CMS\CmsGroup g JOIN g.users u GROUP BY m'); + } + /** * @group DDC-117 */ diff --git a/tests/Doctrine/Tests/ORM/Query/SelectSqlGenerationTest.php b/tests/Doctrine/Tests/ORM/Query/SelectSqlGenerationTest.php index 7b9cb4815..08fb9edb0 100644 --- a/tests/Doctrine/Tests/ORM/Query/SelectSqlGenerationTest.php +++ b/tests/Doctrine/Tests/ORM/Query/SelectSqlGenerationTest.php @@ -851,6 +851,28 @@ class SelectSqlGenerationTest extends \Doctrine\Tests\OrmTestCase 'SELECT f0_.id AS id0, f0_.extension AS extension1, f0_.name AS name2 FROM "file" f0_ INNER JOIN Directory d1_ ON f0_.parentDirectory_id = d1_.id WHERE f0_.id = ?' ); } + + /** + * @group DDC-1053 + */ + public function testGroupBy() + { + $this->assertSqlGeneration( + 'SELECT g.id, count(u.id) FROM Doctrine\Tests\Models\CMS\CmsGroup g JOIN g.users u GROUP BY g.id', + 'SELECT c0_.id AS id0, count(c1_.id) AS sclr1 FROM cms_groups c0_ INNER JOIN cms_users_groups c2_ ON c0_.id = c2_.group_id INNER JOIN cms_users c1_ ON c1_.id = c2_.user_id GROUP BY c0_.id' + ); + } + + /** + * @group DDC-1053 + */ + public function testGroupByIdentificationVariable() + { + $this->assertSqlGeneration( + 'SELECT g, count(u.id) FROM Doctrine\Tests\Models\CMS\CmsGroup g JOIN g.users u GROUP BY g', + 'SELECT c0_.id AS id0, c0_.name AS name1, count(c1_.id) AS sclr2 FROM cms_groups c0_ INNER JOIN cms_users_groups c2_ ON c0_.id = c2_.group_id INNER JOIN cms_users c1_ ON c1_.id = c2_.user_id GROUP BY c0_.id' + ); + } }