Commit 3928ba9d authored by guilhermeblanco's avatar guilhermeblanco

[2.0] Added support to complex PathExpression in DQL queries

parent 20c84166
This diff is collapsed.
......@@ -414,9 +414,8 @@ class SqlWalker implements TreeWalker
switch ($pathExpr->type) {
case AST\PathExpression::TYPE_STATE_FIELD:
$parts = $pathExpr->parts;
$numParts = count($parts);
$dqlAlias = $pathExpr->identificationVariable;
$fieldName = $parts[$numParts - 1];
$fieldName = array_pop($parts);
$dqlAlias = $pathExpr->identificationVariable . (( ! empty($parts)) ? '.' . implode('.', $parts) : '');
$qComp = $this->_queryComponents[$dqlAlias];
$class = $qComp['metadata'];
......@@ -609,20 +608,18 @@ class SqlWalker implements TreeWalker
*/
public function walkOrderByItem($orderByItem)
{
$sql = '';
$expr = $orderByItem->expression;
if ($expr instanceof AST\PathExpression) {
$parts = $expr->parts;
$dqlAlias = $expr->identificationVariable;
$class = $this->_queryComponents[$dqlAlias]['metadata'];
$columnName = $class->getQuotedColumnName($parts[0], $this->_platform);
return $this->getSqlTableAlias($class->getTableName(), $dqlAlias) . '.'
. $columnName . ' ' . strtoupper($orderByItem->type);
$sql = $this->walkPathExpression($expr);
} else {
$columnName = $this->_queryComponents[$expr]['token']['value'];
return $this->_scalarResultAliasMap[$columnName] . ' ' . strtoupper($orderByItem->type);
$sql = $this->_scalarResultAliasMap[$columnName];
}
return $sql . ' ' . strtoupper($orderByItem->type);;
}
/**
......@@ -771,16 +768,15 @@ class SqlWalker implements TreeWalker
if ($expr instanceof AST\PathExpression) {
if ($expr->type == AST\PathExpression::TYPE_STATE_FIELD) {
$parts = $expr->parts;
$numParts = count($parts);
$dqlAlias = $expr->identificationVariable;
$fieldName = $parts[$numParts - 1];
$fieldName = array_pop($parts);
$dqlAlias = $expr->identificationVariable . (( ! empty($parts)) ? '.' . implode('.', $parts) : '');
$qComp = $this->_queryComponents[$dqlAlias];
$class = $qComp['metadata'];
if ( ! isset($this->_selectedClasses[$dqlAlias])) {
$this->_selectedClasses[$dqlAlias] = $class;
}
$sqlTableAlias = $this->getSqlTableAlias($class->getTableName(), $dqlAlias);
$columnName = $class->getQuotedColumnName($fieldName, $this->_platform);
$columnAlias = $this->getSqlColumnAlias($class->columnNames[$fieldName]);
......@@ -1004,17 +1000,8 @@ class SqlWalker implements TreeWalker
*/
public function walkAggregateExpression($aggExpression)
{
$sql = '';
$parts = $aggExpression->pathExpression->parts;
$dqlAlias = $aggExpression->pathExpression->identificationVariable;
$fieldName = $parts[0];
$qComp = $this->_queryComponents[$dqlAlias];
$columnName = $qComp['metadata']->getQuotedColumnName($fieldName, $this->_platform);
return $aggExpression->functionName . '(' . ($aggExpression->isDistinct ? 'DISTINCT ' : '')
. $this->getSqlTableAlias($qComp['metadata']->getTableName(), $dqlAlias) . '.'
. $columnName . ')';
. $this->walkPathExpression($aggExpression->pathExpression) . ')';
}
/**
......@@ -1038,12 +1025,7 @@ class SqlWalker implements TreeWalker
*/
public function walkGroupByItem(AST\PathExpression $pathExpr)
{
$parts = $pathExpr->parts;
$dqlAlias = $pathExpr->identificationVariable;
$qComp = $this->_queryComponents[$dqlAlias];
$columnName = $qComp['metadata']->getQuotedColumnName($parts[0], $this->_platform);
return $this->getSqlTableAlias($qComp['metadata']->getTableName(), $dqlAlias) . '.' . $columnName;
return $this->walkPathExpression($pathExpr);
}
/**
......@@ -1219,8 +1201,10 @@ class SqlWalker implements TreeWalker
$sql .= 'EXISTS (SELECT 1 FROM ';
$entityExpr = $collMemberExpr->entityExpression;
$collPathExpr = $collMemberExpr->collectionValuedPathExpression;
$parts = $collPathExpr->parts;
$dqlAlias = $collPathExpr->identificationVariable;
$fieldName = array_pop($parts);
$dqlAlias = $collPathExpr->identificationVariable . (( ! empty($parts)) ? '.' . implode('.', $parts) : '');
$class = $this->_queryComponents[$dqlAlias]['metadata'];
......@@ -1232,7 +1216,7 @@ class SqlWalker implements TreeWalker
throw DoctrineException::notImplemented();
}
$assoc = $class->associationMappings[$parts[0]];
$assoc = $class->associationMappings[$fieldName];
if ($assoc->isOneToMany()) {
$targetClass = $this->_em->getClassMetadata($assoc->targetEntityName);
......
......@@ -58,6 +58,25 @@ class LanguageRecognitionTest extends \Doctrine\Tests\OrmTestCase
return $parser->parse();
}
public function parseDqlForAST($dql, $hints = array())
{
$query = $this->_em->createQuery($dql);
$query->setHint(Query::HINT_FORCE_PARTIAL_LOAD, true);
$query->setDql($dql);
foreach ($hints as $key => $value) {
$query->setHint($key, $value);
}
$parser = new \Doctrine\ORM\Query\Parser($query);
// We do NOT test SQL output here. That only unnecessarily slows down the tests!
$parser->setCustomOutputTreeWalker('Doctrine\Tests\Mocks\MockTreeWalker');
$parser->parse();
return $parser->getAST();
}
public function testEmptyQueryString()
{
......@@ -84,6 +103,11 @@ class LanguageRecognitionTest extends \Doctrine\Tests\OrmTestCase
$this->assertValidDql('SELECT u, p FROM Doctrine\Tests\Models\CMS\CmsUser u JOIN u.phonenumbers p');
}
public function testSelectMultipleComponentsWithAsterisk2()
{
$this->assertValidDql('SELECT a.user.name FROM Doctrine\Tests\Models\CMS\CmsArticle a');
}
public function testSelectDistinctIsSupported()
{
$this->assertValidDql('SELECT DISTINCT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u');
......@@ -93,6 +117,11 @@ class LanguageRecognitionTest extends \Doctrine\Tests\OrmTestCase
{
$this->assertValidDql('SELECT COUNT(u.id) FROM Doctrine\Tests\Models\CMS\CmsUser u');
}
public function testDuplicatedAliasInAggregateFunction()
{
$this->assertInvalidDql('SELECT COUNT(u.id) AS num, SUM(u.id) AS num FROM Doctrine\Tests\Models\CMS\CmsUser u');
}
public function testAggregateFunctionWithDistinctInSelect()
{
......
......@@ -2,7 +2,8 @@
namespace Doctrine\Tests\ORM\Query;
use Doctrine\ORM\Query;
use Doctrine\ORM\Query,
Doctrine\Common\DoctrineException;
require_once __DIR__ . '/../../TestInit.php';
......@@ -22,7 +23,7 @@ class SelectSqlGenerationTest extends \Doctrine\Tests\OrmTestCase
$query->setHint(Query::HINT_FORCE_PARTIAL_LOAD, true);
parent::assertEquals($sqlToBeConfirmed, $query->getSql());
$query->free();
} catch (Doctrine_Exception $e) {
} catch (DoctrineException $e) {
$this->fail($e->getMessage());
}
}
......@@ -42,6 +43,22 @@ class SelectSqlGenerationTest extends \Doctrine\Tests\OrmTestCase
'SELECT c0_.id AS id0 FROM cms_users c0_'
);
}
public function testSupportsSelectForOneNestedField()
{
$this->assertSqlGeneration(
'SELECT a.user.id FROM Doctrine\Tests\Models\CMS\CmsArticle a',
'SELECT c0_.id AS id0 FROM cms_articles c1_ INNER JOIN cms_users c0_ ON c1_.user_id = c0_.id'
);
}
public function testSupportsSelectForAllNestedField()
{
$this->assertSqlGeneration(
'SELECT a FROM Doctrine\Tests\Models\CMS\CmsArticle a ORDER BY a.user.name ASC',
'SELECT c0_.id AS id0, c0_.topic AS topic1, c0_.text AS text2 FROM cms_articles c0_ INNER JOIN cms_users c1_ ON c0_.user_id = c1_.id ORDER BY c1_.name ASC'
);
}
public function testSupportsSelectForMultipleColumnsOfASingleComponent()
{
......
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