예제 #1
0
    /**
     * Walks down a SubselectFromClause AST node, thereby generating the appropriate SQL.
     *
     * @param SubselectFromClause
     * @return string The SQL.
     */
    public function walkSubselectFromClause($subselectFromClause)
    {
        $identificationVarDecls = $subselectFromClause->identificationVariableDeclarations;
        $sqlParts = array ();

        foreach ($identificationVarDecls as $subselectIdVarDecl) {
            $sql = '';

            $rangeDecl = $subselectIdVarDecl->rangeVariableDeclaration;
            $dqlAlias = $rangeDecl->aliasIdentificationVariable;

            $class = $this->_em->getClassMetadata($rangeDecl->abstractSchemaName);
            $sql .= $class->getQuotedTableName($this->_platform) . ' '
                  . $this->getSQLTableAlias($class->table['name'], $dqlAlias);

            if ($class->isInheritanceTypeJoined()) {
                $sql .= $this->_generateClassTableInheritanceJoins($class, $dqlAlias);
            }

            foreach ($subselectIdVarDecl->joinVariableDeclarations as $joinVarDecl) {
                $sql .= $this->walkJoinVariableDeclaration($joinVarDecl);
            }

            $sqlParts[] = $this->_platform->appendLockHint($sql, $this->_query->getHint(Query::HINT_LOCK_MODE));
        }

        return ' FROM ' . implode(', ', $sqlParts);
    }
예제 #2
0
 /**
  * Walks down a SubselectFromClause AST node, thereby generating the appropriate SQL.
  *
  * @param SubselectFromClause
  * @return string The SQL.
  */
 public function walkSubselectFromClause($subselectFromClause)
 {
     $identificationVarDecls = $subselectFromClause->identificationVariableDeclarations;
     $sqlParts = array();
     foreach ($identificationVarDecls as $subselectIdVarDecl) {
         $sql = $this->platform->appendLockHint($this->walkRangeVariableDeclaration($subselectIdVarDecl->rangeVariableDeclaration), $this->query->getHint(Query::HINT_LOCK_MODE));
         foreach ($subselectIdVarDecl->joins as $join) {
             $sql .= $this->walkJoin($join);
         }
         $sqlParts[] = $sql;
     }
     return ' FROM ' . implode(', ', $sqlParts);
 }
예제 #3
0
 /**
  * Walks down a SelectExpression AST node and generates the corresponding SQL.
  *
  * @param SelectExpression $selectExpression
  * @return string The SQL.
  */
 public function walkSelectExpression($selectExpression)
 {
     $sql = '';
     $expr = $selectExpression->expression;
     if ($expr instanceof AST\PathExpression) {
         if ($expr->type == AST\PathExpression::TYPE_STATE_FIELD) {
             $parts = $expr->parts;
             $fieldName = array_pop($parts);
             $dqlAlias = $expr->identificationVariable . (!empty($parts) ? '.' . implode('.', $parts) : '');
             $qComp = $this->_queryComponents[$dqlAlias];
             $class = $qComp['metadata'];
             if (!$selectExpression->fieldIdentificationVariable) {
                 $resultAlias = $fieldName;
             } else {
                 $resultAlias = $selectExpression->fieldIdentificationVariable;
             }
             if ($class->isInheritanceTypeJoined()) {
                 $tableName = $this->_em->getUnitOfWork()->getEntityPersister($class->name)->getOwningTable($fieldName);
             } else {
                 $tableName = $class->getTableName();
             }
             $sqlTableAlias = $this->getSqlTableAlias($tableName, $dqlAlias);
             $columnName = $class->getQuotedColumnName($fieldName, $this->_platform);
             $columnAlias = $this->getSqlColumnAlias($columnName);
             $sql .= $sqlTableAlias . '.' . $columnName . ' AS ' . $columnAlias;
             $columnAlias = $this->_platform->getSQLResultCasing($columnAlias);
             $this->_rsm->addScalarResult($columnAlias, $resultAlias);
         } else {
             throw QueryException::invalidPathExpression($expr->type);
         }
     } else {
         if ($expr instanceof AST\AggregateExpression) {
             if (!$selectExpression->fieldIdentificationVariable) {
                 $resultAlias = $this->_scalarResultCounter++;
             } else {
                 $resultAlias = $selectExpression->fieldIdentificationVariable;
             }
             $columnAlias = 'sclr' . $this->_aliasCounter++;
             $sql .= $this->walkAggregateExpression($expr) . ' AS ' . $columnAlias;
             $this->_scalarResultAliasMap[$resultAlias] = $columnAlias;
             $columnAlias = $this->_platform->getSQLResultCasing($columnAlias);
             $this->_rsm->addScalarResult($columnAlias, $resultAlias);
         } else {
             if ($expr instanceof AST\Subselect) {
                 if (!$selectExpression->fieldIdentificationVariable) {
                     $resultAlias = $this->_scalarResultCounter++;
                 } else {
                     $resultAlias = $selectExpression->fieldIdentificationVariable;
                 }
                 $columnAlias = 'sclr' . $this->_aliasCounter++;
                 $sql .= '(' . $this->walkSubselect($expr) . ') AS ' . $columnAlias;
                 $this->_scalarResultAliasMap[$resultAlias] = $columnAlias;
                 $columnAlias = $this->_platform->getSQLResultCasing($columnAlias);
                 $this->_rsm->addScalarResult($columnAlias, $resultAlias);
             } else {
                 if ($expr instanceof AST\Functions\FunctionNode) {
                     if (!$selectExpression->fieldIdentificationVariable) {
                         $resultAlias = $this->_scalarResultCounter++;
                     } else {
                         $resultAlias = $selectExpression->fieldIdentificationVariable;
                     }
                     $columnAlias = 'sclr' . $this->_aliasCounter++;
                     $sql .= $this->walkFunction($expr) . ' AS ' . $columnAlias;
                     $this->_scalarResultAliasMap[$resultAlias] = $columnAlias;
                     $columnAlias = $this->_platform->getSQLResultCasing($columnAlias);
                     $this->_rsm->addScalarResult($columnAlias, $resultAlias);
                 } else {
                     if ($expr instanceof AST\SimpleArithmeticExpression) {
                         if (!$selectExpression->fieldIdentificationVariable) {
                             $resultAlias = $this->_scalarResultCounter++;
                         } else {
                             $resultAlias = $selectExpression->fieldIdentificationVariable;
                         }
                         $columnAlias = 'sclr' . $this->_aliasCounter++;
                         $sql .= $this->walkSimpleArithmeticExpression($expr) . ' AS ' . $columnAlias;
                         $this->_scalarResultAliasMap[$resultAlias] = $columnAlias;
                         $columnAlias = $this->_platform->getSQLResultCasing($columnAlias);
                         $this->_rsm->addScalarResult($columnAlias, $resultAlias);
                     } else {
                         // IdentificationVariable or PartialObjectExpression
                         if ($expr instanceof AST\PartialObjectExpression) {
                             $dqlAlias = $expr->identificationVariable;
                             $partialFieldSet = $expr->partialFieldSet;
                         } else {
                             $dqlAlias = $expr;
                             $partialFieldSet = array();
                         }
                         $queryComp = $this->_queryComponents[$dqlAlias];
                         $class = $queryComp['metadata'];
                         if (!isset($this->_selectedClasses[$dqlAlias])) {
                             $this->_selectedClasses[$dqlAlias] = $class;
                         }
                         $beginning = true;
                         // Select all fields from the queried class
                         foreach ($class->fieldMappings as $fieldName => $mapping) {
                             if ($partialFieldSet && !in_array($fieldName, $partialFieldSet)) {
                                 continue;
                             }
                             if (isset($mapping['inherited'])) {
                                 $tableName = $this->_em->getClassMetadata($mapping['inherited'])->primaryTable['name'];
                             } else {
                                 $tableName = $class->primaryTable['name'];
                             }
                             if ($beginning) {
                                 $beginning = false;
                             } else {
                                 $sql .= ', ';
                             }
                             $sqlTableAlias = $this->getSqlTableAlias($tableName, $dqlAlias);
                             $columnAlias = $this->getSqlColumnAlias($mapping['columnName']);
                             $sql .= $sqlTableAlias . '.' . $class->getQuotedColumnName($fieldName, $this->_platform) . ' AS ' . $columnAlias;
                             $columnAlias = $this->_platform->getSQLResultCasing($columnAlias);
                             $this->_rsm->addFieldResult($dqlAlias, $columnAlias, $fieldName, $class->name);
                         }
                         // Add any additional fields of subclasses (excluding inherited fields)
                         // 1) on Single Table Inheritance: always, since its marginal overhead
                         // 2) on Class Table Inheritance only if partial objects are disallowed,
                         //    since it requires outer joining subtables.
                         if ($class->isInheritanceTypeSingleTable() || !$this->_query->getHint(Query::HINT_FORCE_PARTIAL_LOAD)) {
                             foreach ($class->subClasses as $subClassName) {
                                 $subClass = $this->_em->getClassMetadata($subClassName);
                                 $sqlTableAlias = $this->getSqlTableAlias($subClass->primaryTable['name'], $dqlAlias);
                                 foreach ($subClass->fieldMappings as $fieldName => $mapping) {
                                     if (isset($mapping['inherited']) || $partialFieldSet && !in_array($fieldName, $partialFieldSet)) {
                                         continue;
                                     }
                                     if ($beginning) {
                                         $beginning = false;
                                     } else {
                                         $sql .= ', ';
                                     }
                                     $columnAlias = $this->getSqlColumnAlias($mapping['columnName']);
                                     $sql .= $sqlTableAlias . '.' . $subClass->getQuotedColumnName($fieldName, $this->_platform) . ' AS ' . $columnAlias;
                                     $columnAlias = $this->_platform->getSQLResultCasing($columnAlias);
                                     $this->_rsm->addFieldResult($dqlAlias, $columnAlias, $fieldName, $subClassName);
                                 }
                                 // Add join columns (foreign keys) of the subclass
                                 //TODO: Probably better do this in walkSelectClause to honor the INCLUDE_META_COLUMNS hint
                                 foreach ($subClass->associationMappings as $fieldName => $assoc) {
                                     if ($assoc->isOwningSide && $assoc->isOneToOne() && !isset($subClass->inheritedAssociationFields[$fieldName])) {
                                         foreach ($assoc->targetToSourceKeyColumns as $srcColumn) {
                                             if ($beginning) {
                                                 $beginning = false;
                                             } else {
                                                 $sql .= ', ';
                                             }
                                             $columnAlias = $this->getSqlColumnAlias($srcColumn);
                                             $sql .= $sqlTableAlias . '.' . $srcColumn . ' AS ' . $columnAlias;
                                             $this->_rsm->addMetaResult($dqlAlias, $this->_platform->getSQLResultCasing($columnAlias), $srcColumn);
                                         }
                                     }
                                 }
                             }
                         }
                     }
                 }
             }
         }
     }
     return $sql;
 }