#1427: Query cache has collisions between queries of different types
-----------------------------------+----------------------------------------
Reporter: chorizo | Owner: jwage
Type: defect | Status: new
Priority: critical | Milestone:
Component: Attributes | Version: 1.0
Keywords: | Has_test: 1
Mystatus: Pending Core Response | Has_patch: 1
-----------------------------------+----------------------------------------
The second of these two queries always breaks because
Doctrine_Query::getDql() returns the same string for both of them, which
gets hashed as the key to the query:
{{{
// DELETE query
Doctrine_Query::create()
->delete()
->from('SpaceMemberRequest')
->where('user_id = ? AND namespace_id = ?', array($user->id, $this->id))
->execute();
}}}
{{{
// SELECT query
Doctrine::getTable('SpaceMemberRequest')->createQuery()
->where('user_id = ? AND namespace_id = ?', array($userId, $spaceId))
->fetchOne();
}}}
I believe this might be an issue for the result cache as well, since it
uses getDql along with the parameters as the Hash.
Here's a test:
{{{
public function testQueryCacheCollisionOnType()
{
$cache = new Doctrine_Cache_Array();
// DELETE
$q = Doctrine_Query::create()
->delete()
->from('User')
->where('name = ?', array('walhala'))
->useQueryCache($cache);
$coll = $q->execute();
$this->assertEqual($cache->count(), 1);
// SELECT
$q = Doctrine_Query::create()
->from('User')
->where('name = ?', array('walhala'))
->useQueryCache($cache);
$coll = $q->execute();
$this->assertEqual($cache->count(), 2);
// DELETE again
$q = Doctrine_Query::create()
->delete()
->from('User')
->where('name = ?', array('walhala'))
->useQueryCache($cache);
$coll = $q->execute();
$this->assertEqual($cache->count(), 2);
// UPDATE
$q = Doctrine_Query::create()
->update('User')
->from('User')
->set('name', '?', array('walhala2'))
->where('name = ?', array('walhala'))
->useQueryCache($cache);
$coll = $q->execute();
$this->assertEqual($cache->count(), 3);
}
}}}
Here's my patch for Doctrine_Query_Abstract::getDql, which changes it to
return valid DQL, and fixes the cache collision above:
{{{
public function getDql()
{
$q = '';
if ($this->_type == Doctrine_Query::SELECT) {
$q .= ( ! empty($this->_dqlParts['select']))? 'SELECT ' .
implode(', ', $this->_dqlParts['select']) : '';
$q .= ( ! empty($this->_dqlParts['from']))? ' FROM ' .
implode(' ', $this->_dqlParts['from']) : '';
} else if ($this->_type == Doctrine_Query::DELETE) {
$q .= 'DELETE';
$q .= ( ! empty($this->_dqlParts['from']))? ' FROM ' .
implode(' ', $this->_dqlParts['from']) : '';
} else if ($this->_type == Doctrine_Query::UPDATE) {
$q .= 'UPDATE ';
$q .= ( ! empty($this->_dqlParts['from']))? implode(' ',
$this->_dqlParts['from']) : '';
$q .= ( ! empty($this->_dqlParts['set']))? ' SET ' . implode('
', $this->_dqlParts['set']) : '';
}
$q .= ( ! empty($this->_dqlParts['where']))? ' WHERE ' .
implode(' ', $this->_dqlParts['where']) : '';
$q .= ( ! empty($this->_dqlParts['groupby']))? ' GROUP BY ' .
implode(', ', $this->_dqlParts['groupby']) : '';
$q .= ( ! empty($this->_dqlParts['having']))? ' HAVING ' .
implode(' AND ', $this->_dqlParts['having']) : '';
$q .= ( ! empty($this->_dqlParts['orderby']))? ' ORDER BY ' .
implode(', ', $this->_dqlParts['orderby']) : '';
$q .= ( ! empty($this->_dqlParts['limit']))? ' LIMIT ' .
implode(' ', $this->_dqlParts['limit']) : '';
$q .= ( ! empty($this->_dqlParts['offset']))? ' OFFSET ' .
implode(' ', $this->_dqlParts['offset']) : '';
return $q;
}
}}}
--
Ticket URL: <http://trac.doctrine-project.org/ticket/1427>
Doctrine <http://www.phpdoctrine.org>
PHP Doctrine Object Relational Mapper
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"doctrine-svn" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at
http://groups.google.co.uk/group/doctrine-svn?hl=en-GB
-~----------~----~----~----~------~----~------~--~---