Commit 262855a6 authored by guilhermeblanco's avatar guilhermeblanco

[2.0] Refactorings in DQL parser to allow more granular enhancements scheduled...

[2.0] Refactorings in DQL parser to allow more granular enhancements scheduled for later versions. Fixed issues with missing validations of invalid ResultVariable, Unknown query components and Re-declaration of query compoenents.
parent 64f59a7a
...@@ -59,15 +59,6 @@ class PathExpression extends Node ...@@ -59,15 +59,6 @@ class PathExpression extends Node
public function dispatch($walker) public function dispatch($walker)
{ {
switch ($this->type) { return $walker->walkPathExpression($this);
case self::TYPE_STATE_FIELD:
return $walker->walkStateFieldPathExpression($this);
case self::TYPE_SINGLE_VALUED_ASSOCIATION:
return $walker->walkSingleValuedAssociationPathExpression($this);
case self::TYPE_COLLECTION_VALUED_ASSOCIATION:
return $walker->walkCollectionValuedAssociationPathExpression($this);
default:
throw new \Exception("Unexhaustive match.");
}
} }
} }
This diff is collapsed.
...@@ -21,6 +21,8 @@ ...@@ -21,6 +21,8 @@
namespace Doctrine\ORM\Query; namespace Doctrine\ORM\Query;
use Doctrine\ORM\Query\AST\PathExpression;
/** /**
* Description of QueryException * Description of QueryException
* *
...@@ -63,6 +65,14 @@ class QueryException extends \Doctrine\Common\DoctrineException ...@@ -63,6 +65,14 @@ class QueryException extends \Doctrine\Common\DoctrineException
{ {
return new self("Invalid parameter: token ".$key." is not defined in the query."); return new self("Invalid parameter: token ".$key." is not defined in the query.");
} }
public static function invalidPathExpression($pathExpr)
{
return new self(
"Invalid PathExpression '" . $pathExpr->identificationVariable .
"." . implode('.', $pathExpr->parts) . "'."
);
}
/** /**
* @param Doctrine\ORM\Mapping\AssociationMapping $assoc * @param Doctrine\ORM\Mapping\AssociationMapping $assoc
......
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
namespace Doctrine\ORM\Query; namespace Doctrine\ORM\Query;
use Doctrine\ORM\Query, use Doctrine\ORM\Query,
Doctrine\ORM\Query\QueryException,
Doctrine\Common\DoctrineException; Doctrine\Common\DoctrineException;
/** /**
...@@ -425,12 +426,35 @@ class SqlWalker implements TreeWalker ...@@ -425,12 +426,35 @@ class SqlWalker implements TreeWalker
$sql .= $class->getQuotedColumnName($fieldName, $this->_platform); $sql .= $class->getQuotedColumnName($fieldName, $this->_platform);
break; break;
case AST\PathExpression::TYPE_SINGLE_VALUED_ASSOCIATION:
// "u.Group" should be converted to:
// 1- IdentificationVariable is the owning side:
// Just append the condition: u.group_id = ?
/*$parts = $pathExpr->parts;
$numParts = count($parts);
$dqlAlias = $pathExpr->identificationVariable;
$fieldName = $parts[$numParts - 1];
$qComp = $this->_queryComponents[$dqlAlias];
$class = $qComp['metadata'];
$assoc = $class->associationMappings[$fieldName];
if ($assoc->isOwningSide) {
foreach ($assoc->)
$sql .= $this->walkIdentificationVariable($dqlAlias, $fieldName) . '.';
}
// 2- IdentificationVariable is the inverse side:
// Join required: INNER JOIN u.Group g
// Append condition: g.id = ?
break;*/
case AST\PathExpression::TYPE_COLLECTION_VALUED_ASSOCIATION: case AST\PathExpression::TYPE_COLLECTION_VALUED_ASSOCIATION:
throw DoctrineException::notImplemented(); throw DoctrineException::notImplemented();
default: default:
throw DoctrineException::invalidPathExpression($pathExpr->type); throw QueryException::invalidPathExpression($pathExpr);
} }
return $sql; return $sql;
......
...@@ -52,10 +52,6 @@ class DeleteSqlGenerationTest extends \Doctrine\Tests\OrmTestCase ...@@ -52,10 +52,6 @@ class DeleteSqlGenerationTest extends \Doctrine\Tests\OrmTestCase
parent::assertEquals($sqlToBeConfirmed, $query->getSql()); parent::assertEquals($sqlToBeConfirmed, $query->getSql());
$query->free(); $query->free();
} catch (\Exception $e) { } catch (\Exception $e) {
if ($debug) {
echo $e->getTraceAsString() . PHP_EOL;
}
$this->fail($e->getMessage()); $this->fail($e->getMessage());
} }
} }
......
<?php <?php
namespace Doctrine\Tests\ORM\Query; namespace Doctrine\Tests\ORM\Query;
use Doctrine\ORM\Query; use Doctrine\ORM\Query,
Doctrine\ORM\Query\QueryException;
require_once __DIR__ . '/../../TestInit.php'; require_once __DIR__ . '/../../TestInit.php';
...@@ -18,7 +19,7 @@ class LanguageRecognitionTest extends \Doctrine\Tests\OrmTestCase ...@@ -18,7 +19,7 @@ class LanguageRecognitionTest extends \Doctrine\Tests\OrmTestCase
{ {
try { try {
$parserResult = $this->parseDql($dql); $parserResult = $this->parseDql($dql);
} catch (\Exception $e) { } catch (QueryException $e) {
if ($debug) { if ($debug) {
echo $e->getTraceAsString() . PHP_EOL; echo $e->getTraceAsString() . PHP_EOL;
} }
...@@ -31,8 +32,9 @@ class LanguageRecognitionTest extends \Doctrine\Tests\OrmTestCase ...@@ -31,8 +32,9 @@ class LanguageRecognitionTest extends \Doctrine\Tests\OrmTestCase
{ {
try { try {
$parserResult = $this->parseDql($dql); $parserResult = $this->parseDql($dql);
$this->fail('No syntax errors were detected, when syntax errors were expected'); $this->fail('No syntax errors were detected, when syntax errors were expected');
} catch (\Exception $e) { } catch (QueryException $e) {
if ($debug) { if ($debug) {
echo $e->getMessage() . PHP_EOL; echo $e->getMessage() . PHP_EOL;
echo $e->getTraceAsString() . PHP_EOL; echo $e->getTraceAsString() . PHP_EOL;
...@@ -248,6 +250,16 @@ class LanguageRecognitionTest extends \Doctrine\Tests\OrmTestCase ...@@ -248,6 +250,16 @@ class LanguageRecognitionTest extends \Doctrine\Tests\OrmTestCase
$this->assertValidDql("SELECT u.id FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.name LIKE 'z|%' ESCAPE '|'"); $this->assertValidDql("SELECT u.id FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.name LIKE 'z|%' ESCAPE '|'");
} }
public function testFieldComparisonWithoutAlias()
{
$this->assertInvalidDql("SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE id = 1");
}
public function testDuplicatedAliasDeclaration()
{
$this->assertInvalidDql("SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u INNER JOIN u.articles u WHERE u.id = 1");
}
/*public function testImplicitJoinInWhereOnSingleValuedAssociationPathExpression() /*public function testImplicitJoinInWhereOnSingleValuedAssociationPathExpression()
{ {
// This should be allowed because avatar is a single-value association. // This should be allowed because avatar is a single-value association.
...@@ -288,7 +300,7 @@ class LanguageRecognitionTest extends \Doctrine\Tests\OrmTestCase ...@@ -288,7 +300,7 @@ class LanguageRecognitionTest extends \Doctrine\Tests\OrmTestCase
public function testDeleteAll() public function testDeleteAll()
{ {
$this->assertValidDql('DELETE FROM Doctrine\Tests\Models\CMS\CmsUser'); $this->assertValidDql('DELETE FROM Doctrine\Tests\Models\CMS\CmsUser u');
} }
public function testDeleteWithCondition() public function testDeleteWithCondition()
......
...@@ -464,16 +464,17 @@ class SelectSqlGenerationTest extends \Doctrine\Tests\OrmTestCase ...@@ -464,16 +464,17 @@ class SelectSqlGenerationTest extends \Doctrine\Tests\OrmTestCase
} }
/* Not yet implemented, needs more thought /* Not yet implemented, needs more thought */
public function testSingleValuedAssociationFieldInWhere() public function testSingleValuedAssociationFieldInWhere()
{ {
$this->assertSqlGeneration( /*$this->assertSqlGeneration(
"SELECT p FROM Doctrine\Tests\Models\CMS\CmsPhonenumber p WHERE p.user = ?1", "SELECT p FROM Doctrine\Tests\Models\CMS\CmsPhonenumber p WHERE p.user = ?1",
"SELECT c0_.phonenumber AS phonenumber0 FROM cms_phonenumbers c0_ WHERE c0_.user_id = ?" "SELECT c0_.id AS id0, c0_user_id AS user_id1, c0_.phonenumber AS phonenumber2 FROM cms_phonenumbers c0_ WHERE c0_.user_id = ?"
); );
$this->assertSqlGeneration( $this->assertSqlGeneration(
"SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.address = ?1", "SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.address = ?1",
"SELECT c0_.id AS id0, c0_.status AS status1, c0_.username AS username2, c0_.name AS name3 FROM cms_users c0_ WHERE c0_.id = (SELECT c1_.user_id FROM cms_addresses c1_ WHERE c1_.id = ?)" //"SELECT c0_.id AS id0, c0_.status AS status1, c0_.username AS username2, c0_.name AS name3 FROM cms_users c0_ WHERE c0_.id = (SELECT c1_.user_id FROM cms_addresses c1_ WHERE c1_.id = ?)"
); "SELECT c0_.id AS id0, c0_.status AS status1, c0_.username AS username2, c0_.name AS name3 FROM cms_users c0_ WHERE EXISTS (SELECT 1 FROM cms_addresses c1_ WHERE c1_.user_id = c0_.id AND c1_.id = ?)"
}*/ );*/
}
} }
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