Skip to content

Instantly share code, notes, and snippets.

@doctrinebot
Created December 13, 2015 18:48
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/f81a0fd9ff2c735d7967 to your computer and use it in GitHub Desktop.
Save doctrinebot/f81a0fd9ff2c735d7967 to your computer and use it in GitHub Desktop.
Attachments to Doctrine Jira Issue DDC-719 - https://github.com/doctrine/doctrine2/issues/5232
diff --git a/lib/Doctrine/ORM/Query/AST/Functions/SizeFunction.php b/lib/Doctrine/ORM/Query/AST/Functions/SizeFunction.php
index cd6741f..864c3eb 100644
--- a/lib/Doctrine/ORM/Query/AST/Functions/SizeFunction.php
+++ b/lib/Doctrine/ORM/Query/AST/Functions/SizeFunction.php
@@ -45,45 +45,66 @@ class SizeFunction extends FunctionNode
*/
public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker)
{
+ $platform = $sqlWalker->getConnection()->getDatabasePlatform();
$dqlAlias = $this->collectionPathExpression->identificationVariable;
$assocField = $this->collectionPathExpression->field;
$qComp = $sqlWalker->getQueryComponent($dqlAlias);
- $assoc = $qComp['metadata']->associationMappings[$assocField];
- $sql = '';
-
+ $class = $qComp['metadata'];
+ $assoc = $class->associationMappings[$assocField];
+ $sql = 'SELECT COUNT(*) FROM ';
+
if ($assoc->isOneToMany()) {
$targetClass = $sqlWalker->getEntityManager()->getClassMetadata($assoc->targetEntityName);
- $targetAssoc = $targetClass->associationMappings[$assoc->mappedBy];
-
$targetTableAlias = $sqlWalker->getSqlTableAlias($targetClass->table['name']);
- $sourceTableAlias = $sqlWalker->getSqlTableAlias($qComp['metadata']->table['name'], $dqlAlias);
-
- $whereSql = '';
+ $sourceTableAlias = $sqlWalker->getSqlTableAlias($class->table['name'], $dqlAlias);
- foreach ($targetAssoc->targetToSourceKeyColumns as $targetKeyColumn => $sourceKeyColumn) {
- $whereSql .= (($whereSql == '') ? ' WHERE ' : ' AND ')
- . $targetTableAlias . '.' . $sourceKeyColumn . ' = '
- . $sourceTableAlias . '.' . $targetKeyColumn;
- }
+ $sql .= $targetClass->getQuotedTableName($platform) . ' ' . $targetTableAlias . ' WHERE ';
+
+ $owningAssoc = $targetClass->associationMappings[$assoc->mappedBy];
- $tableName = $targetClass->table['name'];
- } else if ($assoc->isManyToMany()) {
- $targetTableAlias = $sqlWalker->getSqlTableAlias($assoc->joinTable['name']);
- $sourceTableAlias = $sqlWalker->getSqlTableAlias($qComp['metadata']->table['name'], $dqlAlias);
+ $first = true;
- $whereSql = '';
+ foreach ($owningAssoc->targetToSourceKeyColumns as $targetColumn => $sourceColumn) {
+ if ($first) $first = false; else $sql .= ' AND ';
- foreach ($assoc->relationToSourceKeyColumns as $targetKeyColumn => $sourceKeyColumn) {
- $whereSql .= (($whereSql == '') ? ' WHERE ' : ' AND ')
- . $targetTableAlias . '.' . $targetKeyColumn . ' = '
- . $sourceTableAlias . '.' . $sourceKeyColumn;
+ $sql .= $targetTableAlias . '.' . $sourceColumn
+ . ' = '
+ . $sourceTableAlias . '.' . $class->getQuotedColumnName($class->fieldNames[$targetColumn], $platform);
}
+ } else { // many-to-many
+ $targetClass = $sqlWalker->getEntityManager()->getClassMetadata($assoc->targetEntityName);
+
+ $owningAssoc = $assoc->isOwningSide ? $assoc : $targetClass->associationMappings[$assoc->mappedBy];
+ $joinTable = $assoc->isOwningSide ? $assoc->joinTable : $owningAssoc->joinTable;
- $tableName = $assoc->joinTable['name'];
+ // SQL table aliases
+ $joinTableAlias = $sqlWalker->getSqlTableAlias($joinTable['name']);
+ $sourceTableAlias = $sqlWalker->getSqlTableAlias($class->table['name'], $dqlAlias);
+
+ // join to target table
+ $sql .= $owningAssoc->getQuotedJoinTableName($platform) . ' ' . $joinTableAlias . ' WHERE ';
+
+ $joinColumns = $assoc->isOwningSide
+ ? $joinTable['joinColumns']
+ : $joinTable['inverseJoinColumns'];
+
+ $first = true;
+
+ foreach ($joinColumns as $joinColumn) {
+ if ($first) $first = false; else $sql .= ' AND ';
+
+ $sourceColumnName = $class->getQuotedColumnName(
+ $class->fieldNames[$joinColumn['referencedColumnName']], $platform
+ );
+
+ $sql .= $joinTableAlias . '.' . $joinColumn['name']
+ . ' = '
+ . $sourceTableAlias . '.' . $sourceColumnName;
+ }
}
- return '(SELECT COUNT(*) FROM ' . $tableName . ' ' . $targetTableAlias . $whereSql . ')';
+ return '(' . $sql . ')';
}
/**
diff --git a/lib/Doctrine/ORM/Query/SqlWalker.php b/lib/Doctrine/ORM/Query/SqlWalker.php
index b00ffcc..9f364f6 100644
--- a/lib/Doctrine/ORM/Query/SqlWalker.php
+++ b/lib/Doctrine/ORM/Query/SqlWalker.php
@@ -1401,7 +1401,7 @@ class SqlWalker implements TreeWalker
$sourceTableAlias = $this->getSqlTableAlias($class->table['name'], $dqlAlias);
// join to target table
- $sql .= $assoc->getQuotedJoinTableName($this->_platform)
+ $sql .= $owningAssoc->getQuotedJoinTableName($this->_platform)
. ' ' . $joinTableAlias . ' INNER JOIN '
. $targetClass->getQuotedTableName($this->_platform)
. ' ' . $targetTableAlias . ' ON ';
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment