/** * Walks down a SelectClause AST node, thereby generating the appropriate SQL. * * @param $selectClause * @return string The SQL. */ public function walkSelectClause($selectClause) { $sql = 'SELECT ' . ($selectClause->isDistinct ? 'DISTINCT ' : '') . implode(', ', array_map(array($this, 'walkSelectExpression'), $selectClause->selectExpressions)); $addMetaColumns = !$this->_query->getHint(Query::HINT_FORCE_PARTIAL_LOAD) && $this->_query->getHydrationMode() == Query::HYDRATE_OBJECT || $this->_query->getHydrationMode() != Query::HYDRATE_OBJECT && $this->_query->getHint(Query::HINT_INCLUDE_META_COLUMNS); foreach ($this->_selectedClasses as $dqlAlias => $class) { // Register as entity or joined entity result if ($this->_queryComponents[$dqlAlias]['relation'] === null) { $this->_rsm->addEntityResult($class->name, $dqlAlias); } else { $this->_rsm->addJoinedEntityResult($class->name, $dqlAlias, $this->_queryComponents[$dqlAlias]['parent'], $this->_queryComponents[$dqlAlias]['relation']->sourceFieldName); } if ($class->isInheritanceTypeSingleTable() || $class->isInheritanceTypeJoined()) { // Add discriminator columns to SQL $rootClass = $this->_em->getClassMetadata($class->rootEntityName); $tblAlias = $this->getSqlTableAlias($rootClass->primaryTable['name'], $dqlAlias); $discrColumn = $rootClass->discriminatorColumn; $columnAlias = $this->getSqlColumnAlias($discrColumn['name']); $sql .= ", {$tblAlias}." . $discrColumn['name'] . ' AS ' . $columnAlias; $columnAlias = $this->_platform->getSQLResultCasing($columnAlias); $this->_rsm->setDiscriminatorColumn($dqlAlias, $columnAlias); $this->_rsm->addMetaResult($dqlAlias, $this->_platform->getSQLResultCasing($columnAlias), $discrColumn['fieldName']); // Add foreign key columns to SQL, if necessary if ($addMetaColumns) { //FIXME: Include foreign key columns of child classes also!!?? foreach ($class->associationMappings as $assoc) { if ($assoc->isOwningSide && $assoc->isOneToOne()) { if (isset($class->inheritedAssociationFields[$assoc->sourceFieldName])) { $owningClass = $this->_em->getClassMetadata($class->inheritedAssociationFields[$assoc->sourceFieldName]); $sqlTableAlias = $this->getSqlTableAlias($owningClass->primaryTable['name'], $dqlAlias); } else { $sqlTableAlias = $this->getSqlTableAlias($class->primaryTable['name'], $dqlAlias); } foreach ($assoc->targetToSourceKeyColumns as $srcColumn) { $columnAlias = $this->getSqlColumnAlias($srcColumn); $sql .= ", {$sqlTableAlias}." . $srcColumn . ' AS ' . $columnAlias; $columnAlias = $this->_platform->getSQLResultCasing($columnAlias); $this->_rsm->addMetaResult($dqlAlias, $this->_platform->getSQLResultCasing($columnAlias), $srcColumn); } } } } } else { // 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) { $columnAlias = $this->getSqlColumnAlias($srcColumn); $sql .= ', ' . $sqlTableAlias . '.' . $srcColumn . ' AS ' . $columnAlias; $columnAlias = $this->_platform->getSQLResultCasing($columnAlias); $this->_rsm->addMetaResult($dqlAlias, $this->_platform->getSQLResultCasing($columnAlias), $srcColumn); } } } } } } return $sql; }
/** * @group DDC-1470 * * @expectedException \Doctrine\ORM\Internal\Hydration\HydrationException * @expectedExceptionMessage The discriminator column "discr" is missing for "Doctrine\Tests\Models\Company\CompanyPerson" using the DQL alias "p". */ public function testMissingDiscriminatorColumnException() { $rsm = new ResultSetMapping(); $rsm->addEntityResult('Doctrine\\Tests\\Models\\Company\\CompanyPerson', 'p'); $rsm->addFieldResult('p', 'p__id', 'id'); $rsm->addFieldResult('p', 'p__name', 'name'); $rsm->addMetaResult('p ', 'discr', 'discr'); $rsm->setDiscriminatorColumn('p', 'discr'); $resultSet = array(array('u__id' => '1', 'u__name' => 'Fabio B. Silva')); $stmt = new HydratorMockStatement($resultSet); $hydrator = new \Doctrine\ORM\Internal\Hydration\SimpleObjectHydrator($this->_em); $hydrator->hydrateAll($stmt, $rsm); }
/** * {@inheritdoc} */ public function walkSelectClause($selectClause) { $sql = 'SELECT ' . ($selectClause->isDistinct ? 'DISTINCT ' : ''); $sqlSelectExpressions = array_filter(array_map(array($this, 'walkSelectExpression'), $selectClause->selectExpressions)); if ($this->query->getHint(Query::HINT_INTERNAL_ITERATION) == true && $selectClause->isDistinct) { $this->query->setHint(self::HINT_DISTINCT, true); } $addMetaColumns = !$this->query->getHint(Query::HINT_FORCE_PARTIAL_LOAD) && $this->query->getHydrationMode() == Query::HYDRATE_OBJECT || $this->query->getHydrationMode() != Query::HYDRATE_OBJECT && $this->query->getHint(Query::HINT_INCLUDE_META_COLUMNS); foreach ($this->selectedClasses as $selectedClass) { $class = $selectedClass['class']; $dqlAlias = $selectedClass['dqlAlias']; $resultAlias = $selectedClass['resultAlias']; // Register as entity or joined entity result if ($this->queryComponents[$dqlAlias]['relation'] === null) { $this->rsm->addEntityResult($class->name, $dqlAlias, $resultAlias); } else { $this->rsm->addJoinedEntityResult($class->name, $dqlAlias, $this->queryComponents[$dqlAlias]['parent'], $this->queryComponents[$dqlAlias]['relation']['fieldName']); } if ($class->isInheritanceTypeSingleTable() || $class->isInheritanceTypeJoined()) { // Add discriminator columns to SQL $rootClass = $this->em->getClassMetadata($class->rootEntityName); $tblAlias = $this->getSQLTableAlias($rootClass->getTableName(), $dqlAlias); $discrColumn = $rootClass->discriminatorColumn; $columnAlias = $this->getSQLColumnAlias($discrColumn['name']); $sqlSelectExpressions[] = $tblAlias . '.' . $discrColumn['name'] . ' AS ' . $columnAlias; $this->rsm->setDiscriminatorColumn($dqlAlias, $columnAlias); $this->rsm->addMetaResult($dqlAlias, $columnAlias, $discrColumn['fieldName']); } // Add foreign key columns to SQL, if necessary if (!$addMetaColumns && !$class->containsForeignIdentifier) { continue; } // Add foreign key columns of class and also parent classes foreach ($class->associationMappings as $assoc) { if (!($assoc['isOwningSide'] && $assoc['type'] & ClassMetadata::TO_ONE)) { continue; } else { if (!$addMetaColumns && !isset($assoc['id'])) { continue; } } $owningClass = isset($assoc['inherited']) ? $this->em->getClassMetadata($assoc['inherited']) : $class; $sqlTableAlias = $this->getSQLTableAlias($owningClass->getTableName(), $dqlAlias); foreach ($assoc['targetToSourceKeyColumns'] as $srcColumn) { $columnAlias = $this->getSQLColumnAlias($srcColumn); $sqlSelectExpressions[] = $sqlTableAlias . '.' . $srcColumn . ' AS ' . $columnAlias; $this->rsm->addMetaResult($dqlAlias, $columnAlias, $srcColumn, isset($assoc['id']) && $assoc['id'] === true); } } // Add foreign key columns to SQL, if necessary if (!$addMetaColumns) { continue; } // Add foreign key columns of subclasses foreach ($class->subClasses as $subClassName) { $subClass = $this->em->getClassMetadata($subClassName); $sqlTableAlias = $this->getSQLTableAlias($subClass->getTableName(), $dqlAlias); foreach ($subClass->associationMappings as $assoc) { // Skip if association is inherited if (isset($assoc['inherited'])) { continue; } if (!($assoc['isOwningSide'] && $assoc['type'] & ClassMetadata::TO_ONE)) { continue; } foreach ($assoc['targetToSourceKeyColumns'] as $srcColumn) { $columnAlias = $this->getSQLColumnAlias($srcColumn); $sqlSelectExpressions[] = $sqlTableAlias . '.' . $srcColumn . ' AS ' . $columnAlias; $this->rsm->addMetaResult($dqlAlias, $columnAlias, $srcColumn); } } } } $sql .= implode(', ', $sqlSelectExpressions); return $sql; }
/** * @group DDC-1470 * * @expectedException \Doctrine\ORM\Internal\Hydration\HydrationException * @expectedExceptionMessage The discriminator column "discr" is missing for "Doctrine\Tests\Models\Company\CompanyEmployee" using the DQL alias "e". */ public function testMissingDiscriminatorColumnException() { $rsm = new ResultSetMapping(); $rsm->addEntityResult('Doctrine\\Tests\\Models\\Company\\CompanyFixContract', 'c'); $rsm->addJoinedEntityResult('Doctrine\\Tests\\Models\\Company\\CompanyEmployee', 'e', 'c', 'salesPerson'); $rsm->addFieldResult('c', 'c__id', 'id'); $rsm->addMetaResult('c', 'c_discr', 'discr'); $rsm->setDiscriminatorColumn('c', 'c_discr'); $rsm->addFieldResult('e', 'e__id', 'id'); $rsm->addFieldResult('e', 'e__name', 'name'); $rsm->addMetaResult('e ', 'e_discr', 'discr'); $rsm->setDiscriminatorColumn('e', 'e_discr'); $resultSet = array(array('c__id' => '1', 'c_discr' => 'fix', 'e__id' => '1', 'e__name' => 'Fabio B. Silva')); $stmt = new HydratorMockStatement($resultSet); $hydrator = new \Doctrine\ORM\Internal\Hydration\ObjectHydrator($this->_em); $hydrator->hydrateAll($stmt, $rsm); }