Details
-
Type:
Bug
-
Status:
Resolved
-
Priority:
Major
-
Resolution: Duplicate
-
Affects Version/s: 1.6.0RC1, 1.5.3
-
Fix Version/s: 1.8.2
-
Component/s: Zend_Db_Select
-
Labels:None
Description
There seems to be a problem with joins generated by Zend_Db_Select.
According to my little reserach query is contructed in _renderFrom it using all tables from $this->_parts[self::FROM], with first table being the table which we're selecting "from" and others are being joined. However this array is ordered diffrently (maybe a problem in _join() ?).
I fixed this by adding a code to _renderFrom which searches for "main" table (joinCondition is empty) and moves it in front of array (yes, I realize this solution is really hacky). Something like this:
@@ -897,6 +897,19 @@
$this->_parts[self::FROM] = $this->_getDummyTable();
}
+ // arrange array so first table is first in array. Note this changes state of class
+ // which is not good. We're also not fixing problem but consequence.
+ $first = reset($this->_parts[self::FROM]);
+ if($first["joinCondition"]) {
+ foreach($this->_parts[self::FROM] as $key => $part) {
+ if($part["joinCondition"]) continue;
+
+ unset($this->_parts[self::FROM][$key]);
+ $this->_parts[self::FROM] = array_merge(array($key=>$part), $this->_parts[self::FROM]);
+ break;
+ }
+ }
+
$from = array();
foreach ($this->_parts[self::FROM] as $correlationName => $table) {
this is code snippet demonstrating this behaviour (it's ripped from my project, so it's not really possible to run it by itself - you need so set up adapter and such).
class Model_Runs extends Zend_Db_Table protected $_name = "runs"; protected $_sequence = true; protected $_primary = array('id'); public function blah() { $select = $this->select(); $select->join('survey_runs', 'survey_runs.id_run = runs.id', array()); echo $select->__toString(); die(); } }
result:
SELECT "runs".* FROM "survey_runs" INNER JOIN "runs"
expected result:
SELECT "runs".* FROM "runs" INNER JOIN "survey_runs" ON survey_runs.id_run = runs.id
I ran into the same problem.
A workaround I found was to do
$select = $this->select(); $select->__toString(); $select->join('survey_runs', 'survey_runs.id_run = runs.id', array());My guess is that when calling __toString it seems that the table name is added to $this->_parts[self::FROM] which means that it is now first in the array and everything works.
$select = $this->select(); $select->__toString(); $select->join('survey_runs', 'survey_runs.id_run = runs.id', array());