ZF-3347: findParentRow when column is NULL

Description

When for a table where a optional (can be NULL) reference findParentRow is called the column is NULL i get this sql error: SQLSTATE[HY093]: Invalid parameter number: no parameters were bound

Because this sql is executed: SELECT clubs.* FROM clubs WHERE (id = ?)

Possible solution:


Index: library/Zend/Db/Table/Row/Abstract.php
===================================================================
--- library/Zend/Db/Table/Row/Abstract.php      (revision 9566)
+++ library/Zend/Db/Table/Row/Abstract.php      (working copy)
@@ -879,6 +879,7 @@
         for ($i = 0; $i < count($map[Zend_Db_Table_Abstract::COLUMNS]); ++$i) {
             $dependentColumnName = $db->foldCase($map[Zend_Db_Table_Abstract::COLUMNS][$i]);
             $value = $this->_data[$dependentColumnName];
+            if (is_null($value)) return null;
             // Use adapter from parent table to ensure correct query construction
             $parentDb = $parentTable->getAdapter();
             $parentColumnName = $parentDb->foldCase($map[Zend_Db_Table_Abstract::REF_COLUMNS][$i]);

Comments

Please evaluate and fix/categorize as necessary.

I've worked on this, I have a patch as well as some clarification:

First, it is possible to have a compound/composite key that also has a NULLABLE value. For that reason, I dont think the patch as supplied would work, I would suggest this:


Index: library/Zend/Db/Table/Row/Abstract.php
===================================================================
--- library/Zend/Db/Table/Row/Abstract.php      (revision 15675)
+++ library/Zend/Db/Table/Row/Abstract.php      (working copy)
@@ -971,16 +971,28 @@
 
         $map = $this->_prepareReference($this->_getTable(), $parentTable, $ruleKey);
 
+        // iterate the map, creating the proper wheres
         for ($i = 0; $i < count($map[Zend_Db_Table_Abstract::COLUMNS]); ++$i) {
             $dependentColumnName = $db->foldCase($map[Zend_Db_Table_Abstract::COLUMNS][$i]);
             $value = $this->_data[$dependentColumnName];
+            
             // Use adapter from parent table to ensure correct query construction
             $parentDb = $parentTable->getAdapter();
             $parentColumnName = $parentDb->foldCase($map[Zend_Db_Table_Abstract::REF_COLUMNS][$i]);
             $parentColumn = $parentDb->quoteIdentifier($parentColumnName, true);
             $parentInfo = $parentTable->info();
-            $type = $parentInfo[Zend_Db_Table_Abstract::METADATA][$parentColumnName]['DATA_TYPE'];
-            $select->where("$parentColumn = ?", $value, $type);
+            
+            // determine where part
+            $type     = $parentInfo[Zend_Db_Table_Abstract::METADATA][$parentColumnName]['DATA_TYPE'];
+            $nullable = $parentInfo[Zend_Db_Table_Abstract::METADATA][$parentColumnName]['NULLABLE'];
+            if ($value === null && $nullable == true) {
+                $select->where("$parentColumn IS NULL");
+            } elseif ($value === null && $nullable == false) {
+                return null;
+            } else {
+                $select->where("$parentColumn = ?", $value, $type);
+            }
+            
         }
 
         return $parentTable->fetchRow($select);

I think this same logic might have to be applied to the DependentRowset as well? I need to find a way to test this behavior, but, i think I'll have a solution soon.

Fixed as part of r16733, if not, please reopen.

I think the same fixes should be applied to findDependentRowset and findManyToManyRowset