1
0
mirror of synced 2025-02-06 23:39:25 +03:00

[2.0] Finish implementation of nesting level checkings.

This commit is contained in:
guilhermeblanco 2009-08-05 03:56:21 +00:00
parent cd50fc38ad
commit 995eaf3dcd

View File

@ -453,8 +453,8 @@ class Parser
{ {
$exprStack = array_pop($this->_deferredPathExpressionStacks); $exprStack = array_pop($this->_deferredPathExpressionStacks);
foreach ($exprStack as $pathExpression) { foreach ($exprStack as $item) {
$this->_validatePathExpression($pathExpression); $this->_validatePathExpression($item['pathExpression'], $item['nestingLevel']);
} }
} }
@ -468,13 +468,14 @@ class Parser
* CollectionValuedPathExpression ::= IdentificationVariable "." {SingleValuedAssociationField "."}* CollectionValuedAssociationField * CollectionValuedPathExpression ::= IdentificationVariable "." {SingleValuedAssociationField "."}* CollectionValuedAssociationField
* *
* @param PathExpression $pathExpression * @param PathExpression $pathExpression
* @param integer $nestingLevel
* @return integer * @return integer
*/ */
private function _validatePathExpression(AST\PathExpression $pathExpression) private function _validatePathExpression(AST\PathExpression $pathExpression, $nestingLevel)
{ {
$identificationVariable = $pathExpression->getIdentificationVariable(); $identificationVariable = $pathExpression->getIdentificationVariable();
$this->_validateIdentificationVariable($identificationVariable); $this->_validateIdentificationVariable($identificationVariable, $nestingLevel);
$class = $this->_queryComponents[$identificationVariable]['metadata']; $class = $this->_queryComponents[$identificationVariable]['metadata'];
$stateField = $collectionField = null; $stateField = $collectionField = null;
@ -559,19 +560,26 @@ class Parser
* Validates that the given <tt>IdentificationVariable</tt> is a semantically correct. * Validates that the given <tt>IdentificationVariable</tt> is a semantically correct.
* It must exist in query components list. * It must exist in query components list.
* *
* @param string $identificationVariable * @param string $idVariable
* @param integer $nestingLevel
* @return array Query Component * @return array Query Component
*/ */
private function _validateIdentificationVariable($identificationVariable) private function _validateIdentificationVariable($idVariable, $nestingLevel)
{ {
if ( ! isset($this->_queryComponents[$identificationVariable])) { if ( ! isset($this->_queryComponents[$idVariable])) {
$this->semanticalError( $this->semanticalError(
'Invalid IdentificationVariable. Could not find \'' . "Could not find '$idVariable' in query components"
$identificationVariable . '\' in query components.'
); );
} }
return $this->_queryComponents[$identificationVariable]; // Validate if identification variable nesting level is lower or equal than the current one
if ($this->_queryComponents[$idVariable]['nestingLevel'] > $nestingLevel) {
$this->semanticalError(
"Query component '$idVariable' is not in the same nesting level of its declaration"
);
}
return $this->_queryComponents[$idVariable];
} }
@ -730,7 +738,7 @@ class Parser
$field = $this->_lexer->token['value']; $field = $this->_lexer->token['value'];
// Validating IdentificationVariable (it was already defined previously) // Validating IdentificationVariable (it was already defined previously)
$this->_validateIdentificationVariable($identificationVariable); $this->_validateIdentificationVariable($identificationVariable, $this->_nestingLevel);
// Validating association field (*-to-one or *-to-many) // Validating association field (*-to-one or *-to-many)
$class = $this->_queryComponents[$identificationVariable]['metadata']; $class = $this->_queryComponents[$identificationVariable]['metadata'];
@ -769,14 +777,17 @@ class Parser
// Defer PathExpression validation if requested to be defered // Defer PathExpression validation if requested to be defered
if ( ! empty($this->_deferredPathExpressionStacks)) { if ( ! empty($this->_deferredPathExpressionStacks)) {
$exprStack = array_pop($this->_deferredPathExpressionStacks); $exprStack = array_pop($this->_deferredPathExpressionStacks);
$exprStack[] = $pathExpr; $exprStack[] = array(
'pathExpression' => $pathExpr,
'nestingLevel' => $this->_nestingLevel,
);
array_push($this->_deferredPathExpressionStacks, $exprStack); array_push($this->_deferredPathExpressionStacks, $exprStack);
return $pathExpr; return $pathExpr;
} }
// Apply PathExpression validation normally (not in defer mode) // Apply PathExpression validation normally (not in defer mode)
$this->_validatePathExpression($pathExpr); $this->_validatePathExpression($pathExpr, $this->_nestingLevel);
return $pathExpr; return $pathExpr;
} }
@ -941,10 +952,11 @@ class Parser
// Building queryComponent // Building queryComponent
$queryComponent = array( $queryComponent = array(
'metadata' => $classMetadata, 'metadata' => $classMetadata,
'parent' => null, 'parent' => null,
'relation' => null, 'relation' => null,
'map' => null 'map' => null,
'nestingLevel' => $this->_nestingLevel,
); );
$this->_queryComponents[$aliasIdentificationVariable] = $queryComponent; $this->_queryComponents[$aliasIdentificationVariable] = $queryComponent;
@ -981,10 +993,11 @@ class Parser
$classMetadata = $this->_em->getClassMetadata($deleteClause->getAbstractSchemaName()); $classMetadata = $this->_em->getClassMetadata($deleteClause->getAbstractSchemaName());
$queryComponent = array( $queryComponent = array(
'metadata' => $classMetadata, 'metadata' => $classMetadata,
'parent' => null, 'parent' => null,
'relation' => null, 'relation' => null,
'map' => null 'map' => null,
'nestingLevel' => $this->_nestingLevel,
); );
$this->_queryComponents[$deleteClause->getAliasIdentificationVariable()] = $queryComponent; $this->_queryComponents[$deleteClause->getAliasIdentificationVariable()] = $queryComponent;
@ -1175,7 +1188,7 @@ class Parser
$identificationVariable = $this->IdentificationVariable(); $identificationVariable = $this->IdentificationVariable();
// Validate if IdentificationVariable is defined // Validate if IdentificationVariable is defined
$this->_validateIdentificationVariable($identificationVariable); $this->_validateIdentificationVariable($identificationVariable, $this->_nestingLevel);
return $identificationVariable; return $identificationVariable;
} }
@ -1200,12 +1213,13 @@ class Parser
$expr = $this->ResultVariable(); $expr = $this->ResultVariable();
// Check if ResultVariable is defined in query components // Check if ResultVariable is defined in query components
$queryComponent = $this->_validateIdentificationVariable($expr); $queryComponent = $this->_validateIdentificationVariable($expr, $this->_nestingLevel);
// Outer defininition used in inner subselect is not enough.
// ResultVariable exists in queryComponents, check nesting level // ResultVariable exists in queryComponents, check nesting level
if ($queryComponent['nestingLevel'] != $this->_nestingLevel) { if ($queryComponent['nestingLevel'] != $this->_nestingLevel) {
$this->semanticalError( $this->semanticalError(
"ResultVariable '$expr' is not in the same nesting level of its declaration" "Query component '$expr' is not in the same nesting level of its declaration"
); );
} }
} else { } else {
@ -1333,10 +1347,11 @@ class Parser
// Building queryComponent // Building queryComponent
$queryComponent = array( $queryComponent = array(
'metadata' => $classMetadata, 'metadata' => $classMetadata,
'parent' => null, 'parent' => null,
'relation' => null, 'relation' => null,
'map' => null 'map' => null,
'nestingLevel' => $this->_nestingLevel,
); );
$this->_queryComponents[$aliasIdentificationVariable] = $queryComponent; $this->_queryComponents[$aliasIdentificationVariable] = $queryComponent;
@ -1393,10 +1408,11 @@ class Parser
// Building queryComponent // Building queryComponent
$joinQueryComponent = array( $joinQueryComponent = array(
'metadata' => $this->_em->getClassMetadata($targetClassName), 'metadata' => $this->_em->getClassMetadata($targetClassName),
'parent' => $joinPathExpression->getIdentificationVariable(), 'parent' => $joinPathExpression->getIdentificationVariable(),
'relation' => $parentClass->getAssociationMapping($assocField), 'relation' => $parentClass->getAssociationMapping($assocField),
'map' => null, 'map' => null,
'nestingLevel' => $this->_nestingLevel,
); );
$this->_queryComponents[$aliasIdentificationVariable] = $joinQueryComponent; $this->_queryComponents[$aliasIdentificationVariable] = $joinQueryComponent;
@ -1638,8 +1654,6 @@ class Parser
* ComparisonExpression | BetweenExpression | LikeExpression | * ComparisonExpression | BetweenExpression | LikeExpression |
* InExpression | NullComparisonExpression | ExistsExpression | * InExpression | NullComparisonExpression | ExistsExpression |
* EmptyCollectionComparisonExpression | CollectionMemberExpression * EmptyCollectionComparisonExpression | CollectionMemberExpression
*
* @todo Post 2.0 release. Missing EmptyCollectionComparisonExpression implementation
*/ */
public function SimpleConditionalExpression() public function SimpleConditionalExpression()
{ {