Query: Fix performance regression starting the loop for all fields.
Fixes a performance regression starting the loop after calling `WP_Query( [ 'fields' => 'all' ] )`. This changes how `WP_Query::the_post()` determines whether there is a need to traverse the posts for cache warming. If IDs are queried, `WP_Query::$posts` is assumed to be an array of post IDs. If all fields are queried, `WP_Query::$posts` is assumed to be an array of fully populated post objects. Follow up to [59919], [59937]. Props joemcgill, peterwilsoncc, SirLouen. Fixes #56992. Built from https://develop.svn.wordpress.org/trunk@59993 git-svn-id: http://core.svn.wordpress.org/trunk@59335 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
@@ -2067,6 +2067,15 @@ class WP_Query {
|
||||
case 'id=>parent':
|
||||
$fields = "{$wpdb->posts}.ID, {$wpdb->posts}.post_parent";
|
||||
break;
|
||||
case '':
|
||||
/*
|
||||
* Set the default to 'all'.
|
||||
*
|
||||
* This is used in `WP_Query::the_post` to determine if the
|
||||
* entire post object has been queried.
|
||||
*/
|
||||
$q['fields'] = 'all';
|
||||
// Falls through.
|
||||
default:
|
||||
$fields = "{$wpdb->posts}.*";
|
||||
}
|
||||
@@ -3739,28 +3748,30 @@ class WP_Query {
|
||||
global $post;
|
||||
|
||||
if ( ! $this->in_the_loop ) {
|
||||
// Get post IDs to prime incomplete post objects.
|
||||
$post_ids = array_reduce(
|
||||
$this->posts,
|
||||
function ( $carry, $post ) {
|
||||
if ( is_numeric( $post ) && $post > 0 ) {
|
||||
// Query for post ID.
|
||||
$carry[] = $post;
|
||||
}
|
||||
if ( 'all' === $this->query_vars['fields'] ) {
|
||||
// Full post objects queried.
|
||||
$post_objects = $this->posts;
|
||||
} else {
|
||||
if ( 'ids' === $this->query_vars['fields'] ) {
|
||||
// Post IDs queried.
|
||||
$post_ids = $this->posts;
|
||||
} else {
|
||||
// Only partial objects queried, need to prime the cache for the loop.
|
||||
$post_ids = array_reduce(
|
||||
$this->posts,
|
||||
function ( $carry, $post ) {
|
||||
if ( isset( $post->ID ) ) {
|
||||
$carry[] = $post->ID;
|
||||
}
|
||||
|
||||
if ( is_object( $post ) && isset( $post->ID ) ) {
|
||||
// Query for object, either WP_Post or stdClass.
|
||||
$carry[] = $post->ID;
|
||||
}
|
||||
|
||||
return $carry;
|
||||
},
|
||||
array()
|
||||
);
|
||||
if ( $post_ids ) {
|
||||
return $carry;
|
||||
},
|
||||
array()
|
||||
);
|
||||
}
|
||||
_prime_post_caches( $post_ids, $this->query_vars['update_post_term_cache'], $this->query_vars['update_post_meta_cache'] );
|
||||
$post_objects = array_map( 'get_post', $post_ids );
|
||||
}
|
||||
$post_objects = array_map( 'get_post', $post_ids );
|
||||
update_post_author_caches( $post_objects );
|
||||
}
|
||||
|
||||
@@ -3781,12 +3792,19 @@ class WP_Query {
|
||||
$post = $this->next_post();
|
||||
|
||||
// Ensure a full post object is available.
|
||||
if ( $post instanceof stdClass ) {
|
||||
// stdClass indicates that a partial post object was queried.
|
||||
$post = get_post( $post->ID );
|
||||
} elseif ( is_numeric( $post ) ) {
|
||||
// Numeric indicates that only post IDs were queried.
|
||||
$post = get_post( $post );
|
||||
if ( 'all' !== $this->query_vars['fields'] ) {
|
||||
if ( 'ids' === $this->query_vars['fields'] ) {
|
||||
// Post IDs queried.
|
||||
$post = get_post( $post );
|
||||
} elseif ( isset( $post->ID ) ) {
|
||||
/*
|
||||
* Partial objecct queried.
|
||||
*
|
||||
* The post object was queried with a partial set of
|
||||
* fields, populate the entire object for the loop.
|
||||
*/
|
||||
$post = get_post( $post->ID );
|
||||
}
|
||||
}
|
||||
|
||||
// Set up the global post object for the loop.
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
*
|
||||
* @global string $wp_version
|
||||
*/
|
||||
$wp_version = '6.8-beta2-59992';
|
||||
$wp_version = '6.8-beta2-59993';
|
||||
|
||||
/**
|
||||
* Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.
|
||||
|
||||
Reference in New Issue
Block a user