ZF-6232: findManyToManyRowset() returns columns from the intersection table

Issue Type: Bug Created: 2009-04-07T08:58:50.000+0000 Last Updated: 2010-11-16T08:30:19.000+0000 Status: Resolved Fix version(s): - 1.10.2 (24/Feb/10)

Reporter: Ludek Stepan (ludek.stepan) Assignee: Ralph Schindler (ralph) Tags: - Zend_Db_Table

Related issues: - ZF-3709

Attachments: - zf6232.r21084.patch



I've found that the method findManyToManyRowset() from the Zend_Db_Table_Row_Abstract returns all columns both from the matching and intersection tables in the resulting rowset. Is that safe? I mean what happens if the matching and intersection table have a same column name with different values? Would the results be valid? However the $select sets integrityCheck off and consequently the result rowset's readOnly flag off too.

I believe that the result rowset should not contain any values from the intersection table or optionaly some column collision checking should be done. At least, if the resulting rowset contains any values from the intersection table, it should be marked readOnly for sake.

Best regards, Ludek Stepan


Posted by Steve Yang (steve.yang) on 2009-08-03T08:56:51.000+0000


I believe this is linked to

Inside Zend_Db_Table_Row_Abstract line 1053 onwards we have

<pre class="literal">
 $select->from(array('i' => $interName), Zend_Db_Select::SQL_WILDCARD, $interSchema)
               ->joinInner(array('m' => $matchName), $joinCond, Zend_Db_Select::SQL_WILDCARD, $matchSchema)

I believe the from column declaration is causing the issue and should be

<pre class="literal">
 $select->from(array('i' => $interName), array(), $interSchema)
               ->joinInner(array('m' => $matchName), $joinCond, Zend_Db_Select::SQL_WILDCARD, $matchSchema)

to hide all the columns of the intersection table. This would then matchup with the documentation in…

Posted by Michael Rehbein (tech13) on 2010-01-14T10:37:16.000+0000

Comment converted to patch file.

Posted by Michael Rehbein (tech13) on 2010-02-18T11:53:19.000+0000

Attached patch with fix and adjustment to a unit test to verify

Posted by Ralph Schindler (ralph) on 2010-02-19T13:15:08.000+0000

Fixed in trunk 21100 and in release branch 1.10 in 21102

Posted by Christoph Roensch (croensch) on 2010-03-10T00:56:37.000+0000

First, i believe this is a behaviour not suited to be changed in a minor version.

I have to agree that overlapping column names could invalidate the result set.

However i disagree with issue 3709 that any subsequent save() will fail with an exception as it would only fail if you explicitly set() a column of the intersection table, wich does not make any sense.

We would like to adapt these changes as they make our domain model code somewhat less complicated, but we are running into issues.

Previously we used to display a ManyToMany-Rowset using all columns [i.id_r, i.id_m,, m.value]. Then manipulate it and then synchronize it to a Dependent-Rowset using only the columns that represent the intersection [i.id_r, i.id_m]. This is still possible by translating/fixing the column names from [] to [i.id_r (given), i.id_m].

However we are facing an issue when we actually need a value from the intersection table, in other words when the relation contains some data. I have tried to give a Zend_Db_Table_Select statement to findManyToManyRowset(). bq. $this->select()->columns(array('i' => 'value')); This fails because the intersection Table has not been defined. bq. Zend_Db_Select(255): No table has been specified for the FROM clause

+Do we really have to findDependents and then findParents on this rowset to get the information we could retrieve just fine before?+

Another quick but possibly dirty solution would be to revert the behaviour of this fix by overloading findManyToManyRowset with

<pre class="highlight">
if( $select === null )
  if( is_string($intersectionTable) )
    $intersectionTable = $this->_getTableFromString($intersectionTable);
  $select = $intersectionTable->select(true);

before calling the parent method.

Anyway i'd like this bug to be reopened because of the issue: +It is not easily possible to include intersection values that are actually needed.+

Posted by martin hughes (martinph) on 2010-04-29T06:48:29.000+0000

I'm going to agree with Christoph here. This one came as a bit of a surprise in a minor release.

Posted by William McDonald Buck (deebuck) on 2010-08-27T11:05:27.000+0000

For what it is worth I just spent 4 hours trying to track down a problem which turns out to be due to this change. Working code dependent on the documented behaviour that the result set contains data from the intersection table. Docs say "This method returns a Zend_Db_Table_Rowset_Abstract containing rows from the table $table, satisfying the many-to-many relationship. The current Row object $row from the origin table is used to find rows in the intersection table, and that is joined to the destination table. " Not nice to break working code in a minor release.

Posted by Christoph Roensch (croensch) on 2010-08-28T03:06:38.000+0000

I've extraced my solution to a Workaround:

Posted by Ralph Schindler (ralph) on 2010-11-16T08:30:17.000+0000

Commentary and workaround on this issue has been blogged about here:…


Have you found an issue?

See the Overview section for more details.


© 2006-2022 by Zend by Perforce. Made with by awesome contributors.

This website is built using zend-expressive and it runs on PHP 7.