1
0
mirror of synced 2025-01-20 23:41:39 +03:00

Merge branch 'DDC-619'

This commit is contained in:
Guilherme Blanco 2010-07-23 01:56:38 -03:00
commit 5f109c5d6c
10 changed files with 90 additions and 174 deletions

View File

@ -46,10 +46,9 @@ class SizeFunction extends FunctionNode
public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker) public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker)
{ {
$dqlAlias = $this->collectionPathExpression->identificationVariable; $dqlAlias = $this->collectionPathExpression->identificationVariable;
$parts = $this->collectionPathExpression->parts; $assocField = $this->collectionPathExpression->field;
$assocField = array_pop($parts);
$qComp = $sqlWalker->getQueryComponent(implode('.', array_merge((array) $dqlAlias, $parts))); $qComp = $sqlWalker->getQueryComponent($dqlAlias);
$assoc = $qComp['metadata']->associationMappings[$assocField]; $assoc = $qComp['metadata']->associationMappings[$assocField];
$sql = ''; $sql = '';

View File

@ -23,11 +23,10 @@ namespace Doctrine\ORM\Query\AST;
* AssociationPathExpression ::= CollectionValuedPathExpression | SingleValuedAssociationPathExpression * AssociationPathExpression ::= CollectionValuedPathExpression | SingleValuedAssociationPathExpression
* SingleValuedPathExpression ::= StateFieldPathExpression | SingleValuedAssociationPathExpression * SingleValuedPathExpression ::= StateFieldPathExpression | SingleValuedAssociationPathExpression
* StateFieldPathExpression ::= SimpleStateFieldPathExpression | SimpleStateFieldAssociationPathExpression * StateFieldPathExpression ::= SimpleStateFieldPathExpression | SimpleStateFieldAssociationPathExpression
* SingleValuedAssociationPathExpression ::= IdentificationVariable "." {SingleValuedAssociationField "."}* SingleValuedAssociationField * SingleValuedAssociationPathExpression ::= IdentificationVariable "." SingleValuedAssociationField
* CollectionValuedPathExpression ::= IdentificationVariable "." {SingleValuedAssociationField "."}* CollectionValuedAssociationField * CollectionValuedPathExpression ::= IdentificationVariable "." CollectionValuedAssociationField
* StateField ::= {EmbeddedClassStateField "."}* SimpleStateField * StateField ::= {EmbeddedClassStateField "."}* SimpleStateField
* SimpleStateFieldPathExpression ::= IdentificationVariable "." StateField * SimpleStateFieldPathExpression ::= IdentificationVariable "." StateField
* SimpleStateFieldAssociationPathExpression ::= SingleValuedAssociationPathExpression "." StateField
* *
* @since 2.0 * @since 2.0
* @author Guilherme Blanco <guilhermeblanco@hotmail.com> * @author Guilherme Blanco <guilhermeblanco@hotmail.com>
@ -43,13 +42,13 @@ class PathExpression extends Node
public $type; public $type;
public $expectedType; public $expectedType;
public $identificationVariable; public $identificationVariable;
public $parts; public $field;
public function __construct($expectedType, $identificationVariable, array $parts) public function __construct($expectedType, $identificationVariable, $field = null)
{ {
$this->expectedType = $expectedType; $this->expectedType = $expectedType;
$this->identificationVariable = $identificationVariable; $this->identificationVariable = $identificationVariable;
$this->parts = $parts; $this->field = $field;
} }
public function dispatch($walker) public function dispatch($walker)

View File

@ -84,7 +84,7 @@ class MultiTableUpdateExecutor extends AbstractSqlExecutor
$updateSql = 'UPDATE ' . $class->getQuotedTableName($platform) . ' SET '; $updateSql = 'UPDATE ' . $class->getQuotedTableName($platform) . ' SET ';
foreach ($updateItems as $updateItem) { foreach ($updateItems as $updateItem) {
$field = $updateItem->pathExpression->parts[0]; $field = $updateItem->pathExpression->field;
if (isset($class->fieldMappings[$field]) && ! isset($class->fieldMappings[$field]['inherited']) || if (isset($class->fieldMappings[$field]) && ! isset($class->fieldMappings[$field]['inherited']) ||
isset($class->associationMappings[$field]) && ! $class->associationMappings[$field]->inherited) { isset($class->associationMappings[$field]) && ! $class->associationMappings[$field]->inherited) {
$newValue = $updateItem->newValue; $newValue = $updateItem->newValue;

View File

@ -490,6 +490,7 @@ class Parser
foreach ($this->_deferredPartialObjectExpressions as $deferredItem) { foreach ($this->_deferredPartialObjectExpressions as $deferredItem) {
$expr = $deferredItem['expression']; $expr = $deferredItem['expression'];
$class = $this->_queryComponents[$expr->identificationVariable]['metadata']; $class = $this->_queryComponents[$expr->identificationVariable]['metadata'];
foreach ($expr->partialFieldSet as $field) { foreach ($expr->partialFieldSet as $field) {
if ( ! isset($class->fieldMappings[$field])) { if ( ! isset($class->fieldMappings[$field])) {
$this->semanticalError( $this->semanticalError(
@ -498,6 +499,7 @@ class Parser
); );
} }
} }
if (array_intersect($class->identifier, $expr->partialFieldSet) != $class->identifier) { if (array_intersect($class->identifier, $expr->partialFieldSet) != $class->identifier) {
$this->semanticalError( $this->semanticalError(
"The partial field selection of class " . $class->name . " must contain the identifier.", "The partial field selection of class " . $class->name . " must contain the identifier.",
@ -548,9 +550,9 @@ class Parser
* *
* AssociationPathExpression ::= CollectionValuedPathExpression | SingleValuedAssociationPathExpression * AssociationPathExpression ::= CollectionValuedPathExpression | SingleValuedAssociationPathExpression
* SingleValuedPathExpression ::= StateFieldPathExpression | SingleValuedAssociationPathExpression * SingleValuedPathExpression ::= StateFieldPathExpression | SingleValuedAssociationPathExpression
* StateFieldPathExpression ::= IdentificationVariable "." StateField | SingleValuedAssociationPathExpression "." StateField * StateFieldPathExpression ::= IdentificationVariable "." StateField
* SingleValuedAssociationPathExpression ::= IdentificationVariable "." {SingleValuedAssociationField "."}* SingleValuedAssociationField * SingleValuedAssociationPathExpression ::= IdentificationVariable "." SingleValuedAssociationField
* CollectionValuedPathExpression ::= IdentificationVariable "." {SingleValuedAssociationField "."}* CollectionValuedAssociationField * CollectionValuedPathExpression ::= IdentificationVariable "." CollectionValuedAssociationField
* *
* @param array $deferredItem * @param array $deferredItem
* @param mixed $AST * @param mixed $AST
@ -561,35 +563,10 @@ class Parser
$pathExpression = $deferredItem['expression']; $pathExpression = $deferredItem['expression'];
$qComp = $this->_queryComponents[$pathExpression->identificationVariable]; $qComp = $this->_queryComponents[$pathExpression->identificationVariable];
$numParts = count($pathExpression->parts);
if ($numParts == 0) {
$pathExpression->parts = array($qComp['metadata']->identifier[0]);
$numParts++;
}
$parts = $pathExpression->parts;
$aliasIdentificationVariable = $pathExpression->identificationVariable;
$parentField = $pathExpression->identificationVariable;
$class = $qComp['metadata']; $class = $qComp['metadata'];
$fieldType = null;
$curIndex = 0;
foreach ($parts as $field) { if (($field = $pathExpression->field) === null) {
// Check if it is not in a state field $field = $pathExpression->field = $class->identifier[0];
if ($fieldType & AST\PathExpression::TYPE_STATE_FIELD) {
$this->semanticalError(
'Cannot navigate through state field named ' . $field . ' on ' . $parentField,
$deferredItem['token']
);
}
// Check if it is not a collection field
if ($fieldType & AST\PathExpression::TYPE_COLLECTION_VALUED_ASSOCIATION) {
$this->semanticalError(
'Cannot navigate through collection field named ' . $field . ' on ' . $parentField,
$deferredItem['token']
);
} }
// Check if field or association exists // Check if field or association exists
@ -600,46 +577,12 @@ class Parser
); );
} }
$parentField = $field;
if (isset($class->fieldMappings[$field])) { if (isset($class->fieldMappings[$field])) {
$fieldType = AST\PathExpression::TYPE_STATE_FIELD; $fieldType = AST\PathExpression::TYPE_STATE_FIELD;
} else { } else {
$assoc = $class->associationMappings[$field]; $assoc = $class->associationMappings[$field];
$class = $this->_em->getClassMetadata($assoc->targetEntityName); $class = $this->_em->getClassMetadata($assoc->targetEntityName);
if (
($curIndex != $numParts - 1) &&
! isset($this->_queryComponents[$aliasIdentificationVariable . '.' . $field])
) {
// Building queryComponent
$joinQueryComponent = array(
'metadata' => $class,
'parent' => $aliasIdentificationVariable,
'relation' => $assoc,
'map' => null,
'nestingLevel' => $this->_nestingLevel,
'token' => $deferredItem['token'],
);
// Create AST node
$joinVariableDeclaration = new AST\JoinVariableDeclaration(
new AST\Join(
AST\Join::JOIN_TYPE_INNER,
new AST\JoinAssociationPathExpression($aliasIdentificationVariable, $field),
$aliasIdentificationVariable . '.' . $field,
false
),
null
);
$AST->fromClause->identificationVariableDeclarations[0]->joinVariableDeclarations[] = $joinVariableDeclaration;
$this->_queryComponents[$aliasIdentificationVariable . '.' . $field] = $joinQueryComponent;
}
$aliasIdentificationVariable .= '.' . $field;
if ($assoc->isOneToOne()) { if ($assoc->isOneToOne()) {
$fieldType = AST\PathExpression::TYPE_SINGLE_VALUED_ASSOCIATION; $fieldType = AST\PathExpression::TYPE_SINGLE_VALUED_ASSOCIATION;
} else { } else {
@ -647,9 +590,6 @@ class Parser
} }
} }
++$curIndex;
}
// Validate if PathExpression is one of the expected types // Validate if PathExpression is one of the expected types
$expectedType = $pathExpression->expectedType; $expectedType = $pathExpression->expectedType;
@ -891,11 +831,11 @@ class Parser
public function JoinAssociationPathExpression() public function JoinAssociationPathExpression()
{ {
$token = $this->_lexer->lookahead; $token = $this->_lexer->lookahead;
$identVariable = $this->IdentificationVariable(); $identVariable = $this->IdentificationVariable();
$this->match(Lexer::T_DOT); $this->match(Lexer::T_DOT);
$this->match(Lexer::T_IDENTIFIER); $this->match(Lexer::T_IDENTIFIER);
//$this->match($this->_lexer->lookahead['type']);
$field = $this->_lexer->token['value']; $field = $this->_lexer->token['value'];
// Validate association field // Validate association field
@ -913,7 +853,7 @@ class Parser
* Parses an arbitrary path expression and defers semantical validation * Parses an arbitrary path expression and defers semantical validation
* based on expected types. * based on expected types.
* *
* PathExpression ::= IdentificationVariable {"." identifier}* "." identifier * PathExpression ::= IdentificationVariable "." identifier
* *
* @param integer $expectedTypes * @param integer $expectedTypes
* @return \Doctrine\ORM\Query\AST\PathExpression * @return \Doctrine\ORM\Query\AST\PathExpression
@ -922,17 +862,17 @@ class Parser
{ {
$token = $this->_lexer->lookahead; $token = $this->_lexer->lookahead;
$identVariable = $this->IdentificationVariable(); $identVariable = $this->IdentificationVariable();
$parts = array(); $field = null;
while ($this->_lexer->isNextToken(Lexer::T_DOT)) { if ($this->_lexer->isNextToken(Lexer::T_DOT)) {
$this->match(Lexer::T_DOT); $this->match(Lexer::T_DOT);
$this->match(Lexer::T_IDENTIFIER); $this->match(Lexer::T_IDENTIFIER);
$parts[] = $this->_lexer->token['value']; $field = $this->_lexer->token['value'];
} }
// Creating AST node // Creating AST node
$pathExpr = new AST\PathExpression($expectedTypes, $identVariable, $parts); $pathExpr = new AST\PathExpression($expectedTypes, $identVariable, $field);
// Defer PathExpression validation if requested to be defered // Defer PathExpression validation if requested to be defered
$this->_deferredPathExpressions[] = array( $this->_deferredPathExpressions[] = array(
@ -971,7 +911,7 @@ class Parser
} }
/** /**
* StateFieldPathExpression ::= SimpleStateFieldPathExpression | SimpleStateFieldAssociationPathExpression * StateFieldPathExpression ::= IdentificationVariable "." StateField
* *
* @return \Doctrine\ORM\Query\AST\PathExpression * @return \Doctrine\ORM\Query\AST\PathExpression
*/ */
@ -981,7 +921,7 @@ class Parser
} }
/** /**
* SingleValuedAssociationPathExpression ::= IdentificationVariable "." {SingleValuedAssociationField "."}* SingleValuedAssociationField * SingleValuedAssociationPathExpression ::= IdentificationVariable "." SingleValuedAssociationField
* *
* @return \Doctrine\ORM\Query\AST\PathExpression * @return \Doctrine\ORM\Query\AST\PathExpression
*/ */
@ -991,7 +931,7 @@ class Parser
} }
/** /**
* CollectionValuedPathExpression ::= IdentificationVariable "." {SingleValuedAssociationField "."}* CollectionValuedAssociationField * CollectionValuedPathExpression ::= IdentificationVariable "." CollectionValuedAssociationField
* *
* @return \Doctrine\ORM\Query\AST\PathExpression * @return \Doctrine\ORM\Query\AST\PathExpression
*/ */
@ -1000,26 +940,6 @@ class Parser
return $this->PathExpression(AST\PathExpression::TYPE_COLLECTION_VALUED_ASSOCIATION); return $this->PathExpression(AST\PathExpression::TYPE_COLLECTION_VALUED_ASSOCIATION);
} }
/**
* SimpleStateFieldPathExpression ::= IdentificationVariable "." StateField
*
* @return \Doctrine\ORM\Query\AST\PathExpression
*/
public function SimpleStateFieldPathExpression()
{
$pathExpression = $this->PathExpression(AST\PathExpression::TYPE_STATE_FIELD);
$parts = $pathExpression->parts;
if (count($parts) > 1) {
$this->semanticalError(
"Invalid SimpleStateFieldPathExpression. " .
"Expected state field, got association '{$parts[0]}'."
);
}
return $pathExpression;
}
/** /**
* SelectClause ::= "SELECT" ["DISTINCT"] SelectExpression {"," SelectExpression} * SelectClause ::= "SELECT" ["DISTINCT"] SelectExpression {"," SelectExpression}
* *
@ -1292,7 +1212,9 @@ class Parser
public function UpdateItem() public function UpdateItem()
{ {
$pathExpr = $this->PathExpression(AST\PathExpression::TYPE_STATE_FIELD | AST\PathExpression::TYPE_SINGLE_VALUED_ASSOCIATION); $pathExpr = $this->PathExpression(AST\PathExpression::TYPE_STATE_FIELD | AST\PathExpression::TYPE_SINGLE_VALUED_ASSOCIATION);
$this->match(Lexer::T_EQUALS); $this->match(Lexer::T_EQUALS);
$updateItem = new AST\UpdateItem($pathExpr, $this->NewValue()); $updateItem = new AST\UpdateItem($pathExpr, $this->NewValue());
return $updateItem; return $updateItem;
@ -1308,7 +1230,7 @@ class Parser
// We need to check if we are in a IdentificationVariable or SingleValuedPathExpression // We need to check if we are in a IdentificationVariable or SingleValuedPathExpression
$glimpse = $this->_lexer->glimpse(); $glimpse = $this->_lexer->glimpse();
if ($glimpse['value'] != '.') { if ($glimpse['type'] != Lexer::T_DOT) {
$token = $this->_lexer->lookahead; $token = $this->_lexer->lookahead;
$identVariable = $this->IdentificationVariable(); $identVariable = $this->IdentificationVariable();
@ -1333,7 +1255,7 @@ class Parser
// We need to check if we are in a ResultVariable or StateFieldPathExpression // We need to check if we are in a ResultVariable or StateFieldPathExpression
$glimpse = $this->_lexer->glimpse(); $glimpse = $this->_lexer->glimpse();
if ($glimpse['value'] != '.') { if ($glimpse['type'] != Lexer::T_DOT) {
$token = $this->_lexer->lookahead; $token = $this->_lexer->lookahead;
$expr = $this->ResultVariable(); $expr = $this->ResultVariable();
} else { } else {
@ -1409,9 +1331,11 @@ class Parser
*/ */
public function SubselectIdentificationVariableDeclaration() public function SubselectIdentificationVariableDeclaration()
{ {
$peek = $this->_lexer->glimpse(); $glimpse = $this->_lexer->glimpse();
if ($peek['value'] == '.') { /* NOT YET IMPLEMENTED!
if ($glimpse['type'] == Lexer::T_DOT) {
$subselectIdVarDecl = new AST\SubselectIdentificationVariableDeclaration(); $subselectIdVarDecl = new AST\SubselectIdentificationVariableDeclaration();
$subselectIdVarDecl->associationPathExpression = $this->AssociationPathExpression(); $subselectIdVarDecl->associationPathExpression = $this->AssociationPathExpression();
$this->match(Lexer::T_AS); $this->match(Lexer::T_AS);
@ -1419,6 +1343,7 @@ class Parser
return $subselectIdVarDecl; return $subselectIdVarDecl;
} }
*/
return $this->IdentificationVariableDeclaration(); return $this->IdentificationVariableDeclaration();
} }
@ -1486,11 +1411,13 @@ class Parser
$this->match(Lexer::T_OPEN_CURLY_BRACE); $this->match(Lexer::T_OPEN_CURLY_BRACE);
$this->match(Lexer::T_IDENTIFIER); $this->match(Lexer::T_IDENTIFIER);
$partialFieldSet[] = $this->_lexer->token['value']; $partialFieldSet[] = $this->_lexer->token['value'];
while ($this->_lexer->isNextToken(Lexer::T_COMMA)) { while ($this->_lexer->isNextToken(Lexer::T_COMMA)) {
$this->match(Lexer::T_COMMA); $this->match(Lexer::T_COMMA);
$this->match(Lexer::T_IDENTIFIER); $this->match(Lexer::T_IDENTIFIER);
$partialFieldSet[] = $this->_lexer->token['value']; $partialFieldSet[] = $this->_lexer->token['value'];
} }
$this->match(Lexer::T_CLOSE_CURLY_BRACE); $this->match(Lexer::T_CLOSE_CURLY_BRACE);
$partialObjectExpression = new AST\PartialObjectExpression($identificationVariable, $partialFieldSet); $partialObjectExpression = new AST\PartialObjectExpression($identificationVariable, $partialFieldSet);
@ -1577,7 +1504,7 @@ class Parser
} }
/** /**
* IndexBy ::= "INDEX" "BY" SimpleStateFieldPathExpression * IndexBy ::= "INDEX" "BY" StateFieldPathExpression
* *
* @return Doctrine\ORM\Query\AST\IndexBy * @return Doctrine\ORM\Query\AST\IndexBy
*/ */
@ -1585,13 +1512,12 @@ class Parser
{ {
$this->match(Lexer::T_INDEX); $this->match(Lexer::T_INDEX);
$this->match(Lexer::T_BY); $this->match(Lexer::T_BY);
$pathExp = $this->SimpleStateFieldPathExpression(); $pathExpr = $this->StateFieldPathExpression();
// Add the INDEX BY info to the query component // Add the INDEX BY info to the query component
$parts = $pathExp->parts; $this->_queryComponents[$pathExpr->identificationVariable]['map'] = $pathExpr->field;
$this->_queryComponents[$pathExp->identificationVariable]['map'] = $parts[0];
return new AST\IndexBy($pathExp); return new AST\IndexBy($pathExpr);
} }
/** /**
@ -1725,9 +1651,9 @@ class Parser
{ {
if ($this->_lexer->isNextToken(Lexer::T_IDENTIFIER)) { if ($this->_lexer->isNextToken(Lexer::T_IDENTIFIER)) {
// SingleValuedPathExpression | IdentificationVariable // SingleValuedPathExpression | IdentificationVariable
$peek = $this->_lexer->glimpse(); $glimpse = $this->_lexer->glimpse();
if ($peek['value'] == '.') { if ($glimpse['type'] == Lexer::T_DOT) {
return new AST\SimpleSelectExpression($this->StateFieldPathExpression()); return new AST\SimpleSelectExpression($this->StateFieldPathExpression());
} }
@ -2199,7 +2125,7 @@ class Parser
return $this->SingleValuedPathExpression(); return $this->SingleValuedPathExpression();
} }
return $this->SimpleStateFieldPathExpression(); return $this->StateFieldPathExpression();
case Lexer::T_INPUT_PARAMETER: case Lexer::T_INPUT_PARAMETER:
return $this->InputParameter(); return $this->InputParameter();

View File

@ -438,7 +438,7 @@ class SqlWalker implements TreeWalker
* @param string $identificationVariable * @param string $identificationVariable
* @return string The SQL. * @return string The SQL.
*/ */
public function walkIdentificationVariable($identificationVariable, $fieldName = null) public function walkIdentificationVariable($identificationVariable, $fieldName)
{ {
$class = $this->_queryComponents[$identificationVariable]['metadata']; $class = $this->_queryComponents[$identificationVariable]['metadata'];
@ -464,9 +464,8 @@ class SqlWalker implements TreeWalker
switch ($pathExpr->type) { switch ($pathExpr->type) {
case AST\PathExpression::TYPE_STATE_FIELD: case AST\PathExpression::TYPE_STATE_FIELD:
$parts = $pathExpr->parts; $fieldName = $pathExpr->field;
$fieldName = array_pop($parts); $dqlAlias = $pathExpr->identificationVariable;
$dqlAlias = $pathExpr->identificationVariable . ( ! empty($parts) ? '.' . implode('.', $parts) : '');
$class = $this->_queryComponents[$dqlAlias]['metadata']; $class = $this->_queryComponents[$dqlAlias]['metadata'];
if ($this->_useSqlTableAliases) { if ($this->_useSqlTableAliases) {
@ -479,8 +478,7 @@ class SqlWalker implements TreeWalker
case AST\PathExpression::TYPE_SINGLE_VALUED_ASSOCIATION: case AST\PathExpression::TYPE_SINGLE_VALUED_ASSOCIATION:
// 1- the owning side: // 1- the owning side:
// Just use the foreign key, i.e. u.group_id // Just use the foreign key, i.e. u.group_id
$parts = $pathExpr->parts; $fieldName = $pathExpr->field;
$fieldName = array_pop($parts);
$dqlAlias = $pathExpr->identificationVariable; $dqlAlias = $pathExpr->identificationVariable;
$class = $this->_queryComponents[$dqlAlias]['metadata']; $class = $this->_queryComponents[$dqlAlias]['metadata'];
@ -630,7 +628,7 @@ class SqlWalker implements TreeWalker
if ($identificationVariableDecl->indexBy) { if ($identificationVariableDecl->indexBy) {
$this->_rsm->addIndexBy( $this->_rsm->addIndexBy(
$identificationVariableDecl->indexBy->simpleStateFieldPathExpression->identificationVariable, $identificationVariableDecl->indexBy->simpleStateFieldPathExpression->identificationVariable,
$identificationVariableDecl->indexBy->simpleStateFieldPathExpression->parts[0] $identificationVariableDecl->indexBy->simpleStateFieldPathExpression->field
); );
} }
@ -840,9 +838,8 @@ class SqlWalker implements TreeWalker
if ($expr instanceof AST\PathExpression) { if ($expr instanceof AST\PathExpression) {
if ($expr->type == AST\PathExpression::TYPE_STATE_FIELD) { if ($expr->type == AST\PathExpression::TYPE_STATE_FIELD) {
$parts = $expr->parts; $fieldName = $expr->field;
$fieldName = array_pop($parts); $dqlAlias = $expr->identificationVariable;
$dqlAlias = $expr->identificationVariable . (( ! empty($parts)) ? '.' . implode('.', $parts) : '');
$qComp = $this->_queryComponents[$dqlAlias]; $qComp = $this->_queryComponents[$dqlAlias];
$class = $qComp['metadata']; $class = $qComp['metadata'];
@ -1345,9 +1342,8 @@ class SqlWalker implements TreeWalker
$entityExpr = $collMemberExpr->entityExpression; $entityExpr = $collMemberExpr->entityExpression;
$collPathExpr = $collMemberExpr->collectionValuedPathExpression; $collPathExpr = $collMemberExpr->collectionValuedPathExpression;
$parts = $collPathExpr->parts; $fieldName = $collPathExpr->field;
$fieldName = array_pop($parts); $dqlAlias = $collPathExpr->identificationVariable;
$dqlAlias = $collPathExpr->identificationVariable . (( ! empty($parts)) ? '.' . implode('.', $parts) : '');
$class = $this->_queryComponents[$dqlAlias]['metadata']; $class = $this->_queryComponents[$dqlAlias]['metadata'];

View File

@ -92,7 +92,7 @@ class AdvancedDqlQueryTest extends \Doctrine\Tests\OrmFunctionalTestCase
public function testSelectSubselect() public function testSelectSubselect()
{ {
$dql = 'SELECT p, (SELECT c.brand FROM Doctrine\Tests\Models\Company\CompanyCar c WHERE p.car.id = c.id) brandName '. $dql = 'SELECT p, (SELECT c.brand FROM Doctrine\Tests\Models\Company\CompanyCar c WHERE p.car = c) brandName '.
'FROM Doctrine\Tests\Models\Company\CompanyManager p'; 'FROM Doctrine\Tests\Models\Company\CompanyManager p';
$result = $this->_em->createQuery($dql)->getArrayResult(); $result = $this->_em->createQuery($dql)->getArrayResult();

View File

@ -47,14 +47,23 @@ class CustomTreeWalkersTest extends \Doctrine\Tests\OrmFunctionalTestCase
$query->setHint(Query::HINT_CUSTOM_TREE_WALKERS, array('Doctrine\Tests\ORM\Functional\CustomTreeWalker')) $query->setHint(Query::HINT_CUSTOM_TREE_WALKERS, array('Doctrine\Tests\ORM\Functional\CustomTreeWalker'))
->useQueryCache(false); ->useQueryCache(false);
parent::assertEquals($sqlToBeConfirmed, $query->getSql()); $this->assertEquals($sqlToBeConfirmed, $query->getSql());
$query->free(); $query->free();
} catch (\Exception $e) { } catch (\Exception $e) {
$this->fail($e->getMessage()); $this->fail($e->getMessage() . ' at "' . $e->getFile() . '" on line ' . $e->getLine());
} }
} }
public function testSupportsQueriesWithoutWhere() public function testSupportsQueriesWithoutWhere()
{
$this->assertSqlGeneration(
'select u from Doctrine\Tests\Models\CMS\CmsUser u',
"SELECT c0_.id AS id0, c0_.status AS status1, c0_.username AS username2, c0_.name AS name3 FROM cms_users c0_ WHERE c0_.id = 1"
);
}
public function testSupportsQueriesWithMultipleConditionalExpressions()
{ {
$this->assertSqlGeneration( $this->assertSqlGeneration(
'select u from Doctrine\Tests\Models\CMS\CmsUser u where u.name = :name or u.name = :otherName', 'select u from Doctrine\Tests\Models\CMS\CmsUser u where u.name = :name or u.name = :otherName',
@ -62,21 +71,13 @@ class CustomTreeWalkersTest extends \Doctrine\Tests\OrmFunctionalTestCase
); );
} }
public function testSupportsQueriesWithSimpleConditionalExpressions() public function testSupportsQueriesWithSimpleConditionalExpression()
{ {
$this->assertSqlGeneration( $this->assertSqlGeneration(
'select u from Doctrine\Tests\Models\CMS\CmsUser u where u.name = :name', 'select u from Doctrine\Tests\Models\CMS\CmsUser u where u.name = :name',
"SELECT c0_.id AS id0, c0_.status AS status1, c0_.username AS username2, c0_.name AS name3 FROM cms_users c0_ WHERE c0_.name = ? AND c0_.id = 1" "SELECT c0_.id AS id0, c0_.status AS status1, c0_.username AS username2, c0_.name AS name3 FROM cms_users c0_ WHERE c0_.name = ? AND c0_.id = 1"
); );
} }
public function testSupportsQueriesWithMultipleConditionalExpressions()
{
$this->assertSqlGeneration(
'select u from Doctrine\Tests\Models\CMS\CmsUser u',
"SELECT c0_.id AS id0, c0_.status AS status1, c0_.username AS username2, c0_.name AS name3 FROM cms_users c0_ WHERE c0_.id = 1"
);
}
} }
class CustomTreeWalker extends Query\TreeWalkerAdapter class CustomTreeWalker extends Query\TreeWalkerAdapter
@ -97,7 +98,7 @@ class CustomTreeWalker extends Query\TreeWalkerAdapter
// Create our conditions for all involved classes // Create our conditions for all involved classes
$factors = array(); $factors = array();
foreach ($dqlAliases as $alias) { foreach ($dqlAliases as $alias) {
$pathExpr = new Query\AST\PathExpression(Query\AST\PathExpression::TYPE_STATE_FIELD, $alias, array('id')); $pathExpr = new Query\AST\PathExpression(Query\AST\PathExpression::TYPE_STATE_FIELD, $alias, 'id');
$pathExpr->type = Query\AST\PathExpression::TYPE_STATE_FIELD; $pathExpr->type = Query\AST\PathExpression::TYPE_STATE_FIELD;
$comparisonExpr = new Query\AST\ComparisonExpression($pathExpr, '=', 1); $comparisonExpr = new Query\AST\ComparisonExpression($pathExpr, '=', 1);

View File

@ -17,7 +17,7 @@ class DDC493Test extends \Doctrine\Tests\OrmFunctionalTestCase
public function testIssue() public function testIssue()
{ {
$q = $this->_em->createQuery("select u, u.contact.data from ".__NAMESPACE__."\\DDC493Distributor u"); $q = $this->_em->createQuery("select u, c.data from ".__NAMESPACE__."\\DDC493Distributor u JOIN u.contact c");
$this->assertEquals('SELECT d0_.id AS id0, d1_.data AS data1, d0_.discr AS discr2, d0_.contact AS contact3 FROM DDC493Distributor d2_ INNER JOIN DDC493Customer d0_ ON d2_.id = d0_.id INNER JOIN DDC493Contact d1_ ON d0_.contact = d1_.id', $q->getSQL()); $this->assertEquals('SELECT d0_.id AS id0, d1_.data AS data1, d0_.discr AS discr2, d0_.contact AS contact3 FROM DDC493Distributor d2_ INNER JOIN DDC493Customer d0_ ON d2_.id = d0_.id INNER JOIN DDC493Contact d1_ ON d0_.contact = d1_.id', $q->getSQL());
} }
} }

View File

@ -89,11 +89,6 @@ class LanguageRecognitionTest extends \Doctrine\Tests\OrmTestCase
$this->assertValidDql('SELECT u, p FROM Doctrine\Tests\Models\CMS\CmsUser u JOIN u.phonenumbers p'); $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() public function testSelectDistinctIsSupported()
{ {
$this->assertValidDql('SELECT DISTINCT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u'); $this->assertValidDql('SELECT DISTINCT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u');
@ -294,13 +289,13 @@ class LanguageRecognitionTest extends \Doctrine\Tests\OrmTestCase
{ {
// This should be allowed because avatar is a single-value association. // This should be allowed because avatar is a single-value association.
// SQL: SELECT ... FROM forum_user fu INNER JOIN forum_avatar fa ON fu.avatar_id = fa.id WHERE fa.id = ? // SQL: SELECT ... FROM forum_user fu INNER JOIN forum_avatar fa ON fu.avatar_id = fa.id WHERE fa.id = ?
$this->assertValidDql("SELECT u FROM Doctrine\Tests\Models\Forum\ForumUser u WHERE u.avatar.id = ?1"); $this->assertValidDql("SELECT u FROM Doctrine\Tests\Models\Forum\ForumUser u JOIN u.avatar a WHERE a.id = ?1");
} }
public function testImplicitJoinInWhereOnCollectionValuedPathExpression() public function testImplicitJoinInWhereOnCollectionValuedPathExpression()
{ {
// This should be forbidden, because articles is a collection // This should be forbidden, because articles is a collection
$this->assertInvalidDql("SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.articles.title = ?"); $this->assertInvalidDql("SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u JOIN u.articles a WHERE a.title = ?");
} }
public function testInvalidSyntaxIsRejected() public function testInvalidSyntaxIsRejected()

View File

@ -51,7 +51,7 @@ class SelectSqlGenerationTest extends \Doctrine\Tests\OrmTestCase
public function testSupportsSelectForOneNestedField() public function testSupportsSelectForOneNestedField()
{ {
$this->assertSqlGeneration( $this->assertSqlGeneration(
'SELECT a.user.id FROM Doctrine\Tests\Models\CMS\CmsArticle a', 'SELECT u.id FROM Doctrine\Tests\Models\CMS\CmsArticle a JOIN a.user u',
'SELECT c0_.id AS id0 FROM cms_articles c1_ INNER JOIN cms_users c0_ ON c1_.user_id = c0_.id' 'SELECT c0_.id AS id0 FROM cms_articles c1_ INNER JOIN cms_users c0_ ON c1_.user_id = c0_.id'
); );
} }
@ -59,7 +59,7 @@ class SelectSqlGenerationTest extends \Doctrine\Tests\OrmTestCase
public function testSupportsSelectForAllNestedField() public function testSupportsSelectForAllNestedField()
{ {
$this->assertSqlGeneration( $this->assertSqlGeneration(
'SELECT a FROM Doctrine\Tests\Models\CMS\CmsArticle a ORDER BY a.user.name ASC', 'SELECT a FROM Doctrine\Tests\Models\CMS\CmsArticle a JOIN a.user u ORDER BY u.name ASC',
'SELECT c0_.id AS id0, c0_.topic AS topic1, c0_.text AS text2, c0_.version AS version3 FROM cms_articles c0_ INNER JOIN cms_users c1_ ON c0_.user_id = c1_.id ORDER BY c1_.name ASC' 'SELECT c0_.id AS id0, c0_.topic AS topic1, c0_.text AS text2, c0_.version AS version3 FROM cms_articles c0_ INNER JOIN cms_users c1_ ON c0_.user_id = c1_.id ORDER BY c1_.name ASC'
); );
} }