Make WordPress Core

Changeset 54892


Ignore:
Timestamp:
11/29/2022 08:09:24 PM (17 months ago)
Author:
ocean90
Message:

Query: Account for primed post caches without primed post meta/term caches.

In [54352] update_post_caches() was replaced by _prime_post_caches() to reduce excessive object cache calls. That's because _prime_post_caches() checks first if post IDs aren't already cached. Unfortunately this becomes an issue if a post itself is cached but not the meta/terms.
To fix this regression, _prime_post_caches() now always calls update_postmeta_cache() and update_object_term_cache() depending on the arguments passed to it. Both functions internally check whether IDs are already cached so the fix from [54352] remains in place.

Props peterwilsoncc, spacedmonkey, ocean90.
Fixes #57163.

Location:
branches/6.1
Files:
1 added
2 edited

Legend:

Unmodified
Added
Removed
  • branches/6.1/src/wp-includes/post.php

    r54784 r54892  
    78237823    $post_type_taxonomies = array();
    78247824    $term_ids             = array();
     7825    $prime_post_terms     = array();
    78257826    foreach ( $posts as $post ) {
    78267827        if ( ! ( $post instanceof WP_Post ) ) {
     
    78327833        }
    78337834
     7835        foreach ( $post_type_taxonomies[ $post->post_type ] as $taxonomy ) {
     7836            $prime_post_terms[ $taxonomy ][] = $post->ID;
     7837        }
     7838    }
     7839
     7840    foreach ( $prime_post_terms as $taxonomy => $post_ids ){
     7841        wp_cache_get_multiple( $post_ids, "{$taxonomy}_relationships" );
     7842    }
     7843
     7844    foreach ( $posts as $post ) {
    78347845        foreach ( $post_type_taxonomies[ $post->post_type ] as $taxonomy ) {
    78357846            // Term cache should already be primed by `update_post_term_cache()`.
     
    78787889 * @since 6.1.0 This function is no longer marked as "private".
    78797890 *
    7880  * @see update_post_caches()
     7891 * @see update_post_cache()
     7892 * @see update_postmeta_cache()
     7893 * @see update_object_term_cache()
    78817894 *
    78827895 * @global wpdb $wpdb WordPress database abstraction object.
     
    78937906        $fresh_posts = $wpdb->get_results( sprintf( "SELECT $wpdb->posts.* FROM $wpdb->posts WHERE ID IN (%s)", implode( ',', $non_cached_ids ) ) );
    78947907
    7895         update_post_caches( $fresh_posts, 'any', $update_term_cache, $update_meta_cache );
     7908        if ( $fresh_posts ) {
     7909            // Despite the name, update_post_cache() expects an array rather than a single post.
     7910            update_post_cache( $fresh_posts );
     7911        }
     7912    }
     7913
     7914    if ( $update_meta_cache ) {
     7915        update_postmeta_cache( $ids );
     7916    }
     7917
     7918    if ( $update_term_cache ) {
     7919        $post_types = array_map( 'get_post_type', $ids );
     7920        $post_types = array_unique( $post_types );
     7921        update_object_term_cache( $ids, $post_types );
    78967922    }
    78977923}
  • branches/6.1/tests/phpunit/tests/query/cacheResults.php

    r54784 r54892  
    12381238        $query_1 = new WP_Query(
    12391239            array(
    1240                 'post_type' => 'page',
    1241                 'fields'    => $fields,
    1242                 'author'    => self::$author_id,
     1240                'post_type'              => 'page',
     1241                'fields'                 => $fields,
     1242                'author'                 => self::$author_id,
     1243                'update_post_meta_cache' => false,
     1244                'update_post_term_cache' => false,
    12431245            )
    12441246        );
     
    12481250        $query_1->the_post();
    12491251        $num_loop_queries = get_num_queries() - $start_loop_queries;
     1252        /*
     1253         * Two expected queries:
     1254         * 1: User meta data,
     1255         * 2: User data.
     1256         */
    12501257        $this->assertSame( 2, $num_loop_queries, 'Unexpected number of queries while initializing the loop.' );
    12511258
     
    12721279        );
    12731280    }
     1281
     1282    /**
     1283     * Ensure lazy loading term meta queries all term meta in a single query.
     1284     *
     1285     * @since 6.1.2
     1286     * @ticket 57163
     1287     * @ticket 22176
     1288     */
     1289    public function test_get_post_meta_lazy_loads_all_term_meta_data() {
     1290        $query = new WP_Query();
     1291
     1292        $t2 = $this->factory()->term->create(
     1293            array(
     1294                'taxonomy' => 'category',
     1295                'slug'     => 'bar',
     1296                'name'     => 'Bar',
     1297            )
     1298        );
     1299
     1300        wp_set_post_terms( self::$posts[0], $t2, 'category', true );
     1301        // Clean data added to cache by factory and setting terms.
     1302        clean_term_cache( array( self::$t1, $t2 ), 'category' );
     1303        clean_post_cache( self::$posts[0] );
     1304
     1305        $num_queries_start = get_num_queries();
     1306        $query_posts       = $query->query(
     1307            array(
     1308                'lazy_load_term_meta' => true,
     1309                'no_found_rows'       => true,
     1310            )
     1311        );
     1312        $num_queries       = get_num_queries() - $num_queries_start;
     1313
     1314        /*
     1315         * Four expected queries:
     1316         * 1: Post IDs
     1317         * 2: Post data
     1318         * 3: Post meta data.
     1319         * 4: Post term data.
     1320         */
     1321        $this->assertSame( 4, $num_queries, 'Unexpected number of queries while querying posts.' );
     1322        $this->assertNotEmpty( $query_posts, 'Query posts is empty.' );
     1323
     1324        $num_queries_start = get_num_queries();
     1325        get_term_meta( self::$t1 );
     1326        $num_queries = get_num_queries() - $num_queries_start;
     1327
     1328        /*
     1329         * One expected query:
     1330         * 1: Term meta data.
     1331         */
     1332        $this->assertSame( 1, $num_queries, 'Unexpected number of queries during first query of term meta.' );
     1333
     1334        $num_queries_start = get_num_queries();
     1335        get_term_meta( $t2 );
     1336        $num_queries = get_num_queries() - $num_queries_start;
     1337
     1338        // No additional queries expected.
     1339        $this->assertSame( 0, $num_queries, 'Unexpected number of queries during second query of term meta.' );
     1340    }
    12741341}
Note: See TracChangeset for help on using the changeset viewer.