-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Invalidate old query cache format #6510
Invalidate old query cache format #6510
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like it also reduces the cache size 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good 👍 Just one nit.
6fcf73d
to
773774e
Compare
Thanks @derrabus for handling this! |
|
||
return new Result(new ArrayResult($columnNames, $rows), $this); | ||
if (isset($value[$realKey]) && $value[$realKey] instanceof ArrayResult) { | ||
return new Result($value[$realKey], $this); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The changes made here in Connection
introduced a
BC Break
Before this PR, the values in the cache were uncoupled from the ArrayResult
.
Since this PR, the cache and the Result
/ArrayResult
are now coupled: hitting the \Doctrine\DBAL\Result::free
method erases all the cache content as well 😱
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please file a bug report with clear steps to reproduce.
Bug emerged in #6510 (comment) The current implementation of query cache relies on the cache **not** saved by-reference; the bug has never been seen before because by default `new ArrayAdapter()` saves the cache with serialization, hence breaking the by-reference pointer. Once the _by-reference_ tecnique is used, two issues pop up: 1. `\Doctrine\DBAL\Cache\ArrayResult::$num` is never reset, so once it gets incremented in the first `\Doctrine\DBAL\Cache\ArrayResult::fetch` call, the following calls will always fail 2. Even considering fixing the `$num` property reset, a manual call on `\Doctrine\DBAL\Result::free` will by cascade call the `\Doctrine\DBAL\Cache\ArrayResult::free` method erasing all the saved results I think that the `ArrayResult` implementation is not the culprit, but rather the #6510 giving to the cache backend the internal object by reference instead of giving it a copy.
Summary
I'm changing the query cache format once again: Instead of storing a tuple of arrays, I'm now storing the whole
ArrayResult
object. This way, we can easily detect if we support the data returned from the cache and we can handle future cache format changes in the__unserialize()
methods.After #6504, we would run into errors if an app would attempt to us a cache written with DBAL 4.1. With my change, the old cache is ignored and the app would behave as if it had encountered a cache miss instead.
I've also added tests covering the serialization of
ArrayResult
objects.