/** * {@inheritdoc} */ public function walkSubselectFromClause($subselectFromClause) { $identificationVarDecls = $subselectFromClause->identificationVariableDeclarations; $sqlParts = array(); foreach ($identificationVarDecls as $subselectIdVarDecl) { $sql = $this->walkRangeVariableDeclaration($subselectIdVarDecl->rangeVariableDeclaration); foreach ($subselectIdVarDecl->joins as $join) { $sql .= $this->walkJoin($join); } $sqlParts[] = $this->platform->appendLockHint($sql, $this->query->getHint(Query::HINT_LOCK_MODE)); } return ' FROM ' . implode(', ', $sqlParts); }
/** * {@inheritdoc} */ public function walkSelectExpression($selectExpression) { $sql = ''; $expr = $selectExpression->expression; $hidden = $selectExpression->hiddenAliasResultVariable; switch (true) { case $expr instanceof AST\PathExpression: if ($expr->type !== AST\PathExpression::TYPE_STATE_FIELD) { throw QueryException::invalidPathExpression($expr); } $fieldName = $expr->field; $dqlAlias = $expr->identificationVariable; $qComp = $this->queryComponents[$dqlAlias]; $class = $qComp['metadata']; $resultAlias = $selectExpression->fieldIdentificationVariable ?: $fieldName; $tableName = $class->isInheritanceTypeJoined() ? $this->em->getUnitOfWork()->getEntityPersister($class->name)->getOwningTable($fieldName) : $class->getTableName(); $sqlTableAlias = $this->getSQLTableAlias($tableName, $dqlAlias); $columnName = $this->quoteStrategy->getColumnName($fieldName, $class, $this->platform); $columnAlias = $this->getSQLColumnAlias($class->fieldMappings[$fieldName]['columnName']); $col = $sqlTableAlias . '.' . $columnName; $fieldType = $class->getTypeOfField($fieldName); if (isset($class->fieldMappings[$fieldName]['requireSQLConversion'])) { $type = Type::getType($fieldType); $col = $type->convertToPHPValueSQL($col, $this->conn->getDatabasePlatform()); } $sql .= $col . ' AS ' . $columnAlias; $this->scalarResultAliasMap[$resultAlias] = $columnAlias; if (!$hidden) { $this->rsm->addScalarResult($columnAlias, $resultAlias, $fieldType); $this->scalarFields[$dqlAlias][$fieldName] = $columnAlias; } break; case $expr instanceof AST\AggregateExpression: case $expr instanceof AST\Functions\FunctionNode: case $expr instanceof AST\SimpleArithmeticExpression: case $expr instanceof AST\ArithmeticTerm: case $expr instanceof AST\ArithmeticFactor: case $expr instanceof AST\ParenthesisExpression: case $expr instanceof AST\Literal: case $expr instanceof AST\NullIfExpression: case $expr instanceof AST\CoalesceExpression: case $expr instanceof AST\GeneralCaseExpression: case $expr instanceof AST\SimpleCaseExpression: $columnAlias = $this->getSQLColumnAlias('sclr'); $resultAlias = $selectExpression->fieldIdentificationVariable ?: $this->scalarResultCounter++; $sql .= $expr->dispatch($this) . ' AS ' . $columnAlias; $this->scalarResultAliasMap[$resultAlias] = $columnAlias; if (!$hidden) { // We cannot resolve field type here; assume 'string'. $this->rsm->addScalarResult($columnAlias, $resultAlias, 'string'); } break; case $expr instanceof AST\Subselect: $columnAlias = $this->getSQLColumnAlias('sclr'); $resultAlias = $selectExpression->fieldIdentificationVariable ?: $this->scalarResultCounter++; $sql .= '(' . $this->walkSubselect($expr) . ') AS ' . $columnAlias; $this->scalarResultAliasMap[$resultAlias] = $columnAlias; if (!$hidden) { // We cannot resolve field type here; assume 'string'. $this->rsm->addScalarResult($columnAlias, $resultAlias, 'string'); } break; case $expr instanceof AST\NewObjectExpression: $sql .= $this->walkNewObject($expr, $selectExpression->fieldIdentificationVariable); break; default: // 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']; $resultAlias = $selectExpression->fieldIdentificationVariable ?: null; if (!isset($this->selectedClasses[$dqlAlias])) { $this->selectedClasses[$dqlAlias] = array('class' => $class, 'dqlAlias' => $dqlAlias, 'resultAlias' => $resultAlias); } $sqlParts = array(); // Select all fields from the queried class foreach ($class->fieldMappings as $fieldName => $mapping) { if ($partialFieldSet && !in_array($fieldName, $partialFieldSet)) { continue; } $tableName = isset($mapping['inherited']) ? $this->em->getClassMetadata($mapping['inherited'])->getTableName() : $class->getTableName(); $sqlTableAlias = $this->getSQLTableAlias($tableName, $dqlAlias); $columnAlias = $this->getSQLColumnAlias($mapping['columnName']); $quotedColumnName = $this->quoteStrategy->getColumnName($fieldName, $class, $this->platform); $col = $sqlTableAlias . '.' . $quotedColumnName; if (isset($class->fieldMappings[$fieldName]['requireSQLConversion'])) { $type = Type::getType($class->getTypeOfField($fieldName)); $col = $type->convertToPHPValueSQL($col, $this->platform); } $sqlParts[] = $col . ' AS ' . $columnAlias; $this->scalarResultAliasMap[$resultAlias][] = $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->getTableName(), $dqlAlias); foreach ($subClass->fieldMappings as $fieldName => $mapping) { if (isset($mapping['inherited']) || $partialFieldSet && !in_array($fieldName, $partialFieldSet)) { continue; } $columnAlias = $this->getSQLColumnAlias($mapping['columnName']); $quotedColumnName = $this->quoteStrategy->getColumnName($fieldName, $subClass, $this->platform); $col = $sqlTableAlias . '.' . $quotedColumnName; if (isset($subClass->fieldMappings[$fieldName]['requireSQLConversion'])) { $type = Type::getType($subClass->getTypeOfField($fieldName)); $col = $type->convertToPHPValueSQL($col, $this->platform); } $sqlParts[] = $col . ' AS ' . $columnAlias; $this->scalarResultAliasMap[$resultAlias][] = $columnAlias; $this->rsm->addFieldResult($dqlAlias, $columnAlias, $fieldName, $subClassName); } } } $sql .= implode(', ', $sqlParts); } return $sql; }