Query: Cache post ID database query within WP_Query.

Add object caching to the first database query in `WP_Query`, ie the database query for post IDs that match the desired result. Randomly ordered queries remain uncached as they are not intended to return consistent results.

Caching of ID queries is enabled by default, per the post object, term and meta caches.

Props spacedmonkey, aaroncampbell, batmoo, chriscct7, costdev, dd32, drewapicture, johnbillion, mukesh27, nacin, ocean90, peterwilsoncc, ryan, scribu, sergeybiryukov, tillkruss.
Fixes #22176.


git-svn-id: https://develop.svn.wordpress.org/trunk@53941 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
Peter Wilson
2022-08-25 04:21:40 +00:00
parent 193406ab64
commit 7f7d616d82
3 changed files with 1017 additions and 17 deletions
+119 -17
View File
@@ -1874,11 +1874,7 @@ class WP_Query {
}
if ( ! isset( $q['cache_results'] ) ) {
if ( wp_using_ext_object_cache() ) {
$q['cache_results'] = false;
} else {
$q['cache_results'] = true;
}
$q['cache_results'] = true;
}
if ( ! isset( $q['update_post_term_cache'] ) ) {
@@ -3072,6 +3068,77 @@ class WP_Query {
*/
$this->posts = apply_filters_ref_array( 'posts_pre_query', array( null, &$this ) );
/*
* Ensure the ID database query is able to be cached.
*
* Random queries are expected to have unpredictable results and
* cannot be cached. Note the space before `RAND` in the string
* search, that to ensure against a collision with another
* function.
*/
$id_query_is_cacheable = ! str_contains( strtoupper( $orderby ), ' RAND(' );
if ( $q['cache_results'] && $id_query_is_cacheable ) {
$cache_args = $q;
unset(
$cache_args['suppress_filters'],
$cache_args['cache_results'],
$cache_args['fields'],
$cache_args['update_post_meta_cache'],
$cache_args['update_post_term_cache'],
$cache_args['lazy_load_term_meta'],
$cache_args['update_menu_item_cache']
);
$new_request = str_replace( $fields, "{$wpdb->posts}.*", $this->request );
$key = md5( serialize( $cache_args ) . $new_request );
$last_changed = wp_cache_get_last_changed( 'posts' );
if ( ! empty( $this->tax_query->queried_terms ) ) {
$last_changed .= wp_cache_get_last_changed( 'terms' );
}
$cache_key = "wp_query:$key:$last_changed";
if ( null === $this->posts ) {
$cached_results = wp_cache_get( $cache_key, 'posts' );
if ( $cached_results ) {
if ( 'ids' === $q['fields'] ) {
/** @var int[] */
$this->posts = array_map( 'intval', $cached_results['posts'] );
} else {
_prime_post_caches( $cached_results['posts'], $q['update_post_term_cache'], $q['update_post_meta_cache'] );
/** @var WP_Post[] */
$this->posts = array_map( 'get_post', $cached_results['posts'] );
}
$this->post_count = count( $this->posts );
$this->found_posts = $cached_results['found_posts'];
$this->max_num_pages = $cached_results['max_num_pages'];
if ( 'ids' === $q['fields'] ) {
return $this->posts;
} elseif ( 'id=>parent' === $q['fields'] ) {
/** @var int[] */
$post_parents = array();
foreach ( $this->posts as $key => $post ) {
$obj = new stdClass();
$obj->ID = (int) $post->ID;
$obj->post_parent = (int) $post->post_parent;
$this->posts[ $key ] = $obj;
$post_parents[ $obj->ID ] = $obj->post_parent;
}
return $post_parents;
}
}
}
}
if ( 'ids' === $q['fields'] ) {
if ( null === $this->posts ) {
$this->posts = $wpdb->get_col( $this->request );
@@ -3082,6 +3149,16 @@ class WP_Query {
$this->post_count = count( $this->posts );
$this->set_found_posts( $q, $limits );
if ( $q['cache_results'] && $id_query_is_cacheable ) {
$cache_value = array(
'posts' => $this->posts,
'found_posts' => $this->found_posts,
'max_num_pages' => $this->max_num_pages,
);
wp_cache_set( $cache_key, $cache_value, 'posts' );
}
return $this->posts;
}
@@ -3094,15 +3171,28 @@ class WP_Query {
$this->set_found_posts( $q, $limits );
/** @var int[] */
$r = array();
$post_parents = array();
$post_ids = array();
foreach ( $this->posts as $key => $post ) {
$this->posts[ $key ]->ID = (int) $post->ID;
$this->posts[ $key ]->post_parent = (int) $post->post_parent;
$r[ (int) $post->ID ] = (int) $post->post_parent;
$post_parents[ (int) $post->ID ] = (int) $post->post_parent;
$post_ids[] = (int) $post->ID;
}
return $r;
if ( $q['cache_results'] && $id_query_is_cacheable ) {
$cache_value = array(
'posts' => $post_ids,
'found_posts' => $this->found_posts,
'max_num_pages' => $this->max_num_pages,
);
wp_cache_set( $cache_key, $cache_value, 'posts' );
}
return $post_parents;
}
if ( null === $this->posts ) {
@@ -3144,12 +3234,12 @@ class WP_Query {
*/
$this->request = apply_filters( 'posts_request_ids', $this->request, $this );
$ids = $wpdb->get_col( $this->request );
$post_ids = $wpdb->get_col( $this->request );
if ( $ids ) {
$this->posts = $ids;
if ( $post_ids ) {
$this->posts = $post_ids;
$this->set_found_posts( $q, $limits );
_prime_post_caches( $ids, $q['update_post_term_cache'], $q['update_post_meta_cache'] );
_prime_post_caches( $post_ids, $q['update_post_term_cache'], $q['update_post_meta_cache'] );
} else {
$this->posts = array();
}
@@ -3165,6 +3255,18 @@ class WP_Query {
$this->posts = array_map( 'get_post', $this->posts );
}
if ( $q['cache_results'] && $id_query_is_cacheable ) {
$post_ids = wp_list_pluck( $this->posts, 'ID' );
$cache_value = array(
'posts' => $post_ids,
'found_posts' => $this->found_posts,
'max_num_pages' => $this->max_num_pages,
);
wp_cache_set( $cache_key, $cache_value, 'posts' );
}
if ( ! empty( $this->posts ) && $q['update_menu_item_cache'] ) {
update_menu_item_cache( $this->posts );
}
@@ -3201,14 +3303,14 @@ class WP_Query {
$comments_request = "SELECT {$wpdb->comments}.comment_ID FROM {$wpdb->comments} $cjoin $cwhere $cgroupby $corderby $climits";
$key = md5( $comments_request );
$last_changed = wp_cache_get_last_changed( 'comment' );
$comment_key = md5( $comments_request );
$comment_last_changed = wp_cache_get_last_changed( 'comment' );
$cache_key = "comment_feed:$key:$last_changed";
$comment_ids = wp_cache_get( $cache_key, 'comment' );
$comment_cache_key = "comment_feed:$comment_key:$comment_last_changed";
$comment_ids = wp_cache_get( $comment_cache_key, 'comment' );
if ( false === $comment_ids ) {
$comment_ids = $wpdb->get_col( $comments_request );
wp_cache_add( $cache_key, $comment_ids, 'comment' );
wp_cache_add( $comment_cache_key, $comment_ids, 'comment' );
}
_prime_comment_caches( $comment_ids, false );
+896
View File
@@ -0,0 +1,896 @@
<?php
/**
* @group query
*/
class Test_Query_CacheResults extends WP_UnitTestCase {
/**
* Page IDs.
*
* @var int[]
*/
public static $pages;
/**
* Post IDs.
*
* @var int[]
*/
public static $posts;
/**
* Term ID.
*
* @var int
*/
public static $t1;
/**
* Author's user ID.
*
* @var int
*/
public static $author_id;
public static function wpSetUpBeforeClass( WP_UnitTest_Factory $factory ) {
// Make some post objects.
self::$posts = $factory->post->create_many( 5 );
self::$pages = $factory->post->create_many( 5, array( 'post_type' => 'page' ) );
self::$t1 = $factory->term->create(
array(
'taxonomy' => 'category',
'slug' => 'foo',
'name' => 'Foo',
)
);
wp_set_post_terms( self::$posts[0], self::$t1, 'category' );
add_post_meta( self::$posts[0], 'color', '#000000' );
// Make a user.
self::$author_id = $factory->user->create(
array(
'role' => 'author',
)
);
}
/**
* @dataProvider data_query_cache
* @ticket 22176
*/
public function test_query_cache( $args ) {
$query1 = new WP_Query();
$posts1 = $query1->query( $args );
$queries_before = get_num_queries();
$query2 = new WP_Query();
$posts2 = $query2->query( $args );
$queries_after = get_num_queries();
add_filter( 'split_the_query', '__return_false' );
$split_query = new WP_Query();
$split_posts = $split_query->query( $args );
remove_filter( 'split_the_query', '__return_false' );
if ( isset( $args['fields'] ) ) {
if ( 'all' !== $args['fields'] ) {
$this->assertSameSets( $posts1, $posts2, 'Second query produces different set of posts to first.' );
$this->assertSameSets( $posts1, $split_posts, 'Split query produces different set of posts to first.' );
}
if ( 'id=>parent' !== $args['fields'] ) {
$this->assertSame( $queries_after, $queries_before, 'Second query produces unexpected DB queries.' );
}
} else {
$this->assertSame( $queries_after, $queries_before, 'Second query produces unexpected DB queries.' );
}
$this->assertSame( $query1->found_posts, $query2->found_posts, 'Second query has a different number of found posts to first.' );
$this->assertSame( $query1->found_posts, $split_query->found_posts, 'Split query has a different number of found posts to first.' );
$this->assertSame( $query1->max_num_pages, $query2->max_num_pages, 'Second query has a different number of total to first.' );
$this->assertSame( $query1->max_num_pages, $split_query->max_num_pages, 'Split query has a different number of total to first.' );
if ( ! $query1->query_vars['no_found_rows'] ) {
wp_delete_post( self::$posts[0], true );
wp_delete_post( self::$pages[0], true );
$query3 = new WP_Query();
$query3->query( $args );
$this->assertNotSame( $query1->found_posts, $query3->found_posts );
$this->assertNotSame( $queries_after, get_num_queries() );
}
}
/**
* Data provider.
*
* @return array[] Test parameters.
*/
public function data_query_cache() {
return array(
'cache true' => array(
'args' => array(
'cache_results' => true,
),
),
'cache true and pagination' => array(
'args' => array(
'cache_results' => true,
'posts_per_page' => 3,
'page' => 2,
),
),
'cache true and no pagination' => array(
'args' => array(
'cache_results' => true,
'nopaging' => true,
),
),
'cache true and post type any' => array(
'args' => array(
'cache_results' => true,
'nopaging' => true,
'post_type' => 'any',
),
),
'cache true and get all' => array(
'args' => array(
'cache_results' => true,
'fields' => 'all',
'posts_per_page' => -1,
'post_status' => 'any',
'post_type' => 'any',
),
),
'cache true and page' => array(
'args' => array(
'cache_results' => true,
'post_type' => 'page',
),
),
'cache true and ids' => array(
'args' => array(
'cache_results' => true,
'fields' => 'ids',
),
),
'cache true and id=>parent and no found rows' => array(
'args' => array(
'cache_results' => true,
'fields' => 'id=>parent',
),
),
'cache true and ids and no found rows' => array(
'args' => array(
'no_found_rows' => true,
'cache_results' => true,
'fields' => 'ids',
),
),
'cache true and id=>parent' => array(
'args' => array(
'no_found_rows' => true,
'cache_results' => true,
'fields' => 'id=>parent',
),
),
'cache and ignore_sticky_posts' => array(
'args' => array(
'cache_results' => true,
'ignore_sticky_posts' => true,
),
),
'cache meta query' => array(
'args' => array(
'cache_results' => true,
'meta_query' => array(
array(
'key' => 'color',
),
),
),
),
'cache comment_count' => array(
'args' => array(
'cache_results' => true,
'comment_count' => 0,
),
),
'cache term query' => array(
'args' => array(
'cache_results' => true,
'tax_query' => array(
array(
'taxonomy' => 'category',
'terms' => array( 'foo' ),
'field' => 'slug',
),
),
),
),
);
}
/**
* @ticket 22176
*/
public function test_seeded_random_queries_only_cache_post_objects() {
$args = array(
'cache_results' => true,
'fields' => 'ids',
'orderby' => 'rand(6)',
);
$query1 = new WP_Query();
$query1->query( $args );
$queries_before = get_num_queries();
$query2 = new WP_Query();
$query2->query( $args );
$queries_after = get_num_queries();
$this->assertNotSame( $queries_before, $queries_after );
}
/**
* @ticket 22176
*/
public function test_unseeded_random_queries_only_cache_post_objects() {
$args = array(
'cache_results' => true,
'fields' => 'ids',
'orderby' => 'rand',
);
$query1 = new WP_Query();
$query1->query( $args );
$queries_before = get_num_queries();
$query2 = new WP_Query();
$query2->query( $args );
$queries_after = get_num_queries();
$this->assertNotSame( $queries_before, $queries_after );
}
/**
* @ticket 22176
*/
public function test_query_cache_filter_request() {
$args = array(
'cache_results' => true,
'fields' => 'ids',
);
$query1 = new WP_Query();
$query1->query( $args );
$queries_before = get_num_queries();
add_filter( 'posts_request', array( $this, 'filter_posts_request' ) );
$query2 = new WP_Query();
$query2->query( $args );
$queries_after = get_num_queries();
$this->assertNotSame( $queries_before, $queries_after );
}
/**
* @ticket 22176
*/
public function test_query_cache_no_caching() {
$args = array(
'cache_results' => true,
'fields' => 'ids',
);
$query1 = new WP_Query();
$query1->query( $args );
$queries_before = get_num_queries();
$query2 = new WP_Query();
$args['cache_results'] = false;
$query2->query( $args );
$queries_after = get_num_queries();
$this->assertNotSame( $queries_before, $queries_after );
}
public function filter_posts_request( $request ) {
return $request . ' -- Add comment';
}
/**
* @ticket 22176
*/
public function test_query_cache_new_post() {
$args = array(
'cache_results' => true,
'fields' => 'ids',
);
$query1 = new WP_Query();
$posts1 = $query1->query( $args );
$p1 = self::factory()->post->create();
$query2 = new WP_Query();
$posts2 = $query2->query( $args );
$this->assertNotSame( $posts1, $posts2 );
$this->assertContains( $p1, $posts2 );
$this->assertNotSame( $query1->found_posts, $query2->found_posts );
}
/**
* @ticket 22176
*/
public function test_main_query_sticky_posts_change() {
add_action( 'parse_query', array( $this, 'set_cache_results' ) );
update_option( 'posts_per_page', 5 );
$old_date = date_create( '-25 hours' );
$old_post = self::factory()->post->create( array( 'post_date' => $old_date->format( 'Y-m-d H:i:s' ) ) );
// Post is unstuck.
$this->go_to( '/' );
$unstuck = $GLOBALS['wp_query']->posts;
$unstuck_ids = wp_list_pluck( $unstuck, 'ID' );
$expected = array_reverse( self::$posts );
$this->assertSame( $expected, $unstuck_ids );
// Stick the post.
stick_post( $old_post );
$this->go_to( '/' );
$stuck = $GLOBALS['wp_query']->posts;
$stuck_ids = wp_list_pluck( $stuck, 'ID' );
$expected = array_reverse( self::$posts );
array_unshift( $expected, $old_post );
$this->assertSame( $expected, $stuck_ids );
}
/**
* @ticket 22176
*/
public function test_main_query_in_query_sticky_posts_change() {
add_action( 'parse_query', array( $this, 'set_cache_results' ) );
update_option( 'posts_per_page', 5 );
$middle_post = self::$posts[2];
// Post is unstuck.
$this->go_to( '/' );
$unstuck = $GLOBALS['wp_query']->posts;
$unstuck_ids = wp_list_pluck( $unstuck, 'ID' );
$expected = array_reverse( self::$posts );
$this->assertSame( $expected, $unstuck_ids );
// Stick the post.
stick_post( $middle_post );
$this->go_to( '/' );
$stuck = $GLOBALS['wp_query']->posts;
$stuck_ids = wp_list_pluck( $stuck, 'ID' );
$expected = array_diff( array_reverse( self::$posts ), array( $middle_post ) );
array_unshift( $expected, $middle_post );
$this->assertSame( $expected, $stuck_ids );
}
/**
* @ticket 22176
*/
public function test_query_sticky_posts_change() {
add_action( 'parse_query', array( $this, 'set_cache_results' ) );
$old_date = date_create( '-25 hours' );
$old_post = self::factory()->post->create( array( 'post_date' => $old_date->format( 'Y-m-d H:i:s' ) ) );
// Post is unstuck.
$unstuck = new WP_Query( array( 'posts_per_page' => 5 ) );
$unstuck_ids = wp_list_pluck( $unstuck->posts, 'ID' );
$expected = array_reverse( self::$posts );
$this->assertSame( $expected, $unstuck_ids );
// Stick the post.
stick_post( $old_post );
$stuck = new WP_Query( array( 'posts_per_page' => 5 ) );
$stuck_ids = wp_list_pluck( $stuck->posts, 'ID' );
$expected = array_reverse( self::$posts );
array_unshift( $expected, $old_post );
$this->assertSame( $expected, $stuck_ids );
// Ignore sticky posts.
$ignore_stuck = new WP_Query(
array(
'posts_per_page' => 5,
'ignore_sticky_posts' => true,
)
);
$ignore_stuck_ids = wp_list_pluck( $ignore_stuck->posts, 'ID' );
$expected = array_reverse( self::$posts );
$this->assertSame( $expected, $ignore_stuck_ids );
// Just to make sure everything has changed.
$this->assertNotSame( $unstuck, $stuck );
}
/**
* @ticket 22176
*/
public function test_query_in_query_sticky_posts_change() {
add_action( 'parse_query', array( $this, 'set_cache_results' ) );
$middle_post = self::$posts[2];
// Post is unstuck.
$unstuck = new WP_Query( array( 'posts_per_page' => 5 ) );
$unstuck_ids = wp_list_pluck( $unstuck->posts, 'ID' );
$expected = array_reverse( self::$posts );
$this->assertSame( $expected, $unstuck_ids );
// Stick the post.
stick_post( $middle_post );
$stuck = new WP_Query( array( 'posts_per_page' => 5 ) );
$stuck_ids = wp_list_pluck( $stuck->posts, 'ID' );
$expected = array_diff( array_reverse( self::$posts ), array( $middle_post ) );
array_unshift( $expected, $middle_post );
$this->assertSame( $expected, $stuck_ids );
// Ignore sticky posts.
$ignore_stuck = new WP_Query(
array(
'posts_per_page' => 5,
'ignore_sticky_posts' => true,
)
);
$ignore_stuck_ids = wp_list_pluck( $ignore_stuck->posts, 'ID' );
$expected = array_reverse( self::$posts );
$this->assertSame( $expected, $ignore_stuck_ids );
// Just to make sure everything has changed.
$this->assertNotSame( $unstuck, $stuck );
}
public function set_cache_results( $q ) {
$q->set( 'cache_results', true );
}
/**
* @ticket 22176
*/
public function test_query_cache_different_args() {
$args = array(
'cache_results' => true,
'fields' => 'ids',
);
$query1 = new WP_Query();
$posts1 = $query1->query( $args );
$args = array(
'cache_results' => true,
'fields' => 'ids',
'suppress_filters' => true,
'cache_results' => true,
'update_post_meta_cache' => false,
'update_post_term_cache' => false,
'lazy_load_term_meta' => false,
);
$queries_before = get_num_queries();
$query2 = new WP_Query();
$posts2 = $query2->query( $args );
$queries_after = get_num_queries();
$this->assertSame( $queries_before, $queries_after );
$this->assertSame( $posts1, $posts2 );
$this->assertSame( $query1->found_posts, $query2->found_posts );
}
/**
* @ticket 22176
*/
public function test_query_cache_different_fields() {
$args = array(
'cache_results' => true,
'fields' => 'all',
);
$query1 = new WP_Query();
$query1->query( $args );
$args = array(
'cache_results' => true,
'fields' => 'id=>parent',
);
$queries_before = get_num_queries();
$query2 = new WP_Query();
$query2->query( $args );
$queries_after = get_num_queries();
$this->assertSame( $queries_before, $queries_after );
$this->assertCount( 5, $query1->posts );
$this->assertCount( 5, $query2->posts );
$this->assertSame( $query1->found_posts, $query2->found_posts );
/*
* Make sure the returned post objects differ due to the field argument.
*
* This uses assertNotEquals rather than assertNotSame as the former is
* agnostic to the instance ID of objects, whereas the latter will take
* it in to account. The test needs to discard the instance ID when
* confirming inequality.
*/
$this->assertNotEquals( $query1->posts, $query2->posts );
}
/**
* @ticket 22176
*/
public function test_query_cache_logged_in() {
$user_id = self::$author_id;
self::factory()->post->create(
array(
'post_status' => 'private',
'post_author' => $user_id,
)
);
$args = array(
'cache_results' => true,
'author' => $user_id,
);
$query1 = new WP_Query();
$posts1 = $query1->query( $args );
wp_set_current_user( $user_id );
$query2 = new WP_Query();
$posts2 = $query2->query( $args );
$this->assertEmpty( $posts1 );
$this->assertNotSame( $posts1, $posts2 );
$this->assertNotSame( $query1->found_posts, $query2->found_posts );
}
/**
* @ticket 22176
*/
public function test_query_cache_logged_in_password() {
$user_id = self::$author_id;
self::factory()->post->create(
array(
'post_title' => 'foo',
'post_password' => 'password',
'post_author' => $user_id,
)
);
$args = array(
'cache_results' => true,
's' => 'foo',
);
$query1 = new WP_Query();
$posts1 = $query1->query( $args );
wp_set_current_user( $user_id );
$query2 = new WP_Query();
$posts2 = $query2->query( $args );
$this->assertEmpty( $posts1 );
$this->assertNotSame( $posts1, $posts2 );
$this->assertNotSame( $query1->found_posts, $query2->found_posts );
}
/**
* @ticket 22176
*/
public function test_query_cache_new_comment() {
$args = array(
'cache_results' => true,
'fields' => 'ids',
'comment_count' => 1,
);
$query1 = new WP_Query();
$posts1 = $query1->query( $args );
self::factory()->comment->create( array( 'comment_post_ID' => self::$posts[0] ) );
$query2 = new WP_Query();
$posts2 = $query2->query( $args );
$this->assertNotSame( $posts1, $posts2 );
$this->assertContains( self::$posts[0], $posts2 );
$this->assertNotEmpty( $posts2 );
$this->assertNotSame( $query1->found_posts, $query2->found_posts );
}
/**
* @ticket 22176
*/
public function test_main_comments_feed_includes_attachment_comments() {
$attachment_id = self::factory()->post->create( array( 'post_type' => 'attachment' ) );
$comment_id = self::factory()->comment->create(
array(
'comment_post_ID' => $attachment_id,
'comment_approved' => '1',
)
);
$args = array(
'cache_results' => true,
'withcomments' => 1,
'feed' => 'feed',
);
$query1 = new WP_Query();
$query1->query( $args );
$query2 = new WP_Query();
$query2->query( $args );
$this->assertTrue( $query1->have_comments() );
$this->assertTrue( $query2->have_comments() );
$feed_comment = $query1->next_comment();
$this->assertEquals( $comment_id, $feed_comment->comment_ID );
}
/**
* @ticket 22176
*/
public function test_query_cache_delete_comment() {
$comment_id = self::factory()->comment->create( array( 'comment_post_ID' => self::$posts[0] ) );
$args = array(
'cache_results' => true,
'fields' => 'ids',
'comment_count' => 1,
);
$query1 = new WP_Query();
$posts1 = $query1->query( $args );
wp_delete_comment( $comment_id, true );
$query2 = new WP_Query();
$posts2 = $query2->query( $args );
$this->assertNotSame( $posts1, $posts2 );
$this->assertEmpty( $posts2 );
$this->assertNotSame( $query1->found_posts, $query2->found_posts );
}
/**
* @ticket 22176
*/
public function test_query_cache_update_post() {
$p1 = self::$posts[0];
$args = array(
'cache_results' => true,
'fields' => 'ids',
);
$query1 = new WP_Query();
$posts1 = $query1->query( $args );
wp_update_post(
array(
'ID' => $p1,
'post_status' => 'draft',
)
);
$query2 = new WP_Query();
$posts2 = $query2->query( $args );
$this->assertNotSame( $posts1, $posts2 );
$this->assertContains( $p1, $posts1 );
$this->assertNotContains( $p1, $posts2 );
$this->assertNotSame( $query1->found_posts, $query2->found_posts );
}
/**
* @ticket 22176
*/
public function test_query_cache_new_meta() {
$p1 = self::$posts[1]; // Post 0 already has a color meta value.
$args = array(
'cache_results' => true,
'fields' => 'ids',
'meta_query' => array(
array(
'key' => 'color',
),
),
);
$query1 = new WP_Query();
$posts1 = $query1->query( $args );
add_post_meta( $p1, 'color', 'black' );
$query2 = new WP_Query();
$posts2 = $query2->query( $args );
$this->assertNotSame( $posts1, $posts2 );
$this->assertContains( $p1, $posts2 );
$this->assertNotSame( $query1->found_posts, $query2->found_posts );
}
/**
* @ticket 22176
*/
public function test_query_cache_update_meta() {
// Posts[0] already has a color meta value set to #000000.
$p1 = self::$posts[0];
$args = array(
'cache_results' => true,
'fields' => 'ids',
'meta_query' => array(
array(
'key' => 'color',
'value' => '#000000',
),
),
);
$query1 = new WP_Query();
$posts1 = $query1->query( $args );
update_post_meta( $p1, 'color', 'blue' );
$query2 = new WP_Query();
$posts2 = $query2->query( $args );
$this->assertNotSame( $posts1, $posts2 );
$this->assertContains( $p1, $posts1 );
$this->assertEmpty( $posts2 );
$this->assertNotSame( $query1->found_posts, $query2->found_posts );
}
/**
* @ticket 22176
*/
public function test_query_cache_delete_attachment() {
$p1 = self::factory()->post->create(
array(
'post_type' => 'attachment',
'post_status' => 'inherit',
)
);
$args = array(
'cache_results' => true,
'fields' => 'ids',
'post_type' => 'attachment',
'post_status' => 'inherit',
);
$query1 = new WP_Query();
$posts1 = $query1->query( $args );
wp_delete_attachment( $p1 );
$query2 = new WP_Query();
$posts2 = $query2->query( $args );
$this->assertNotSame( $posts1, $posts2 );
$this->assertContains( $p1, $posts1 );
$this->assertEmpty( $posts2 );
$this->assertNotSame( $query1->found_posts, $query2->found_posts );
}
/**
* @ticket 22176
*/
public function test_query_cache_delete_meta() {
// Post 0 already has a color meta value.
$p1 = self::$posts[1];
add_post_meta( $p1, 'color', 'black' );
$args = array(
'cache_results' => true,
'fields' => 'ids',
'meta_query' => array(
array(
'key' => 'color',
),
),
);
$query1 = new WP_Query();
$posts1 = $query1->query( $args );
delete_post_meta( $p1, 'color' );
$query2 = new WP_Query();
$posts2 = $query2->query( $args );
$this->assertNotSame( $posts1, $posts2 );
$this->assertContains( $p1, $posts1 );
$this->assertNotEmpty( $posts2 );
$this->assertNotSame( $query1->found_posts, $query2->found_posts );
}
/**
* @ticket 22176
*/
public function test_query_cache_new_term() {
// Post 0 already has the category foo.
$p1 = self::$posts[1];
$args = array(
'cache_results' => true,
'fields' => 'ids',
'tax_query' => array(
array(
'taxonomy' => 'category',
'terms' => array( 'foo' ),
'field' => 'slug',
),
),
);
$query1 = new WP_Query();
$posts1 = $query1->query( $args );
wp_set_post_terms( $p1, array( self::$t1 ), 'category' );
$query2 = new WP_Query();
$posts2 = $query2->query( $args );
$this->assertNotSame( $posts1, $posts2 );
$this->assertContains( $p1, $posts2 );
$this->assertNotSame( $query1->found_posts, $query2->found_posts );
}
/**
* @ticket 22176
*/
public function test_query_cache_delete_term() {
// Post 0 already has the category foo.
$p1 = self::$posts[1];
register_taxonomy( 'wptests_tax1', 'post' );
$t1 = self::factory()->term->create( array( 'taxonomy' => 'wptests_tax1' ) );
wp_set_object_terms( $p1, array( $t1 ), 'wptests_tax1' );
$args = array(
'cache_results' => true,
'fields' => 'ids',
'tax_query' => array(
array(
'taxonomy' => 'wptests_tax1',
'terms' => array( $t1 ),
'field' => 'term_id',
),
),
);
$query1 = new WP_Query();
$posts1 = $query1->query( $args );
wp_delete_term( $t1, 'wptests_tax1' );
$query2 = new WP_Query();
$posts2 = $query2->query( $args );
$this->assertNotSame( $posts1, $posts2 );
$this->assertContains( $p1, $posts1 );
$this->assertEmpty( $posts2 );
$this->assertNotSame( $query1->found_posts, $query2->found_posts );
}
}
@@ -39,6 +39,7 @@ class Tests_Query_CommentFeed extends WP_UnitTestCase {
'update_post_term_cache' => false,
'ignore_sticky_posts' => false,
'no_found_rows' => true,
'cache_results' => false,
);
$q1->query( $args );
$num_queries = $wpdb->num_queries;
@@ -98,6 +99,7 @@ class Tests_Query_CommentFeed extends WP_UnitTestCase {
'update_post_meta_cache' => false,
'update_post_term_cache' => false,
'ignore_sticky_posts' => false,
'cache_results' => false,
);
$q1->query( $args );