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

Make Paginator-internal query cacheable in the query cache #10444

Merged
merged 2 commits into from
Feb 8, 2023

Commits on Feb 5, 2023

  1. Make Paginator-internal query cacheable in the query cache

    Make the `Paginator`-internal query (`... WHERE ... IN (id, id2,
    id3...)`) cacheable in the query cache again.
    
    When the Paginator creates the internal subquery that does the actual
    result limiting, it has to take DBAL type conversions for the identifier
    column of the paginated root entity into account (doctrine#7820, fixed in
     doctrine#7821).
    
    In order to perform this type conversion, we need to know the DBAL type
    class for the root entity's `#[Id]`, and we have to figure it out based
    on a given (arbitrary) DQL query. This requires DQL parsing and
    inspecting the AST, so doctrine#7821 placed the conversion code in the
    `WhereInWalker` where all the necessary information is available.
    
    The problem is that type conversion has to happen every time the
    paginator is run, but the query that results from running
    `WhereInWalker` would be kept in the query cache. This was reported in
     doctrine#7837 and fixed by doctrine#7865, by making this particular query expire every
    time. The query must not be cached, since the necessary ID type
    conversion happens as a side-effect of running the `WhereInWalker`.
    
    The Paginator internal query that uses `WhereInWalker` has its DQL
    re-parsed and transformed in every request.
    
    This PR moves the code that determines the DBAL type out of
    `WhereInWalker` into a dedicated SQL walker class, `RootTypeWalker`.
    
    `RootTypeWalker` uses a ~hack~  clever trick to report the type back: It
    sets the type as the resulting "SQL" string. The benefit is that
    `RootTypeWalker` results can be cached in the query cache themselves.
    Only the first time a given DQL query has to be paginated, we need to
    run this walker to find out the root entity's ID type. After that, the
    type will be returned from the query cache.
    
    With the type information being provided, `Paginator` can take care of
    the necessary conversions by itself. This happens every time the
    Paginator is used.
    
    The internal query that uses `WhereInWalker` can be cached again since
    it no longer has side effects.
    mpdude authored and greg0ire committed Feb 5, 2023
    Configuration menu
    Copy the full SHA
    77df5db View commit details
    Browse the repository at this point in the history
  2. Configuration menu
    Copy the full SHA
    cc5775c View commit details
    Browse the repository at this point in the history