ZF-6232: findManyToManyRowset() returns columns from the intersection table
Description
Hello,
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
Comments
Posted by Steve Yang (steve.yang) on 2009-08-03T08:56:51.000+0000
Hi,
I believe this is linked to http://framework.zend.com/issues/browse/ZF-3709
Inside Zend_Db_Table_Row_Abstract line 1053 onwards we have
$select->from(array('i' => $interName), Zend_Db_Select::SQL_WILDCARD, $interSchema) ->joinInner(array('m' => $matchName), $joinCond, Zend_Db_Select::SQL_WILDCARD, $matchSchema) ->setIntegrityCheck(false);I believe the from column declaration is causing the issue and should be
$select->from(array('i' => $interName), array(), $interSchema) ->joinInner(array('m' => $matchName), $joinCond, Zend_Db_Select::SQL_WILDCARD, $matchSchema) ->setIntegrityCheck(false);to hide all the columns of the intersection table. This would then matchup with the documentation in http://framework.zend.com/manual/en/…
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.id, 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 [m.id] 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
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: http://gist.github.com/554965
Posted by Ralph Schindler (ralph) on 2010-11-16T08:30:17.000+0000
Commentary and workaround on this issue has been blogged about here: http://ralphschindler.com/2010/11/…
-ralph