Opened 2 years ago
Closed 2 years ago
#57012 closed defect (bug) (fixed)
WP_Query caching discards `posts_fields` and `posts_clauses['fields']` filters.
Reported by: | peterwilsoncc | Owned by: | peterwilsoncc |
---|---|---|---|
Milestone: | 6.1.1 | Priority: | normal |
Severity: | normal | Version: | 6.1 |
Component: | Query | Keywords: | has-patch has-unit-tests commit fixed-major |
Focuses: | performance | Cc: |
Description
When generating the cache key, WP_Query
uses a consistent value for the fields requested in the SELECT
clause.
In most cases, this is problem free as WP_Query
uses the same cache regardless of the fields requested. When a plugin is filtering the fields returned, this can be problematic as the cache key could cause collisions in some circumstances.
When generating the cache key, WP_Query
should consider the fields value if it has been modified by a plugin. This may also affect what needs to be cached.
I'm still investigating this so will add further notes to the ticket. I'm putting this on the 6.1.1 milestone for visibility.
Attachments (1)
Change History (19)
This ticket was mentioned in PR #3574 on WordPress/wordpress-develop by @peterwilsoncc.
2 years ago
#2
- Keywords has-patch has-unit-tests added
https://core.trac.wordpress.org/ticket/57012
First commit is some tests that pass on 6.0 but not on 6.1
#3
@
2 years ago
Props due @pypwalters, @claytoncollie, @johnwatkins0 for helping diagnose this issue.
#4
@
2 years ago
In the linked pull request:
- Added some tests to ensure modified
SELECT
s return the same values on the first and subsequent requests - Bypass the main cache (ie, revert to 6.0 behavior) if the
SELECT
has been modified from an expected form
I considered caching modified SELECT
s but figured some additional care would need to be taken to account for SELECT
ing many values that could blow up the size of the cached value.
@TimothyBlynJacobs commented on PR #3574:
2 years ago
#5
This seemse like a sensible fix for a minor to me. 6.2 could explore generating a more comprehensive cache key.
@peterwilsoncc commented on PR #3574:
2 years ago
#6
Props due @costdev for reviewing names and tests via Slack DM.
#7
@
2 years ago
- Keywords commit added
Patch looks good to me. Adding commit, ahead of merge deadline in 6.1.1.
#9
@
2 years ago
- Owner set to peterwilsoncc
- Resolution set to fixed
- Status changed from new to closed
In 54768:
#10
@
2 years ago
- Keywords fixed-major added
- Resolution fixed deleted
- Status changed from closed to reopened
Reopening merge for to the 6.1 branch.
@peterwilsoncc commented on PR #3574:
2 years ago
#11
#15
@
2 years ago
- Resolution fixed deleted
- Status changed from closed to reopened
After [54768], seeing some test failures on MariaDB due to indeterminate sort order, see these test runs for example:
I can also reproduce these failures locally with MariaDB 10.6.8.
57012.diff aims to stabilize the tests by using assertEqualSets()
instead of assertEquals()
, since testing the order is out of their scope. Includes removing array_unshift()
and array_reverse()
calls as no longer needed.
#16
@
2 years ago
Thanks @SergeyBiryukov, the patch looks good based on a visual review.
As an educated guess, this is caused by hitting undefined behavior due to create_many
creating several posts with the same date/time fields.
WP_Query is generating the DB Query below and each engine refines the order further using a different index.
SELECT SQL_CALC_FOUND_ROWS wptests_posts.ID, wptests_posts.post_parent FROM wptests_posts WHERE 1=1 AND ((wptests_posts.post_type = 'wptests_pt' AND (wptests_posts.post_status = 'publish'))) ORDER BY wptests_posts.post_date DESC LIMIT 0, 10
I've created a mini-plugin to modify the fields requested by
WP_Query
:When initializing
WP_Query( 'fields' => $value )
the following happens in 6.0:$value = 'ids'
: Theposts
property is an array if integers. The 6.1 behaviour matches.$value = 'all' /* or '' */
: Theposts
property contains an array ofWP_Post
objects with the addition oftest_post_fields
andtest_post_clauses
. The 6.1 behaviour does not match.$vallue = 'id=>parent'
: Theposts
property contains an array ofstdClass
with the propertiesID
,post_parent
,test_post_fields
andtest_post_clauses
. The 6.1 behaviour does not match.I see two options:
WP_Query
handles by defaultEither way, tests will need to be added to ensure changing the fields includes the additional values in the event the
posts
property is an object.