From 8452108e215ff8f5d66b82d3eeaa00c9bb03385f Mon Sep 17 00:00:00 2001 From: guilhermeblanco Date: Thu, 13 Aug 2009 02:17:27 +0000 Subject: [PATCH] [2.0] Some code reordering, changes. Removed classMetadata from RangeVariableDeclaration, since it is against AST concept. --- .../Query/AST/RangeVariableDeclaration.php | 6 +- .../Query/Exec/MultiTableDeleteExecutor.php | 2 +- .../Query/Exec/MultiTableUpdateExecutor.php | 2 +- lib/Doctrine/ORM/Query/Parser.php | 10 +- lib/Doctrine/ORM/Query/SqlWalker.php | 222 +++++++++--------- 5 files changed, 121 insertions(+), 121 deletions(-) diff --git a/lib/Doctrine/ORM/Query/AST/RangeVariableDeclaration.php b/lib/Doctrine/ORM/Query/AST/RangeVariableDeclaration.php index 60ccf5532..7a01bdcbe 100644 --- a/lib/Doctrine/ORM/Query/AST/RangeVariableDeclaration.php +++ b/lib/Doctrine/ORM/Query/AST/RangeVariableDeclaration.php @@ -34,14 +34,12 @@ namespace Doctrine\ORM\Query\AST; */ class RangeVariableDeclaration extends Node { - public $classMetadata; public $abstractSchemaName; public $aliasIdentificationVariable; - public function __construct($classMetadata, $aliasIdentificationVar) + public function __construct($abstractSchemaName, $aliasIdentificationVar) { - $this->classMetadata = $classMetadata; - $this->abstractSchemaName = $classMetadata->name; + $this->abstractSchemaName = $abstractSchemaName; $this->aliasIdentificationVariable = $aliasIdentificationVar; } diff --git a/lib/Doctrine/ORM/Query/Exec/MultiTableDeleteExecutor.php b/lib/Doctrine/ORM/Query/Exec/MultiTableDeleteExecutor.php index 3b75c5218..e8627135c 100644 --- a/lib/Doctrine/ORM/Query/Exec/MultiTableDeleteExecutor.php +++ b/lib/Doctrine/ORM/Query/Exec/MultiTableDeleteExecutor.php @@ -67,7 +67,7 @@ class MultiTableDeleteExecutor extends AbstractSqlExecutor $this->_insertSql = 'INSERT INTO ' . $tempTable . ' (' . $idColumnList . ')' . ' SELECT t0.' . implode(', t0.', $idColumnNames); $sqlWalker->setSqlTableAlias($primaryClass->primaryTable['name'] . $primaryDqlAlias, 't0'); - $rangeDecl = new AST\RangeVariableDeclaration($primaryClass, $primaryDqlAlias); + $rangeDecl = new AST\RangeVariableDeclaration($primaryClass->name, $primaryDqlAlias); $fromClause = new AST\FromClause(array(new AST\IdentificationVariableDeclaration($rangeDecl, null, array()))); $this->_insertSql .= $sqlWalker->walkFromClause($fromClause); diff --git a/lib/Doctrine/ORM/Query/Exec/MultiTableUpdateExecutor.php b/lib/Doctrine/ORM/Query/Exec/MultiTableUpdateExecutor.php index 6b4fcb350..0167175b0 100644 --- a/lib/Doctrine/ORM/Query/Exec/MultiTableUpdateExecutor.php +++ b/lib/Doctrine/ORM/Query/Exec/MultiTableUpdateExecutor.php @@ -70,7 +70,7 @@ class MultiTableUpdateExecutor extends AbstractSqlExecutor $this->_insertSql = 'INSERT INTO ' . $tempTable . ' (' . $idColumnList . ')' . ' SELECT t0.' . implode(', t0.', $idColumnNames); $sqlWalker->setSqlTableAlias($primaryClass->primaryTable['name'] . $updateClause->aliasIdentificationVariable, 't0'); - $rangeDecl = new AST\RangeVariableDeclaration($primaryClass, $updateClause->aliasIdentificationVariable); + $rangeDecl = new AST\RangeVariableDeclaration($primaryClass->name, $updateClause->aliasIdentificationVariable); $fromClause = new AST\FromClause(array(new AST\IdentificationVariableDeclaration($rangeDecl, null, array()))); $this->_insertSql .= $sqlWalker->walkFromClause($fromClause); diff --git a/lib/Doctrine/ORM/Query/Parser.php b/lib/Doctrine/ORM/Query/Parser.php index ff6234412..d22b85a93 100644 --- a/lib/Doctrine/ORM/Query/Parser.php +++ b/lib/Doctrine/ORM/Query/Parser.php @@ -601,11 +601,7 @@ class Parser $token = ($token) ?: $this->_lexer->lookahead; if ( ! isset($this->_queryComponents[$identVariable])) { - echo '[Query Components: ' . var_export($this->_queryComponents, true) . ']'; - - $this->semanticalError( - "'$idVariable' is not defined", $token - ); + $this->semanticalError("'$idVariable' is not defined", $token); } // Validate if identification variable nesting level is lower or equal than the current one @@ -1402,9 +1398,7 @@ class Parser ); $this->_queryComponents[$aliasIdentificationVariable] = $queryComponent; - return new AST\RangeVariableDeclaration( - $classMetadata, $aliasIdentificationVariable - ); + return new AST\RangeVariableDeclaration($abstractSchemaName, $aliasIdentificationVariable); } /** diff --git a/lib/Doctrine/ORM/Query/SqlWalker.php b/lib/Doctrine/ORM/Query/SqlWalker.php index e432eeae3..f52cacbfb 100644 --- a/lib/Doctrine/ORM/Query/SqlWalker.php +++ b/lib/Doctrine/ORM/Query/SqlWalker.php @@ -171,9 +171,9 @@ class SqlWalker implements TreeWalker } else { return new Exec\SingleTableDeleteUpdateExecutor($AST, $this); } - } else { - return new Exec\SingleSelectExecutor($AST, $this); } + + return new Exec\SingleSelectExecutor($AST, $this); } /** @@ -203,6 +203,8 @@ class SqlWalker implements TreeWalker public function setSqlTableAlias($tableName, $alias) { $this->_dqlToSqlAliasMap[$tableName] = $alias; + + return $alias; } /** @@ -240,6 +242,7 @@ class SqlWalker implements TreeWalker foreach ($class->identifier as $idField) { if ($first) $first = false; else $sql .= ' AND '; + $columnName = $class->getQuotedColumnName($idField, $this->_platform); $sql .= $baseTableAlias . '.' . $columnName . ' = ' @@ -251,11 +254,13 @@ class SqlWalker implements TreeWalker foreach ($class->subClasses as $subClassName) { $subClass = $this->_em->getClassMetadata($subClassName); $tableAlias = $this->getSqlTableAlias($subClass->primaryTable['name'], $dqlAlias); - $sql .= ' LEFT JOIN ' . $subClass->primaryTable['name'] . ' ' . $tableAlias . ' ON '; + $sql .= ' LEFT JOIN ' . $subClass->getQuotedTableName($this->_platform) + . ' ' . $tableAlias . ' ON '; $first = true; foreach ($class->identifier as $idField) { if ($first) $first = false; else $sql .= ' AND '; + $columnName = $class->getQuotedColumnName($idField, $this->_platform); $sql .= $baseTableAlias . '.' . $columnName . ' = ' @@ -266,7 +271,38 @@ class SqlWalker implements TreeWalker return $sql; } + /** + * Generates a discriminator column SQL condition for the class with the given DQL alias. + * + * @param string $dqlAlias + * @return string + */ + private function _generateDiscriminatorColumnConditionSql($dqlAlias) + { + $sql = ''; + + if ($dqlAlias) { + $class = $this->_queryComponents[$dqlAlias]['metadata']; + + if ($class->isInheritanceTypeSingleTable()) { + $conn = $this->_em->getConnection(); + $values = array($conn->quote($class->discriminatorValue)); + + foreach ($class->subClasses as $subclassName) { + $values[] = $conn->quote($this->_em->getClassMetadata($subclassName)->discriminatorValue); + } + + $sql .= (($this->_useSqlTableAliases) + ? $this->getSqlTableAlias($class->primaryTable['name'], $dqlAlias) . '.' : '' + ) . $class->getQuotedDiscriminatorColumnName($this->_platform) + . ' IN (' . implode(', ', $values) . ')'; + } + } + + return $sql; + } + /** * Walks down a SelectStatement AST node, thereby generating the appropriate SQL. * @@ -277,9 +313,9 @@ class SqlWalker implements TreeWalker $sql = $this->walkSelectClause($AST->selectClause); $sql .= $this->walkFromClause($AST->fromClause); - if ($whereClause = $AST->whereClause) { + if (($whereClause = $AST->whereClause) !== null) { $sql .= $this->walkWhereClause($whereClause); - } else if ($discSql = $this->_generateDiscriminatorColumnConditionSql($this->_currentRootAlias)) { + } else if (($discSql = $this->_generateDiscriminatorColumnConditionSql($this->_currentRootAlias)) !== '') { $sql .= ' WHERE ' . $discSql; } @@ -306,9 +342,9 @@ class SqlWalker implements TreeWalker $this->_useSqlTableAliases = false; $sql = $this->walkUpdateClause($AST->updateClause); - if ($whereClause = $AST->whereClause) { + if (($whereClause = $AST->whereClause) !== null) { $sql .= $this->walkWhereClause($whereClause); - } else if ($discSql = $this->_generateDiscriminatorColumnConditionSql($this->_currentRootAlias)) { + } else if (($discSql = $this->_generateDiscriminatorColumnConditionSql($this->_currentRootAlias)) !== '') { $sql .= ' WHERE ' . $discSql; } @@ -326,9 +362,9 @@ class SqlWalker implements TreeWalker $this->_useSqlTableAliases = false; $sql = $this->walkDeleteClause($AST->deleteClause); - if ($whereClause = $AST->whereClause) { + if (($whereClause = $AST->whereClause) !== null) { $sql .= $this->walkWhereClause($whereClause); - } else if ($discSql = $this->_generateDiscriminatorColumnConditionSql($this->_currentRootAlias)) { + } else if (($discSql = $this->_generateDiscriminatorColumnConditionSql($this->_currentRootAlias)) !== '') { $sql .= ' WHERE ' . $discSql; } @@ -339,22 +375,71 @@ class SqlWalker implements TreeWalker /** * Walks down an IdentificationVariable (no AST node associated), thereby generating the SQL. * - * @param string + * @param string $identificationVariable * @return string The SQL. */ - public function walkIdentificationVariable($identVariable) + public function walkIdentificationVariable($identificationVariable, $fieldName = null) { - $qComp = $this->_queryComponents[$identVariable]; - $class = $qComp['metadata']; - - if ( ! isset($this->_selectedClasses[$identVariable])) { - $this->_selectedClasses[$identVariable] = $class; + $class = $this->_queryComponents[$identificationVariable]['metadata']; + + if ( + $fieldName !== null && $class->isInheritanceTypeJoined() && + isset($class->fieldMappings[$fieldName]['inherited']) + ) { + $class = $this->_em->getClassMetadata($class->fieldMappings[$fieldName]['inherited']); } - - return $this->_dqlToSqlAliasMap[$class->getTableName()]; + + return $this->getSqlTableAlias($class->primaryTable['name'], $identificationVariable); } + /** + * Walks down a PathExpression AST node, thereby generating the appropriate SQL. + * + * @param mixed + * @return string The SQL. + */ + public function walkPathExpression($pathExpr) + { + $sql = ''; + $pathExprType = $pathExpr->type; + + switch ($pathExpr->type) { + case AST\PathExpression::TYPE_STATE_FIELD: + $parts = $pathExpr->parts; + $numParts = count($parts); + $dqlAlias = $pathExpr->identificationVariable; + $fieldName = $parts[$numParts - 1]; + $qComp = $this->_queryComponents[$dqlAlias]; + $class = $qComp['metadata']; + + if ($this->_useSqlTableAliases) { + $sql .= $this->walkIdentificationVariable($dqlAlias, $fieldName) . '.'; + } + + if (isset($class->associationMappings[$fieldName])) { + //FIXME: Inverse side support + //FIXME: Throw exception on composite key + $assoc = $class->associationMappings[$fieldName]; + $sql .= $assoc->getQuotedJoinColumnName($assoc->joinColumns[0]['name'], $this->_platform); + } else { + $sql .= $class->getQuotedColumnName($fieldName, $this->_platform); + } + break; + + case AST\PathExpression::TYPE_COLLECTION_VALUED_ASSOCIATION: + throw DoctrineException::updateMe("Not yet implemented."); + + default: + throw DoctrineException::updateMe( + "Encountered invalid PathExpression during SQL construction." + ); + } + + return $sql; + } + + /** * Walks down a SelectClause AST node, thereby generating the appropriate SQL. * @@ -408,9 +493,11 @@ class SqlWalker implements TreeWalker } else { $sqlTableAlias = $this->getSqlTableAlias($class->primaryTable['name'], $dqlAlias); } + foreach ($assoc->targetToSourceKeyColumns as $srcColumn) { $columnAlias = $this->getSqlColumnAlias($srcColumn); - $sql .= ', ' . $sqlTableAlias . '.' . $assoc->getQuotedJoinColumnName($srcColumn, $this->_platform) . ' AS ' . $columnAlias; + $sql .= ", $sqlTableAlias." . $assoc->getQuotedJoinColumnName($srcColumn, $this->_platform) + . ' AS ' . $columnAlias; $this->_rsm->addMetaResult($dqlAlias, $columnAlias, $srcColumn); } } @@ -420,6 +507,7 @@ class SqlWalker implements TreeWalker // Add foreign key columns to SQL, if necessary if ($addMetaColumns) { $sqlTableAlias = $this->getSqlTableAlias($class->primaryTable['name'], $dqlAlias); + foreach ($class->associationMappings as $assoc) { if ($assoc->isOwningSide && $assoc->isOneToOne()) { foreach ($assoc->targetToSourceKeyColumns as $srcColumn) { @@ -450,10 +538,10 @@ class SqlWalker implements TreeWalker $dqlAlias = $rangeDecl->aliasIdentificationVariable; $this->_currentRootAlias = $dqlAlias; - $class = $rangeDecl->classMetadata; - + + $class = $this->_em->getClassMetadata($rangeDecl->abstractSchemaName); $sql .= $class->getQuotedTableName($this->_platform) . ' ' - . $this->getSqlTableAlias($class->getTableName(), $dqlAlias); + . $this->getSqlTableAlias($class->primaryTable['name'], $dqlAlias); if ($class->isInheritanceTypeJoined()) { $sql .= $this->_generateClassTableInheritanceJoins($class, $dqlAlias); @@ -795,10 +883,11 @@ class SqlWalker implements TreeWalker $identificationVarDecls = $subselectFromClause->identificationVariableDeclarations; $firstIdentificationVarDecl = $identificationVarDecls[0]; $rangeDecl = $firstIdentificationVarDecl->rangeVariableDeclaration; - $tblName = $rangeDecl->classMetadata->getTableName(); + $class = $this->_em->getClassMetadata($rangeDecl->abstractSchemaName); + $dqlAlias = $rangeDecl->aliasIdentificationVariable; - $sql = ' FROM ' . $rangeDecl->classMetadata->getQuotedTableName($this->_platform) . ' ' - . $this->getSqlTableAlias($tblName, $rangeDecl->aliasIdentificationVariable); + $sql = ' FROM ' . $class->getQuotedTableName($this->_platform) . ' ' + . $this->getSqlTableAlias($class->primaryTable['name'], $dqlAlias); foreach ($firstIdentificationVarDecl->joinVariableDeclarations as $joinVarDecl) { $sql .= $this->walkJoinVariableDeclaration($joinVarDecl); @@ -1013,40 +1102,6 @@ class SqlWalker implements TreeWalker return $sql; } - /** - * Generates a discriminator column SQL condition for the class with the given DQL alias. - * - * @param string $dqlAlias - * @return string - */ - private function _generateDiscriminatorColumnConditionSql($dqlAlias) - { - $sql = ''; - if ($dqlAlias) { - $class = $this->_queryComponents[$dqlAlias]['metadata']; - - if ($class->isInheritanceTypeSingleTable()) { - $conn = $this->_em->getConnection(); - $values = array($conn->quote($class->discriminatorValue)); - - foreach ($class->subClasses as $subclassName) { - $values[] = $conn->quote($this->_em->getClassMetadata($subclassName)->discriminatorValue); - } - - $discrColumn = $class->discriminatorColumn; - - if ($this->_useSqlTableAliases) { - $sql .= $this->getSqlTableAlias($class->getTableName(), $dqlAlias) . '.'; - } - - $sql .= $class->getQuotedDiscriminatorColumnName($this->_platform) . - ' IN (' . implode(', ', $values) . ')'; - } - } - - return $sql; - } - /** * Walks down a ConditionalTerm AST node, thereby generating the appropriate SQL. * @@ -1447,7 +1502,7 @@ class SqlWalker implements TreeWalker $primary = $factor->arithmeticPrimary; if (is_numeric($primary)) { - $sql .= $primary; // We should not quote numeric values! + $sql .= $primary; } else if (is_string($primary)) { $sql .= $this->_conn->quote($primary); } else if ($primary instanceof AST\SimpleArithmeticExpression) { @@ -1471,51 +1526,4 @@ class SqlWalker implements TreeWalker ' ', array_map(array($this, 'walkArithmeticTerm'), $simpleArithmeticExpr->arithmeticTerms) ); } - - /** - * Walks down a PathExpression AST node, thereby generating the appropriate SQL. - * - * @param mixed - * @return string The SQL. - */ - public function walkPathExpression($pathExpr) - { - $sql = ''; - $pathExprType = $pathExpr->type; - - if ($pathExprType == AST\PathExpression::TYPE_STATE_FIELD) { - $parts = $pathExpr->parts; - $numParts = count($parts); - $dqlAlias = $pathExpr->identificationVariable; - $fieldName = $parts[$numParts - 1]; - $qComp = $this->_queryComponents[$dqlAlias]; - $class = $qComp['metadata']; - - if ($this->_useSqlTableAliases) { - if ($class->isInheritanceTypeJoined() && isset($class->fieldMappings[$fieldName]['inherited'])) { - $sql .= $this->getSqlTableAlias( - $this->_em->getClassMetadata($class->fieldMappings[$fieldName]['inherited'])->getTableName(), - $dqlAlias - ) . '.'; - } else { - $sql .= $this->getSqlTableAlias($class->getTableName(), $dqlAlias) . '.'; - } - } - - if (isset($class->associationMappings[$fieldName])) { - //FIXME: Inverse side support - //FIXME: Throw exception on composite key - $assoc = $class->associationMappings[$fieldName]; - $sql .= $assoc->getQuotedJoinColumnName($assoc->joinColumns[0]['name'], $this->_platform); - } else { - $sql .= $class->getQuotedColumnName($fieldName, $this->_platform); - } - } else if ($pathExprType == AST\PathExpression::TYPE_COLLECTION_VALUED_ASSOCIATION) { - throw DoctrineException::updateMe("Not yet implemented."); - } else { - throw DoctrineException::updateMe("Encountered invalid PathExpression during SQL construction."); - } - - return $sql; - } }