Skip to content

Instantly share code, notes, and snippets.

@doctrinebot
Created December 13, 2015 18:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save doctrinebot/89a6a25f52905f6a57c4 to your computer and use it in GitHub Desktop.
Save doctrinebot/89a6a25f52905f6a57c4 to your computer and use it in GitHub Desktop.
Attachments to Doctrine Jira Issue DDC-416 - https://github.com/doctrine/doctrine2/issues/4913
Index: lib/Doctrine/ORM/Persisters/JoinedSubclassPersister.php
===================================================================
--- lib/Doctrine/ORM/Persisters/JoinedSubclassPersister.php (revision 7334)
+++ lib/Doctrine/ORM/Persisters/JoinedSubclassPersister.php (working copy)
@@ -320,6 +320,7 @@
$tableAlias = isset($this->_class->inheritedAssociationFields[$assoc->sourceFieldName]) ?
$this->_getSQLTableAlias($this->_em->getClassMetadata($this->_class->inheritedAssociationFields[$assoc->sourceFieldName]))
: $baseTableAlias;
+
foreach ($assoc->targetToSourceKeyColumns as $srcColumn) {
$columnAlias = $srcColumn . $this->_sqlAliasCounter++;
$columnList .= ", $tableAlias.$srcColumn AS $columnAlias";
@@ -333,6 +334,7 @@
// Add discriminator column (DO NOT ALIAS THIS COLUMN).
$discrColumn = $this->_class->discriminatorColumn['name'];
+
if ($this->_class->rootEntityName == $this->_class->name) {
$columnList .= ", $baseTableAlias.$discrColumn";
} else {
@@ -346,8 +348,11 @@
// INNER JOIN parent tables
$joinSql = '';
+ $parentClassesMetaData = array();
+
foreach ($this->_class->parentClasses as $parentClassName) {
$parentClass = $this->_em->getClassMetadata($parentClassName);
+
$tableAlias = $this->_getSQLTableAlias($parentClass);
$joinSql .= ' INNER JOIN ' . $parentClass->getQuotedTableName($this->_platform) . ' ' . $tableAlias . ' ON ';
$first = true;
@@ -355,6 +360,8 @@
if ($first) $first = false; else $joinSql .= ' AND ';
$joinSql .= $baseTableAlias . '.' . $idColumn . ' = ' . $tableAlias . '.' . $idColumn;
}
+
+ $parentClassColumns[$tableAlias] = $parentClass;
}
// OUTER JOIN sub tables
@@ -396,16 +403,58 @@
}
$conditionSql = '';
+ $assocFields = array();
+ if (isset($this->_class->associationMappings) && count($this->_class->associationMappings)) {
+ foreach ($this->_class->associationMappings as $mapColumnAlias => $mapObject) {
+ if (is_array($mapObject->joinColumnFieldNames) && count($mapObject->joinColumnFieldNames)) {
+ foreach ($mapObject->joinColumnFieldNames as $id => $fieldName) {
+ $assocFields[] = $fieldName;
+ }
+ }
+ }
+ }
foreach ($criteria as $field => $value) {
+ $tableAlias = $baseTableAlias;
+ $quotedColumnName = false;
+ if (count($parentClassColumns)) {
+ foreach ($parentClassColumns as $parentTableAlias => $parentTableMetaData) {
+ if (in_array($field, $parentTableMetaData->columnNames) || in_array($field, $parentTableMetaData->fieldNames)) {
+ $tableAlias = $parentTableAlias;
+ $quotedColumnName = $parentTableMetaData->getQuotedColumnName($field, $this->_platform);
+ break 1;
+ } elseif (isset($parentTableMetaData->associationMappings) && count($parentTableMetaData->associationMappings)) {
+ foreach ($parentTableMetaData->associationMappings as $mapColumnAlias => $mapObject) {
+ // by table join column name
+ if ($mapColumnAlias == $field && isset($mapObject->joinColumns[0]['name'])) {
+ $tableAlias = $parentTableAlias;
+ $quotedColumnName = $this->_platform->quoteIdentifier($mapObject->joinColumns[0]['name']);
+ break 2;
+ }
+
+ // by table field name
+ if (in_array($field, $mapObject->joinColumnFieldNames)) {
+ $tableAlias = $parentTableAlias;
+ $quotedColumnName = $this->_platform->quoteIdentifier($field);
+ break 2;
+ }
+ }
+ }
+ }
+ }
+
if ($conditionSql != '') $conditionSql .= ' AND ';
- $conditionSql .= $baseTableAlias . '.';
- if (isset($this->_class->columnNames[$field])) {
+ $conditionSql .= $tableAlias . '.';
+
+ if ($quotedColumnName) {
+ $conditionSql .= $quotedColumnName;
+ } else if (isset($this->_class->columnNames[$field])) {
$conditionSql .= $this->_class->getQuotedColumnName($field, $this->_platform);
} else if ($assoc !== null) {
$conditionSql .= $field;
} else {
throw ORMException::unrecognizedField($field);
}
+
$conditionSql .= ' = ?';
}
@@ -419,11 +468,11 @@
}
return 'SELECT ' . $this->_selectColumnListSql
- . ' FROM ' . $this->_class->getQuotedTableName($this->_platform) . ' ' . $baseTableAlias
- . $joinSql
- . ($conditionSql != '' ? ' WHERE ' . $conditionSql : '') . $orderBySql;
+ . ' FROM ' . $this->_class->getQuotedTableName($this->_platform) . ' ' . $baseTableAlias
+ . $joinSql
+ . ($conditionSql != '' ? ' WHERE ' . $conditionSql : '') . $orderBySql;
}
-
+
/** Ensure this is never called. This persister overrides _getSelectEntitiesSQL directly. */
protected function _getSelectColumnListSQL()
{
Index: /var/www/doctrine/trunk/lib/Doctrine/ORM/Persisters/JoinedSubclassPersister.php
===================================================================
--- /var/www/doctrine/trunk/lib/Doctrine/ORM/Persisters/JoinedSubclassPersister.php (revision 7336)
+++ /var/www/doctrine/trunk/lib/Doctrine/ORM/Persisters/JoinedSubclassPersister.php (working copy)
@@ -343,20 +343,26 @@
$resultColumnName = $this->_platform->getSQLResultCasing($discrColumn);
$this->_resultColumnNames[$resultColumnName] = $discrColumn;
}
-
+
// INNER JOIN parent tables
$joinSql = '';
+ $arrJoinSql = array();
+ $parentClassColumns = array();
+ // Create array with links on parent classes
foreach ($this->_class->parentClasses as $parentClassName) {
$parentClass = $this->_em->getClassMetadata($parentClassName);
+
$tableAlias = $this->_getSQLTableAlias($parentClass);
- $joinSql .= ' INNER JOIN ' . $parentClass->getQuotedTableName($this->_platform) . ' ' . $tableAlias . ' ON ';
+ $arrJoinSql[$parentClassName] = ' INNER JOIN ' . $parentClass->getQuotedTableName($this->_platform) . ' ' . $tableAlias . ' ON ';
$first = true;
foreach ($idColumns as $idColumn) {
- if ($first) $first = false; else $joinSql .= ' AND ';
- $joinSql .= $baseTableAlias . '.' . $idColumn . ' = ' . $tableAlias . '.' . $idColumn;
+ if ($first) $first = false; else $arrJoinSql[$parentClassName] .= ' AND ';
+ $arrJoinSql[$parentClassName] .= $baseTableAlias . '.' . $idColumn . ' = ' . $tableAlias . '.' . $idColumn;
}
+ $parentClassColumns[$tableAlias] = $parentClass;
+ unset($parentClass);
}
-
+
// OUTER JOIN sub tables
foreach ($this->_class->subClasses as $subClassName) {
$subClass = $this->_em->getClassMetadata($subClassName);
@@ -387,19 +393,61 @@
}
// Add LEFT JOIN
- $joinSql .= ' LEFT JOIN ' . $subClass->getQuotedTableName($this->_platform) . ' ' . $tableAlias . ' ON ';
+ $arrJoinSql[$subClassName] = ' LEFT JOIN ' . $subClass->getQuotedTableName($this->_platform) . ' ' . $tableAlias . ' ON ';
$first = true;
+
foreach ($idColumns as $idColumn) {
- if ($first) $first = false; else $joinSql .= ' AND ';
- $joinSql .= $baseTableAlias . '.' . $idColumn . ' = ' . $tableAlias . '.' . $idColumn;
+ if ($first) $first = false; else $arrJoinSql[$subClassName] .= ' AND ';
+ $arrJoinSql[$subClassName] .= $baseTableAlias . '.' . $idColumn . ' = ' . $tableAlias . '.' . $idColumn;
}
}
+ // Create join part of sql query from array. Also, protect it from double joins.
+ $joinSql = ((is_array($arrJoinSql) && count($arrJoinSql)))?join('', array_unique($arrJoinSql)):'';
+
$conditionSql = '';
foreach ($criteria as $field => $value) {
+ $tableAlias = $baseTableAlias; // table name
+ $quotedColumnName = false; // Column name
+ // It may be column from other table. Check it.
+ if (isset($parentClassColumns) && count($parentClassColumns)) {
+ foreach ($parentClassColumns as $parentTableAlias => $parentTableMetaData) {
+ //foreach_mark
+ if (is_array($parentTableMetaData->columnNames)
+ && (in_array($field, $parentTableMetaData->columnNames)
+ || in_array($field, $parentTableMetaData->fieldNames))) {
+ $tableAlias = $parentTableAlias;
+ $quotedColumnName = $parentTableMetaData->getQuotedColumnName($field, $this->_platform);
+ break 1; // goto foreach_mark
+ } elseif (isset($parentTableMetaData->associationMappings)
+ && count($parentTableMetaData->associationMappings)) {
+ foreach ($parentTableMetaData->associationMappings as $mapColumnAlias => $mapObject) {
+ // by table join column name
+ if ($mapColumnAlias == $field && isset($mapObject->joinColumns[0]['name'])) {
+ $tableAlias = $parentTableAlias;
+ $quotedColumnName = $this->_platform->quoteIdentifier($mapObject->joinColumns[0]['name']);
+ break 2; // goto foreach_mark
+ }
+
+ // by table field name
+ if (is_object($mapObject)
+ && isset($mapObject->joinColumnFieldNames)
+ && in_array($field, $mapObject->joinColumnFieldNames)) {
+ $tableAlias = $parentTableAlias;
+ $quotedColumnName = $this->_platform->quoteIdentifier($field);
+ break 2; // goto foreach_mark
+ }
+ }
+ }
+ }
+ }
if ($conditionSql != '') $conditionSql .= ' AND ';
- $conditionSql .= $baseTableAlias . '.';
- if (isset($this->_class->columnNames[$field])) {
+ $conditionSql .= $tableAlias . '.';
+ if ($quotedColumnName) {
+ // Column from other table
+ $conditionSql .= $quotedColumnName;
+ } else if (isset($this->_class->columnNames[$field])) {
+ // Column fron this table
$conditionSql .= $this->_class->getQuotedColumnName($field, $this->_platform);
} else if ($assoc !== null) {
$conditionSql .= $field;
@@ -417,7 +465,7 @@
if ($this->_selectColumnListSql === null) {
$this->_selectColumnListSql = $columnList;
}
-
+
return 'SELECT ' . $this->_selectColumnListSql
. ' FROM ' . $this->_class->getQuotedTableName($this->_platform) . ' ' . $baseTableAlias
. $joinSql
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment