Skip to content
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

Merged

Conversation

derrabus
Copy link
Member

@derrabus derrabus commented Aug 29, 2024

Q A
Type improvement
Fixed issues Follows #6504

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.

greg0ire
greg0ire previously approved these changes Aug 29, 2024
Copy link
Member

@greg0ire greg0ire left a 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 👍

morozov
morozov previously approved these changes Aug 30, 2024
Copy link
Member

@morozov morozov left a 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.

src/Cache/ArrayResult.php Outdated Show resolved Hide resolved
@derrabus derrabus dismissed stale reviews from morozov and greg0ire via 773774e August 30, 2024 08:13
@derrabus derrabus force-pushed the improvement/ignore-old-query-cache branch from 6fcf73d to 773774e Compare August 30, 2024 08:13
@derrabus derrabus merged commit c56a608 into doctrine:4.2.x Aug 30, 2024
78 of 79 checks passed
@derrabus derrabus deleted the improvement/ignore-old-query-cache branch August 30, 2024 08:34
derrabus added a commit that referenced this pull request Aug 30, 2024
* 4.2.x:
  Invalidate old query cache format (#6510)
  Handle cached result column names and rows separately (#6504)
@morozov
Copy link
Member

morozov commented Aug 30, 2024

Thanks @derrabus for handling this!

@derrabus derrabus added this to the 4.2.0 milestone Sep 3, 2024

return new Result(new ArrayResult($columnNames, $rows), $this);
if (isset($value[$realKey]) && $value[$realKey] instanceof ArrayResult) {
return new Result($value[$realKey], $this);
Copy link
Contributor

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 😱

Copy link
Member Author

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.

derrabus pushed a commit that referenced this pull request Oct 21, 2024
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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants