Skip to content

Loading…

DDC-416: [patch] findBy() and @InheritanceType("JOINED") #4913

Closed
doctrinebot opened this Issue · 13 comments

1 participant

@doctrinebot

Jira issue originally created by user freeakk:

My tables:

/****
 * @Entity
 * @Table(name="inventory_system")
 */
class inventorySystem extends privateInventoryBasic
{
    /****
     * @Column(name="name", type="string", length=255, nullable=true)
     */
    protected $name;

    /****
     * @Column(name="serial", type="string", length=255, nullable=true)
     */
    protected $serial;

    /****
     * @Column(name="boot", type="string", length=255, nullable=true)
     */
    protected $boot;

    /****
     * @Column(name="chassis", type="string", length=255, nullable=true)
     */
    protected $chassis;

    /****
     * @Column(name="smbios", type="string", length=255, nullable=true)
     */
    protected $smbios;

    /****
     * @Column(name="dmi", type="string", length=255, nullable=true)
     */
    protected $dmi;

    /****
     * @Column(name="bits", type="smallint", nullable=true)
     */
    protected $bits;

    /****
     * @Column(name="uuid", type="string", length=255, nullable=true)
     */
    protected $uuid;
/****
 * @Entity
 * @InheritanceType("JOINED") 
 * @DiscriminatorColumn(name="discr", type="smallint")
 * @DiscriminatorMap({
 * "0" = "privateInventoryBasic",
 * "1" = "inventorySystem", 
 * "2" = "inventoryBattery",
 * "3" = "inventoryBus",
 * "4" = "inventoryCache",
 * "5" = "inventoryCdrom",
 * "6" = "inventoryCpu",
 * "7" = "inventoryDisk",
 * "8" = "inventoryDisplay",
 * "9" = "inventoryFirmware",
 * "10" = "inventoryMemory",
 * "11" = "inventoryMemoryBank",
 * "12" = "inventoryMemoryController",
 * "13" = "inventoryMultimedia",
 * "14" = "inventoryNetwork",
 * "15" = "inventoryPciHostBridge",
 * "16" = "inventoryStorage",
 * "17" = "inventorySystem",
 * "18" = "inventoryUsbBus",
 * "19" = "inventoryUsbGeneric",
 * "20" = "inventoryUsbHost",
 * "21" = "inventoryVolume"
 * })
 * @Table(name="private*inventory*basic")
 * @HasLifecycleCallbacks 
 */
class privateInventoryBasic
{   
    static function getSearchFieldList()
    {
        return array('vendor', 'product', 'description', 'version');
    }
    /****
     * @Id
     * @Column(name="id", type="integer")
     * @GeneratedValue(strategy="AUTO")
     */
    private $id;

    /****
     * @Column(name="product", type="string", length=255, nullable=true)
     */
    private $product;

    /****
     * @Column(name="vendor", type="string", length=255, nullable=true)
     */
    private $vendor;

    /****
     * @Column(name="version", type="string", length=255, nullable=true)
     */
    private $version;

    /****
     * @Column(name="businfo", type="string", length=255, nullable=true)
     */
    private $businfo;

    /****
     * @Column(name="capabilities", type="bigint", nullable=true)
     */
    private $capabilities;

    /****
     * @Column(name="num", type="string", length=255, nullable=true)
     */
    private $num;

    /****
     * @Column(name="comment", type="string", length=255, nullable=true)
     */
    private $comment;

    /****
     * @Column(name="physid", type="string", length=255, nullable=true)
     */
    private $physid;

    /****
     * @Column(name="driver", type="string", length=255, nullable=true)
     */
    private $driver;

    /****
     * @Column(name="driver_version", type="string", length=255, nullable=true)
     */
    private $driverversion;

    /****
     * @Column(name="description", type="string", length=255, nullable=true)
     */
    private $description;

    /****
     * @Column(name="xml_id", type="string", length=255, nullable=true)
     */
    private $xmlId;

    /****
     * @ManyToOne(targetEntity="basicHost",  cascade={"all"}, fetch="EAGER")
     * @JoinColumn(name="host_id", referencedColumnName="id", onDelete="CASCADE", onUpdate="CASCADE", nullable=true)
     */
    private $hostId;
    private $hostIdValue;

    /****
     * @Column(name="class", type="string", length=255, nullable=true)
     */
    private $class;

    /****
     * @Column(name="handle", type="string", length=16, nullable=true)
     */
    private $handle;

    /****
     * @Column(name="parent_handle", type="string", length=16, nullable=true)
     */
    private $parentHandle;

hostId and xmlId are the fields of parent table.
This code gets error:
$dbObj = $em->getRepository('inventorySystem')->findOneBy(array('hostId' => $hostId, 'xmlId' => $xmlId))
This code gets no error:
$dbObj = $em->getRepository('inventorySystem')->findOneBy(array('name' => $name))

1) Shelly*Core_Task*DaemonTest::testRun
PDOException: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'i0.hostId' in 'where clause'

/var/www/shelly/library/Doctrine/ORM/Persisters/StandardEntityPersister.php:443
/var/www/shelly/library/Doctrine/ORM/EntityRepository.php:143
/var/www/shelly/application/library/Shelly/Core/Task/Lshw/Xml/Parser.php:44
/var/www/shelly/application/library/Shelly/Core/Task/Basic/Host/Lshw.php:12
/var/www/shelly/application/library/Shelly/Core/Task/Daemon.php:125
/var/www/shelly/tests/library/Shelly/Core/Task/DaemonTest.php:37
@doctrinebot

Comment created by freeakk:

SQL query:

SELECT 
    p1.id AS id2, 
    p1.product AS product3, 
    p1.vendor AS vendor4, 
    p1.version AS version5, 
    p1.businfo AS businfo6, 
    p1.capabilities AS capabilities7, 
    p1.num AS num8, 
    p1.comment AS comment9, 
    p1.physid AS physid10, 
    p1.driver AS driver11, 
    p1.driver*version AS driver*version12, 
    p1.description AS description13, 
    p1.xml*id AS xml*id14, 
    p1.class AS class15, 
    p1.handle AS handle16, 
    p1.parent*handle AS parent*handle17, 
    i0.name AS name18, 
    i0.serial AS serial19, 
    i0.boot AS boot20, 
    i0.chassis AS chassis21, 
    i0.smbios AS smbios22, 
    i0.dmi AS dmi23, 
    i0.bits AS bits24, 
    i0.uuid AS uuid25, 
    p1.host*id AS host*id26, 
    p1.discr 
FROM  inventory_system i0 
             INNER JOIN private*inventory_basic p1 ON i0.id = p1.id WHERE i0.hostId = ? AND i0.xml*id = ?
@doctrinebot

Comment created by freeakk:

I rewrite Doctrine\ORM\Persisters\JoinedSubclassPersister::_getSelectEntitiesSQL() function. I don't know how it will pass unit tests, but it work for my query :) New variant of method work with fields in parent tables and left join fields in parent tables

    /****
     * Gets the SELECT SQL to select one or more entities by a set of field criteria.
     *
     * @param array $criteria
     * @param AssociationMapping $assoc
     * @param string $orderBy
     * @return string
     * @override
     */
    protected function _getSelectEntitiesSQL(array &$criteria, $assoc = null, $orderBy = null)
    {
        $idColumns = $this->_class->getIdentifierColumnNames();
        $baseTableAlias = $this->*getSQLTableAlias($this->*class);

        if ($this->_selectColumnListSql === null) {
            // Add regular columns
            $columnList = '';
            foreach ($this->_class->fieldMappings as $fieldName => $mapping) {
                if ($columnList != '') $columnList .= ', ';
                $columnList .= $this->_getSelectColumnSQL($fieldName,
                isset($mapping['inherited']) ? $this->*em->getClassMetadata($mapping['inherited']) : $this->*class);
            }

            // Add foreign key columns
            foreach ($this->_class->associationMappings as $assoc) {
                if ($assoc->isOwningSide && $assoc->isOneToOne()) {
                    $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<ins></ins>;
                        $columnList .= ", $tableAlias.$srcColumn AS $columnAlias";
                        $resultColumnName = $this->_platform->getSQLResultCasing($columnAlias);
                        if ( ! isset($this->_resultColumnNames[$resultColumnName])) {
                            $this->_resultColumnNames[$resultColumnName] = $srcColumn;
                        }
                    }
                }
            }

            // Add discriminator column (DO NOT ALIAS THIS COLUMN).
            $discrColumn = $this->_class->discriminatorColumn['name'];
            if ($this->*class->rootEntityName == $this->*class->name) {
                $columnList .= ", $baseTableAlias.$discrColumn";
            } else {
                $columnList .= ', ' . $this->*getSQLTableAlias($this->_em->getClassMetadata($this->*class->rootEntityName))
                        . ".$discrColumn";
            }

            $resultColumnName = $this->_platform->getSQLResultCasing($discrColumn);
            $this->_resultColumnNames[$resultColumnName] = $discrColumn;
        }

        // 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;
            foreach ($idColumns as $idColumn) {
                if ($first) $first = false; else $joinSql .= ' AND ';
                $joinSql .= $baseTableAlias . '.' . $idColumn . ' = ' . $tableAlias . '.' . $idColumn;
            }
            $parentClassColumns[$tableAlias] = $parentClass;
        }

        // OUTER JOIN sub tables
        foreach ($this->_class->subClasses as $subClassName) {
            $subClass = $this->_em->getClassMetadata($subClassName);
            $tableAlias = $this->_getSQLTableAlias($subClass);

            if ($this->_selectColumnListSql === null) {
                // Add subclass columns
                foreach ($subClass->fieldMappings as $fieldName => $mapping) {
                    if (isset($mapping['inherited'])) {
                        continue;
                    }
                    $columnList .= ', ' . $this->_getSelectColumnSQL($fieldName, $subClass);
                }

                // Add join columns (foreign keys)
                foreach ($subClass->associationMappings as $assoc2) {
                    if ($assoc2->isOwningSide && $assoc2->isOneToOne() && ! isset($subClass->inheritedAssociationFields[$assoc2->sourceFieldName])) {
                        foreach ($assoc2->targetToSourceKeyColumns as $srcColumn) {
                            $columnAlias = $srcColumn . $this->_sqlAliasCounter<ins></ins>;
                            $columnList .= ', ' . $tableAlias . ".$srcColumn AS $columnAlias";
                            $resultColumnName = $this->_platform->getSQLResultCasing($columnAlias);
                            if ( ! isset($this->_resultColumnNames[$resultColumnName])) {
                                $this->_resultColumnNames[$resultColumnName] = $srcColumn;
                            }
                        }
                    }
                }
            }

            // Add LEFT JOIN
            $joinSql .= ' 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;
            }
        }

        $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 .= $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 .= ' = ?';
        }

        $orderBySql = '';
        if ($orderBy !== null) {
            $orderBySql = $this->_getCollectionOrderBySQL($orderBy, $baseTableAlias);
        }

        if ($this->_selectColumnListSql === null) {
            $this->_selectColumnListSql = $columnList;
        }

        return 'SELECT ' . $this->_selectColumnListSql
                . ' FROM ' . $this->*class->getQuotedTableName($this->*platform) . ' ' . $baseTableAlias
                . $joinSql
                . ($conditionSql != '' ? ' WHERE ' . $conditionSql : '') . $orderBySql;
    }

And output sql:

SELECT
    p1.id AS id2, 
    p1.product AS product3, 
    p1.vendor AS vendor4, 
    p1.version AS version5, 
    p1.businfo AS businfo6, 
    p1.capabilities AS capabilities7, 
    p1.num AS num8, 
    p1.comment AS comment9, 
    p1.physid AS physid10, 
    p1.driver AS driver11, 
    p1.driver*version AS driver*version12, 
    p1.description AS description13, 
    p1.xml*id AS xml*id14, 
    p1.class AS class15, 
    p1.handle AS handle16,
    p1.parent*handle AS parent*handle17, 
    i0.name AS name18, 
    i0.serial AS serial19, 
    i0.boot AS boot20, i0.chassis AS chassis21, 
    i0.smbios AS smbios22, 
    i0.dmi AS dmi23, 
    i0.bits AS bits24, 
    i0.uuid AS uuid25, 
    p1.host*id AS host*id26, 
    p1.discr 
FROM inventory*system i0 INNER JOIN private_inventory_basic p1 ON i0.id = p1.id WHERE p1.`host_id` = ? AND p1.xml*id = ?
@doctrinebot

Comment created by freeakk:

I also found a bug with double LEFT JOIN.

        /****
         * SELECT p0.id AS id1, 
         * p0.product AS product2, 
         * p0.vendor AS vendor3, 
         * p0.version AS version4, 
         * p0.businfo AS businfo5, 
         * p0.capabilities AS capabilities6, 
         * p0.num AS num7, 
         * p0.comment AS comment8, 
         * p0.physid AS physid9, 
         * p0.driver AS driver10, 
         * p0.driver*version AS driver*version11, 
         * p0.description AS description12, 
         * p0.xml*id AS xml*id13, 
         * p0.class AS class14, 
         * p0.handle AS handle15, 
         * p0.parent*handle AS parent*handle16, 
         * p0.host*id AS host*id17, 
         * p0.discr, 
         * i18.name AS name19, 
         * i18.serial AS serial20, 
         * i18.boot AS boot21, 
         * i18.chassis AS chassis22, 
         * i18.smbios AS smbios23, 
         * i18.dmi AS dmi24, 
         * i18.bits AS bits25, 
         * i18.uuid AS uuid26, 
         * i27.serial AS serial28, 
         * i27.slot AS slot29, 
         * i27.capacity AS capacity30, 
         * i27.voltage AS voltage31, 
         * i33.slot AS slot34, 
         * i33.size AS size35, 
         * i33.capacity AS capacity36, 
         * i38.slot AS slot39, 
         * i38.size AS size40, 
         * i38.capacity AS capacity41, 
         * i38.width AS width42, 
         * i38.clock AS clock43, 
         * i44.signature AS signature45, 
         * i44.serial AS serial46, 
         * i44.size AS size47, 
         * .......................
         * FROM private*inventory*basic p0 
          * LEFT JOIN inventory_system i18 ON p0.id = i18.id  // here
         * LEFT JOIN inventory_battery i27 ON p0.id = i27.id 
         * LEFT JOIN inventory_bus i32 ON p0.id = i32.id 
         * LEFT JOIN inventory_cache i33 ON p0.id = i33.id 
         * LEFT JOIN inventory_cdrom i37 ON p0.id = i37.id 
         * LEFT JOIN inventory_cpu i38 ON p0.id = i38.id 
         * LEFT JOIN inventory_disk i44 ON p0.id = i44.id 
         * LEFT JOIN inventory_display i48 ON p0.id = i48.id 
         * LEFT JOIN inventory_firmware i54 ON p0.id = i54.id 
         * LEFT JOIN inventory_memory i57 ON p0.id = i57.id 
         * LEFT JOIN inventory*memory*bank i60 ON p0.id = i60.id 
         * LEFT JOIN inventory*memory*controller i64 ON p0.id = i64.id 
         * LEFT JOIN inventory_multimedia i67 ON p0.id = i67.id 
         * LEFT JOIN inventory_network i73 ON p0.id = i73.id 
         * LEFT JOIN inventory*pci_host*bridge i89 ON p0.id = i89.id 
         * LEFT JOIN inventory_storage i92 ON p0.id = i92.id 
         * LEFT JOIN inventory_system i18 ON p0.id = i18.id   // and also here
         * LEFT JOIN inventory*usb*bus i104 ON p0.id = i104.id 
         * LEFT JOIN inventory*usb*generic i108 ON p0.id = i108.id 
         * LEFT JOIN inventory*usb*host i112 ON p0.id = i112.id 
         * LEFT JOIN inventory_volume i117 ON p0.id = i117.id 
         * WHERE p0.host_id = ?
         */

My patch:

    /****
     * Gets the SELECT SQL to select one or more entities by a set of field criteria.
     *
     * @param array $criteria
     * @param AssociationMapping $assoc
     * @param string $orderBy
     * @return string
     * @override
     */
    protected function _getSelectEntitiesSQL(array &$criteria, $assoc = null, $orderBy = null)
    {
        $idColumns = $this->_class->getIdentifierColumnNames();
        $baseTableAlias = $this->*getSQLTableAlias($this->*class);

        if ($this->_selectColumnListSql === null) {
            // Add regular columns
            $columnList = '';
            foreach ($this->_class->fieldMappings as $fieldName => $mapping) {
                if ($columnList != '') $columnList .= ', ';
                $columnList .= $this->_getSelectColumnSQL($fieldName,
                isset($mapping['inherited']) ? $this->*em->getClassMetadata($mapping['inherited']) : $this->*class);
            }

            // Add foreign key columns
            foreach ($this->_class->associationMappings as $assoc) {
                if ($assoc->isOwningSide && $assoc->isOneToOne()) {
                    $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<ins></ins>;
                        $columnList .= ", $tableAlias.$srcColumn AS $columnAlias";
                        $resultColumnName = $this->_platform->getSQLResultCasing($columnAlias);
                        if ( ! isset($this->_resultColumnNames[$resultColumnName])) {
                            $this->_resultColumnNames[$resultColumnName] = $srcColumn;
                        }
                    }
                }
            }

            // Add discriminator column (DO NOT ALIAS THIS COLUMN).
            $discrColumn = $this->_class->discriminatorColumn['name'];
            if ($this->*class->rootEntityName == $this->*class->name) {
                $columnList .= ", $baseTableAlias.$discrColumn";
            } else {
                $columnList .= ', ' . $this->*getSQLTableAlias($this->_em->getClassMetadata($this->*class->rootEntityName))
                        . ".$discrColumn";
            }

            $resultColumnName = $this->_platform->getSQLResultCasing($discrColumn);
            $this->_resultColumnNames[$resultColumnName] = $discrColumn;
        }

        // INNER JOIN parent tables
        $joinSql = '';
        $arrJoinSql = array();
        $parentClassesMetaData = array();
        foreach ($this->_class->parentClasses as $parentClassName) {
            $parentClass = $this->_em->getClassMetadata($parentClassName);

            $tableAlias = $this->_getSQLTableAlias($parentClass);
            $arrJoinSql[$parentClassName] = ' INNER JOIN ' . $parentClass->getQuotedTableName($this->_platform) . ' ' . $tableAlias . ' ON ';
            $first = true;
            foreach ($idColumns as $idColumn) {
                if ($first) $first = false; else $arrJoinSql[$parentClassName] .= ' AND ';
                $arrJoinSql[$parentClassName] .= $baseTableAlias . '.' . $idColumn . ' = ' . $tableAlias . '.' . $idColumn;
            }
            $parentClassColumns[$tableAlias] = $parentClass;
        }

        // OUTER JOIN sub tables
        foreach ($this->_class->subClasses as $subClassName) {
            $subClass = $this->_em->getClassMetadata($subClassName);
            $tableAlias = $this->_getSQLTableAlias($subClass);

            if ($this->_selectColumnListSql === null) {
                // Add subclass columns
                foreach ($subClass->fieldMappings as $fieldName => $mapping) {
                    if (isset($mapping['inherited'])) {
                        continue;
                    }
                    $columnList .= ', ' . $this->_getSelectColumnSQL($fieldName, $subClass);
                }

                // Add join columns (foreign keys)
                foreach ($subClass->associationMappings as $assoc2) {
                    if ($assoc2->isOwningSide && $assoc2->isOneToOne() && ! isset($subClass->inheritedAssociationFields[$assoc2->sourceFieldName])) {
                        foreach ($assoc2->targetToSourceKeyColumns as $srcColumn) {
                            $columnAlias = $srcColumn . $this->_sqlAliasCounter<ins></ins>;
                            $columnList .= ', ' . $tableAlias . ".$srcColumn AS $columnAlias";
                            $resultColumnName = $this->_platform->getSQLResultCasing($columnAlias);
                            if ( ! isset($this->_resultColumnNames[$resultColumnName])) {
                                $this->_resultColumnNames[$resultColumnName] = $srcColumn;
                            }
                        }
                    }
                }
            }

            // Add LEFT JOIN
            $arrJoinSql[$subClassName] = ' LEFT JOIN ' . $subClass->getQuotedTableName($this->_platform) . ' ' . $tableAlias . ' ON ';
            $first = true;

            foreach ($idColumns as $idColumn) {
                if ($first) $first = false; else $arrJoinSql[$subClassName] .= ' AND ';
                $arrJoinSql[$subClassName] .= $baseTableAlias . '.' . $idColumn . ' = ' . $tableAlias . '.' . $idColumn;
            }
        }

        $joinSql = join('', array_unique($arrJoinSql));

        $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 (isset($parentClassColumns) && 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 .= $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 .= ' = ?';
        }

        $orderBySql = '';
        if ($orderBy !== null) {
            $orderBySql = $this->_getCollectionOrderBySQL($orderBy, $baseTableAlias);
        }

        if ($this->_selectColumnListSql === null) {
            $this->_selectColumnListSql = $columnList;
        }

        return 'SELECT ' . $this->_selectColumnListSql
                . ' FROM ' . $this->*class->getQuotedTableName($this->*platform) . ' ' . $baseTableAlias
                . $joinSql
                . ($conditionSql != '' ? ' WHERE ' . $conditionSql : '') . $orderBySql;
    }
@doctrinebot

Comment created by @beberlei:

Sorry but this is a useless patch, can you please attach it as a patch file to be applicable against the current trunk?

And for the other issue please open up a new issue with a detailed report. Also all your bug-reports up to now used your original, pretty large code blocks, its pretty hard to make a simple re-produce case out of this, could you please try to locate the problems with smaller examples? Its not that we have infinite time to implement and understand your code

@doctrinebot

Comment created by @guilhermeblanco:

Hi,

I generated a diff of you patch (show you should give us the code you updated) via a svn diff call.
Patch looks reasonable, but we cannot commit for 2 reasons:

  • It fixes one issue, but opens 70+ bugs
  • Does not have a sample test case attached (it should not be as complex as your app environment, but as simple as possible that you can still reproduce)

So, if possible, could you try to update your patch, run our unit tests and if they all get passed, attach the svn diff version?

Cheers,

@doctrinebot

Comment created by @guilhermeblanco:

Broken patch (example of how a patch should be provided), DO NOT COMMIT

@doctrinebot

Comment created by freeakk:

Ok. Thank you. I will rewrite this patch. I need some time for install the unit tests.

@doctrinebot

Comment created by freeakk:

Create new diff.
Before patch and after one
```PHPUnit 3.4.11 by Sebastian Bergmann.

......................................SSSSSSS.......SSSSSSSS 60 / 940
SSSSSS.........................S.S.......................... 120 / 940
............................................................ 180 / 940
............................................................ 240 / 940
............................................E..EEE.......... 300 / 940
...SSSSSSSSSSSSSS..........SSSSSSSSSSSSSSSSSSSSSSS.......... 360 / 940
............................................................ 420 / 940
............................................................ 480 / 940
............................................................ 540 / 940
............................................................ 600 / 940
............................................................ 660 / 940
............................................................ 720 / 940
............................................................ 780 / 940
............................................................ 840 / 940
............................................................ 900 / 940
SSSS....................................

Time: 02:18, Memory: 79.50Mb

There were 4 errors:

1) Doctrine\Tests\DBAL\DriverManagerTest::testValidPdoInstance
PDOException: could not find driver

/var/www/doctrine/trunk/tests/Doctrine/Tests/DBAL/DriverManagerTest.php:23

2) Doctrine\Tests\DBAL\DriverManagerTest::testCustomPlatform
PDOException: could not find driver

/var/www/doctrine/trunk/tests/Doctrine/Tests/DBAL/DriverManagerTest.php:49

3) Doctrine\Tests\DBAL\DriverManagerTest::testCustomWrapper
PDOException: could not find driver

/var/www/doctrine/trunk/tests/Doctrine/Tests/DBAL/DriverManagerTest.php:63

4) Doctrine\Tests\DBAL\DriverManagerTest::testInvalidWrapperClass
PDOException: could not find driver

/var/www/doctrine/trunk/tests/Doctrine/Tests/DBAL/DriverManagerTest.php:76

FAILURES!
Tests: 940, Assertions: 2476, Errors: 4, Skipped: 64.

@doctrinebot

Comment created by romanb:

This should now be fixed in trunk.

Please create a new issue for the "double left join" problem.

@doctrinebot

Issue was closed with resolution "Fixed"

@doctrinebot

Comment created by freeakk:

Thank you.
Double left join is my error: I left join inventorySystem twice: in 1 and in 17

  • "0" = "privateInventoryBasic",
  • "1" = "inventorySystem",
  • "2" = "inventoryBattery",
  • "3" = "inventoryBus",
  • "4" = "inventoryCache",
  • "5" = "inventoryCdrom",
  • "6" = "inventoryCpu",
  • "7" = "inventoryDisk",
  • "8" = "inventoryDisplay",
  • "9" = "inventoryFirmware",
  • "10" = "inventoryMemory",
  • "11" = "inventoryMemoryBank",
  • "12" = "inventoryMemoryController",
  • "13" = "inventoryMultimedia",
  • "14" = "inventoryNetwork",
  • "15" = "inventoryPciHostBridge",
  • "16" = "inventoryStorage",
  • "17" = "inventorySystem",
  • "18" = "inventoryUsbBus",
  • "19" = "inventoryUsbGeneric",
  • "20" = "inventoryUsbHost",
  • "21" = "inventoryVolume"
@doctrinebot

Comment created by romanb:

Please create a new jira issue for that problem. Thanks.

@doctrinebot doctrinebot added this to the 2.0-BETA1 milestone
@doctrinebot doctrinebot closed this
@doctrinebot doctrinebot added the Bug label
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.