Browse files

Fixed Aggregate functions in the Limit and WhereIn walkers

  • Loading branch information...
1 parent 3b407e6 commit 1b6062432b53e38ec66871dab0a365c1ac0df14c @MitMaro MitMaro committed Apr 29, 2011
View
100 lib/DoctrineExtensions/Paginate/LimitSubqueryWalker.php
@@ -18,10 +18,10 @@
namespace DoctrineExtensions\Paginate;
use Doctrine\ORM\Query\TreeWalkerAdapter,
- Doctrine\ORM\Query\AST\SelectStatement,
- Doctrine\ORM\Query\AST\SimpleSelectExpression,
- Doctrine\ORM\Query\AST\PathExpression,
- Doctrine\ORM\Query\AST\AggregateExpression;
+ Doctrine\ORM\Query\AST\SelectStatement,
+ Doctrine\ORM\Query\AST\SimpleSelectExpression,
+ Doctrine\ORM\Query\AST\PathExpression,
+ Doctrine\ORM\Query\AST\AggregateExpression;
/**
* Replaces the selectClause of the AST with a SELECT DISTINCT root.id equivalent
@@ -34,47 +34,53 @@
*/
class LimitSubqueryWalker extends TreeWalkerAdapter
{
- /**
- * Walks down a SelectStatement AST node, modifying it to retrieve DISTINCT ids
- * of the root Entity
- *
- * @param SelectStatement $AST
- * @return void
- */
- public function walkSelectStatement(SelectStatement $AST)
- {
- $parent = null;
- $parentName = null;
- foreach ($this->_getQueryComponents() AS $dqlAlias => $qComp) {
- if ($qComp['parent'] === null && $qComp['nestingLevel'] == 0) {
- $parent = $qComp;
- $parentName = $dqlAlias;
- break;
- }
- }
+ /**
+ * Walks down a SelectStatement AST node, modifying it to retrieve DISTINCT ids
+ * of the root Entity
+ *
+ * @param SelectStatement $AST
+ * @return void
+ */
+ public function walkSelectStatement(SelectStatement $AST)
+ {
+ $parent = null;
+ $parentName = null;
+ foreach ($this->_getQueryComponents() AS $dqlAlias => $qComp) {
+
+ // skip mixed data in query
+ if (isset($qComp['resultVariable'])) {
+ continue;
+ }
+
+ if ($qComp['parent'] === null && $qComp['nestingLevel'] == 0) {
+ $parent = $qComp;
+ $parentName = $dqlAlias;
+ break;
+ }
+ }
- $pathExpression = new PathExpression(
- PathExpression::TYPE_STATE_FIELD | PathExpression::TYPE_SINGLE_VALUED_ASSOCIATION, $parentName,
- $parent['metadata']->getSingleIdentifierFieldName()
- );
- $pathExpression->type = PathExpression::TYPE_STATE_FIELD;
-
- $AST->selectClause->selectExpressions = array(
- new SimpleSelectExpression($pathExpression)
- );
-
- if (isset($AST->orderByClause)) {
- foreach($AST->orderByClause->orderByItems as $item) {
- $pathExpression = new PathExpression(
- PathExpression::TYPE_STATE_FIELD | PathExpression::TYPE_SINGLE_VALUED_ASSOCIATION,
- $item->expression->identificationVariable,
- $item->expression->field
- );
- $pathExpression->type = PathExpression::TYPE_STATE_FIELD;
- $AST->selectClause->selectExpressions[] = new SimpleSelectExpression($pathExpression);
- }
- }
-
- $AST->selectClause->isDistinct = true;
- }
-}
+ $pathExpression = new PathExpression(
+ PathExpression::TYPE_STATE_FIELD | PathExpression::TYPE_SINGLE_VALUED_ASSOCIATION, $parentName,
+ $parent['metadata']->getSingleIdentifierFieldName()
+ );
+ $pathExpression->type = PathExpression::TYPE_STATE_FIELD;
+
+ $AST->selectClause->selectExpressions = array(
+ new SimpleSelectExpression($pathExpression)
+ );
+
+ if (isset($AST->orderByClause)) {
+ foreach($AST->orderByClause->orderByItems as $item) {
+ $pathExpression = new PathExpression(
+ PathExpression::TYPE_STATE_FIELD | PathExpression::TYPE_SINGLE_VALUED_ASSOCIATION,
+ $item->expression->identificationVariable,
+ $item->expression->field
+ );
+ $pathExpression->type = PathExpression::TYPE_STATE_FIELD;
+ $AST->selectClause->selectExpressions[] = new SimpleSelectExpression($pathExpression);
+ }
+ }
+
+ $AST->selectClause->isDistinct = true;
+ }
+}
View
6 lib/DoctrineExtensions/Paginate/WhereInWalker.php
@@ -55,6 +55,12 @@ public function walkSelectStatement(SelectStatement $AST)
$parent = null;
$parentName = null;
foreach ($this->_getQueryComponents() AS $dqlAlias => $qComp) {
+
+ // skip mixed data in query
+ if (isset($qComp['resultVariable'])) {
+ continue;
+ }
+
if ($qComp['parent'] === null && $qComp['nestingLevel'] == 0) {
$parent = $qComp;
$parentName = $dqlAlias;
View
131 tests/DoctrineExtensions/Paginate/LimitSubqueryWalkerTest.php
@@ -5,83 +5,96 @@
class LimitSubqueryWalkerTest extends \PHPUnit_Framework_TestCase
{
- public $entityManager = null;
-
- public function testLimitSubquery()
- {
- $query = $this->entityManager->createQuery(
- 'SELECT p, c, a FROM DoctrineExtensions\Paginate\MyBlogPost p JOIN p.category c JOIN p.author a');
- $limitQuery = clone $query;
- $limitQuery->setHint(Query::HINT_CUSTOM_TREE_WALKERS, array('DoctrineExtensions\Paginate\LimitSubqueryWalker'));
-
- $this->assertEquals(
- "SELECT DISTINCT m0_.id AS id0 FROM MyBlogPost m0_ INNER JOIN Category c1_ ON m0_.category_id = c1_.id INNER JOIN Author a2_ ON m0_.author_id = a2_.id",
- $limitQuery->getSql()
- );
- }
-
- public function testCreateLimitSubQuery()
- {
- $query = $this->entityManager->createQuery(
- 'SELECT p, c, a FROM DoctrineExtensions\Paginate\MyBlogPost p JOIN p.category c JOIN p.author a');
- $limitQuery = Paginate::createLimitSubQuery($query, 10, 20);
-
- $this->assertEquals(10, $limitQuery->getFirstResult());
- $this->assertEquals(20, $limitQuery->getMaxResults());
- $this->assertEquals(array('DoctrineExtensions\Paginate\LimitSubqueryWalker'), $limitQuery->getHint(Query::HINT_CUSTOM_TREE_WALKERS));
- }
-
- public function setUp()
- {
- $config = new \Doctrine\ORM\Configuration();
- $config->setMetadataCacheImpl(new \Doctrine\Common\Cache\ArrayCache);
- $config->setQueryCacheImpl(new \Doctrine\Common\Cache\ArrayCache);
- $config->setProxyDir(__DIR__ . '/_files');
- $config->setProxyNamespace('DoctrineExtensions\Paginate\Proxies');
- $config->setMetadataDriverImpl($config->newDefaultAnnotationDriver());
-
- $conn = array(
- 'driver' => 'pdo_sqlite',
- 'memory' => true,
- );
-
- $this->entityManager = \Doctrine\ORM\EntityManager::create($conn, $config);
- }
+ public $entityManager = null;
+
+ public function testLimitSubquery()
+ {
+ $query = $this->entityManager->createQuery(
+ 'SELECT p, c, a FROM DoctrineExtensions\Paginate\MyBlogPost p JOIN p.category c JOIN p.author a');
+ $limitQuery = clone $query;
+ $limitQuery->setHint(Query::HINT_CUSTOM_TREE_WALKERS, array('DoctrineExtensions\Paginate\LimitSubqueryWalker'));
+
+ $this->assertEquals(
+ "SELECT DISTINCT m0_.id AS id0 FROM MyBlogPost m0_ INNER JOIN Category c1_ ON m0_.category_id = c1_.id INNER JOIN Author a2_ ON m0_.author_id = a2_.id",
+ $limitQuery->getSql()
+ );
+ }
+
+ public function testCountQuery_MixedResultsWithName()
+ {
+ $query = $this->entityManager->createQuery(
+ 'SELECT a, sum(a.name) as foo FROM DoctrineExtensions\Paginate\Author a');
+ $limitQuery = clone $query;
+ $limitQuery->setHint(Query::HINT_CUSTOM_TREE_WALKERS, array('DoctrineExtensions\Paginate\LimitSubqueryWalker'));
+
+ $this->assertEquals(
+ "SELECT DISTINCT a0_.id AS id0 FROM Author a0_",
+ $limitQuery->getSql()
+ );
+ }
+
+ public function testCreateLimitSubQuery()
+ {
+ $query = $this->entityManager->createQuery(
+ 'SELECT p, c, a FROM DoctrineExtensions\Paginate\MyBlogPost p JOIN p.category c JOIN p.author a');
+ $limitQuery = Paginate::createLimitSubQuery($query, 10, 20);
+
+ $this->assertEquals(10, $limitQuery->getFirstResult());
+ $this->assertEquals(20, $limitQuery->getMaxResults());
+ $this->assertEquals(array('DoctrineExtensions\Paginate\LimitSubqueryWalker'), $limitQuery->getHint(Query::HINT_CUSTOM_TREE_WALKERS));
+ }
+
+ public function setUp()
+ {
+ $config = new \Doctrine\ORM\Configuration();
+ $config->setMetadataCacheImpl(new \Doctrine\Common\Cache\ArrayCache);
+ $config->setQueryCacheImpl(new \Doctrine\Common\Cache\ArrayCache);
+ $config->setProxyDir(__DIR__ . '/_files');
+ $config->setProxyNamespace('DoctrineExtensions\Paginate\Proxies');
+ $config->setMetadataDriverImpl($config->newDefaultAnnotationDriver());
+
+ $conn = array(
+ 'driver' => 'pdo_sqlite',
+ 'memory' => true,
+ );
+
+ $this->entityManager = \Doctrine\ORM\EntityManager::create($conn, $config);
+ }
}
/**
* @Entity
*/
class MyBlogPost
{
- /** @Id @column(type="integer") @generatedValue */
- public $id;
-
- /**
- * @ManyToOne(targetEntity="Author")
- */
- public $author;
-
- /**
- * @ManyToOne(targetEntity="Category")
- */
- public $category;
+ /** @Id @column(type="integer") @generatedValue */
+ public $id;
+
+ /**
+ * @ManyToOne(targetEntity="Author")
+ */
+ public $author;
+
+ /**
+ * @ManyToOne(targetEntity="Category")
+ */
+ public $category;
}
/**
* @Entity
*/
class MyAuthor
{
- /** @Id @column(type="integer") @generatedValue */
- public $id;
+ /** @Id @column(type="integer") @generatedValue */
+ public $id;
}
/**
* @Entity
*/
class MyCategory
{
- /** @id @column(type="integer") @generatedValue */
- public $id;
-}
+ /** @id @column(type="integer") @generatedValue */
+ public $id;
+}
View
16 tests/DoctrineExtensions/Paginate/WhereInWalkerTest.php
@@ -22,6 +22,22 @@ public function testWhereInQuery_NoWhere()
);
}
+ public function testCountQuery_MixedResultsWithName()
+ {
+ $query = $this->entityManager->createQuery(
+ 'SELECT a, sum(a.name) as foo FROM DoctrineExtensions\Paginate\Author a'
+ );
+ $whereInQuery = clone $query;
+ $whereInQuery->setHint(Query::HINT_CUSTOM_TREE_WALKERS, array('DoctrineExtensions\Paginate\WhereInWalker'));
+ $whereInQuery->setHint('id.count', 10);
+
+ $this->assertEquals(
+ "SELECT a0_.id AS id0, a0_.name AS name1, sum(a0_.name) AS sclr2 FROM Author a0_ WHERE a0_.id IN (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
+ $whereInQuery->getSql()
+ );
+ }
+
+
public function testWhereInQuery_SingleWhere()
{
$query = $this->entityManager->createQuery(

0 comments on commit 1b60624

Please sign in to comment.