ZF-5775: Zend_Db_Table->find() returns all rows when passed empty array
Description
Not sure if this is a bug or a feature; it certainly contradicts the documentation which states: "If you specify multiple values in an array, the method returns at most as many rows as the number of distinct values you specify. "
Suggested fix, if this is not desired behaviour (it's certainly counter-intuitive), is to create & return an empty rowset of the correct class if there are no items in the whereList:
<?php
public function find()
{
$this->_setupPrimaryKey();
$args = func_get_args();
$keyNames = array_values((array) $this->_primary);
if (count($args) < count($keyNames)) {
require_once 'Zend/Db/Table/Exception.php';
throw new Zend_Db_Table_Exception("Too few columns for the primary key");
}
if (count($args) > count($keyNames)) {
require_once 'Zend/Db/Table/Exception.php';
throw new Zend_Db_Table_Exception("Too many columns for the primary key");
}
$whereList = array();
$numberTerms = 0;
foreach ($args as $keyPosition => $keyValues) {
// Coerce the values to an array.
// Don't simply typecast to array, because the values
// might be Zend_Db_Expr objects.
if (!is_array($keyValues)) {
$keyValues = array($keyValues);
}
if ($numberTerms == 0) {
$numberTerms = count($keyValues);
} else if (count($keyValues) != $numberTerms) {
require_once 'Zend/Db/Table/Exception.php';
throw new Zend_Db_Table_Exception("Missing value(s) for the primary key");
}
for ($i = 0; $i < count($keyValues); ++$i) {
if (!isset($whereList[$i])) {
$whereList[$i] = array();
}
$whereList[$i][$keyPosition] = $keyValues[$i];
}
}
$whereClause = null;
if (count($whereList)) {
$whereOrTerms = array();
foreach ($whereList as $keyValueSets) {
$whereAndTerms = array();
foreach ($keyValueSets as $keyPosition => $keyValue) {
$type = $this->_metadata[$keyNames[$keyPosition]]['DATA_TYPE'];
$tableName = $this->_db->quoteTableAs($this->_name, null, true);
$columnName = $this->_db->quoteIdentifier($keyNames[$keyPosition], true);
$whereAndTerms[] = $this->_db->quoteInto(
$tableName . '.' . $columnName . ' = ?',
$keyValue, $type);
}
$whereOrTerms[] = '(' . implode(' AND ', $whereAndTerms) . ')';
}
$whereClause = '(' . implode(' OR ', $whereOrTerms) . ')';
return $this->fetchAll($whereClause);
}
else
{
$data = array(
'table' => $this,
'readOnly' => $select->isReadOnly(),
'rowClass' => $this->_rowClass,
'stored' => true
);
@Zend_Loader::loadClass($this->_rowsetClass);
return new $this->_rowsetClass($data);
}
}
Comments
Posted by Mark (lightflowmark) on 2009-07-27T10:21:51.000+0000
I'm happy to put together a patch & test for this issue, if I get some guidance as to whether it's a feature or a bug.
Let me know if there's another place I should be asking this kind of question.
Posted by Ralph Schindler (ralph) on 2009-08-25T16:12:21.000+0000
Fixed in trunk in r17817, merged to branch release 1.9 in 17818