Query cache and AR

Try this:


User::model()->cache(1000)->findByPk($nonExistantPk)

Assuming that there is no User with that PK, the result will be NULL. Next time you perform the same search, you would expect the result to be fetched from cache, but it does NOT. Yii attempts to get it from cache, but ends up performing the same query again. In my opinion, this is not the desired behavior.

The problem is this line (CDbCommand::queryInternal()) :




if(($result=$cache->get($cacheKey))!==false)

{

	Yii::trace('Query result found in cache','system.db.CDbCommand');

	return $result;

}



The real issue here is that CCache does not differentiate between a missing value and an existing value that evaluates to FALSE. This makes it impossible to store FALSE to cache, which causes query caching to fail under some circumstances.

The solution (I think) is to:

  1. Add a method to CCache for checking if a key exists in cache (note that offsetExists() will also fail here)

  2. Modify CDbCommand::queryInternal() so that it first checks if cache contains the key, and then returns it even if it is false.

Ended up doing this myself. Created a pull request: https://github.com/yiisoft/yii/pull/1403/files