diff --git a/lib/Doctrine/ORM/Query/SqlWalker.php b/lib/Doctrine/ORM/Query/SqlWalker.php index 8e69389d1..c577bc9a1 100644 --- a/lib/Doctrine/ORM/Query/SqlWalker.php +++ b/lib/Doctrine/ORM/Query/SqlWalker.php @@ -842,7 +842,18 @@ class SqlWalker implements TreeWalker $this->_rsm->addScalarResult($columnAlias, $resultAlias); } else if ($expr instanceof AST\Subselect) { - $sql .= $this->walkSubselect($expr); + if ( ! $selectExpression->fieldIdentificationVariable) { + $resultAlias = $this->_scalarResultCounter++; + } else { + $resultAlias = $selectExpression->fieldIdentificationVariable; + } + + $columnAlias = 'sclr' . $this->_aliasCounter++; + $sql .= '(' . $this->walkSubselect($expr) . ') AS '.$columnAlias; + $this->_scalarResultAliasMap[$resultAlias] = $columnAlias; + + $columnAlias = $this->_platform->getSqlResultCasing($columnAlias); + $this->_rsm->addScalarResult($columnAlias, $resultAlias); } else if ($expr instanceof AST\Functions\FunctionNode) { if ( ! $selectExpression->fieldIdentificationVariable) { @@ -1045,8 +1056,8 @@ class SqlWalker implements TreeWalker } else { $alias = $simpleSelectExpression->fieldIdentificationVariable; } - - $sql .= $this->walkAggregateExpression($expr) . ' AS dctrn__' . $alias; + + $sql .= ' ' . $this->walkAggregateExpression($expr) . ' AS dctrn__' . $alias; } else { // IdentificationVariable // FIXME: Composite key support, or select all columns? Does that make sense diff --git a/tests/Doctrine/Tests/ORM/Functional/AdvancedDqlQueryTest.php b/tests/Doctrine/Tests/ORM/Functional/AdvancedDqlQueryTest.php new file mode 100644 index 000000000..caef30600 --- /dev/null +++ b/tests/Doctrine/Tests/ORM/Functional/AdvancedDqlQueryTest.php @@ -0,0 +1,157 @@ + + */ +class AdvancedDqlQueryTest extends \Doctrine\Tests\OrmFunctionalTestCase +{ + protected function setUp() + { + $this->useModelSet('company'); + parent::setUp(); + + $this->generateFixture(); + } + + public function testAggregateWithHavingClause() + { + $dql = 'SELECT p.department, AVG(p.salary) AS avgSalary '. + 'FROM Doctrine\Tests\Models\Company\CompanyEmployee p '. + 'GROUP BY p.department HAVING SUM(p.salary) > 200000'; + + $result = $this->_em->createQuery($dql)->getScalarResult(); + + $this->assertEquals(2, count($result)); + $this->assertEquals('IT', $result[0]['department']); + $this->assertEquals(150000, $result[0]['avgSalary']); + $this->assertEquals('IT2', $result[1]['department']); + $this->assertEquals(600000, $result[1]['avgSalary']); + } + + public function testOrderByResultVariableCollectionSize() + { + $dql = 'SELECT p.name, size(p.friends) AS friends ' . + 'FROM Doctrine\Tests\Models\Company\CompanyPerson p ' . + 'WHERE p.friends IS NOT EMPTY ' . + 'ORDER BY friends DESC, p.name DESC'; + + $result = $this->_em->createQuery($dql)->getScalarResult(); + + $this->assertEquals(4, count($result)); + + $this->assertEquals("Jonathan W.", $result[0]['name']); + $this->assertEquals(3, $result[0]['friends']); + + $this->assertEquals('Guilherme B.', $result[1]['name']); + $this->assertEquals(2, $result[1]['friends']); + + $this->assertEquals('Benjamin E.', $result[2]['name']); + $this->assertEquals(2, $result[2]['friends']); + + $this->assertEquals('Roman B.', $result[3]['name']); + $this->assertEquals(1, $result[3]['friends']); + } + + public function testIsNullAssocation() + { + $dql = 'SELECT p FROM Doctrine\Tests\Models\Company\CompanyPerson p '. + 'WHERE p.spouse IS NULL'; + $result = $this->_em->createQuery($dql)->getResult(); + + $this->assertEquals(2, count($result)); + $this->assertTrue($result[0]->getId() > 0); + $this->assertNull($result[0]->getSpouse()); + + $this->assertTrue($result[1]->getId() > 0); + $this->assertNull($result[1]->getSpouse()); + } + + public function testSelectSubselect() + { + $dql = 'SELECT p, (SELECT c.brand FROM Doctrine\Tests\Models\Company\CompanyCar c WHERE p.car.id = c.id) brandName '. + 'FROM Doctrine\Tests\Models\Company\CompanyManager p'; + $result = $this->_em->createQuery($dql)->getArrayResult(); + + $this->assertEquals(1, count($result)); + $this->assertEquals("Caramba", $result[0]['brandName']); + } + + /*public function testGroupByMultipleFields() + { + $dql = 'SELECT p.department, p.name, count(p.id) FROM Doctrine\Tests\Models\Company\CompanyEmployee p '. + 'GROUP BY p.department, p.name'; + $result = $this->_em->createQuery($dql)->getResult(); + }*/ + + /** + public function testUpdateAs() + { + $dql = 'UPDATE Doctrine\Tests\Models\Company\CompanyEmployee AS p SET p.salary = 1'; + $this->_em->createQuery($dql)->getResult(); + + $this->assertTrue(count($this->_em->createQuery( + 'SELECT count(p) FROM Doctrine\Tests\Models\Company\CompanyEmployee p WHERE p.salary = 1')->getResult()) > 0); + }*/ + + /*public function testDeleteAs() + { + $dql = 'DELETE Doctrine\Tests\Models\Company\CompanyEmployee AS p'; + $this->_em->createQuery($dql)->getResult(); + + $this->assertEquals(0, count($this->_em->createQuery( + 'SELECT count(p) FROM Doctrine\Tests\Models\Company\CompanyEmployee p')->getResult())); + }*/ + + public function generateFixture() + { + $car = new CompanyCar('Caramba'); + + $manager1 = new CompanyManager(); + $manager1->setName('Roman B.'); + $manager1->setTitle('Foo'); + $manager1->setDepartment('IT'); + $manager1->setSalary(100000); + $manager1->setCar($car); + + $person2 = new CompanyEmployee(); + $person2->setName('Benjamin E.'); + $person2->setDepartment('IT'); + $person2->setSalary(200000); + + $person3 = new CompanyEmployee(); + $person3->setName('Guilherme B.'); + $person3->setDepartment('IT2'); + $person3->setSalary(400000); + + $person4 = new CompanyEmployee(); + $person4->setName('Jonathan W.'); + $person4->setDepartment('IT2'); + $person4->setSalary(800000); + + $person2->setSpouse($person3); + + $manager1->addFriend($person4); + $person2->addFriend($person3); + $person2->addFriend($person4); + $person3->addFriend($person4); + + $this->_em->persist($car); + $this->_em->persist($manager1); + $this->_em->persist($person2); + $this->_em->persist($person3); + $this->_em->persist($person4); + $this->_em->flush(); + $this->_em->clear(); + } +} \ No newline at end of file diff --git a/tests/Doctrine/Tests/ORM/Functional/AllTests.php b/tests/Doctrine/Tests/ORM/Functional/AllTests.php index 81b67c1f2..72eaf6060 100644 --- a/tests/Doctrine/Tests/ORM/Functional/AllTests.php +++ b/tests/Doctrine/Tests/ORM/Functional/AllTests.php @@ -31,6 +31,7 @@ class AllTests $suite->addTestSuite('Doctrine\Tests\ORM\Functional\ResultCacheTest'); $suite->addTestSuite('Doctrine\Tests\ORM\Functional\QueryTest'); $suite->addTestSuite('Doctrine\Tests\ORM\Functional\QueryDqlFunctionTest'); + $suite->addTestSuite('Doctrine\Tests\ORM\Functional\AdvancedDqlQueryTest'); $suite->addTestSuite('Doctrine\Tests\ORM\Functional\OneToOneUnidirectionalAssociationTest'); $suite->addTestSuite('Doctrine\Tests\ORM\Functional\OneToOneBidirectionalAssociationTest'); $suite->addTestSuite('Doctrine\Tests\ORM\Functional\OneToManyBidirectionalAssociationTest'); diff --git a/tests/Doctrine/Tests/ORM/Query/SelectSqlGenerationTest.php b/tests/Doctrine/Tests/ORM/Query/SelectSqlGenerationTest.php index 4ae0745d6..1274270d1 100644 --- a/tests/Doctrine/Tests/ORM/Query/SelectSqlGenerationTest.php +++ b/tests/Doctrine/Tests/ORM/Query/SelectSqlGenerationTest.php @@ -324,7 +324,7 @@ class SelectSqlGenerationTest extends \Doctrine\Tests\OrmTestCase 'SELECT c0_.id AS id0 FROM cms_users c0_ WHERE EXISTS (SELECT c1_.phonenumber FROM cms_phonenumbers c1_ WHERE c1_.phonenumber = c0_.id)' ); } - + public function testSupportsMemberOfExpression() { // "Get all users who have $phone as a phonenumber." (*cough* doesnt really make sense...) @@ -577,4 +577,12 @@ class SelectSqlGenerationTest extends \Doctrine\Tests\OrmTestCase "ORDER BY r1_.departureDate ASC" ); } + + public function testSubselectInSelect() + { + $this->assertSqlGeneration( + "SELECT u.name, (SELECT COUNT(p.phonenumber) FROM Doctrine\Tests\Models\CMS\CmsPhonenumber p WHERE p.phonenumber = 1234) pcount FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.name = 'jon'", + "SELECT c0_.name AS name0, (SELECT COUNT(c1_.phonenumber) AS dctrn__ FROM cms_phonenumbers c1_ WHERE c1_.phonenumber = 1234) AS pcount FROM cms_users c0_ WHERE c0_.name = 'jon'" + ); + } }