<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[53941] trunk: Query: Cache post ID database query within `WP_Query`.</title>
</head>
<body>
<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; }
#msg dl a { font-weight: bold}
#msg dl a:link { color:#fc3; }
#msg dl a:active { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { white-space: pre-line; overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta" style="font-size: 105%">
<dt style="float: left; width: 6em; font-weight: bold">Revision</dt> <dd><a style="font-weight: bold" href="https://core.trac.wordpress.org/changeset/53941">53941</a><script type="application/ld+json">{"@context":"http://schema.org","@type":"EmailMessage","description":"Review this Commit","action":{"@type":"ViewAction","url":"https://core.trac.wordpress.org/changeset/53941","name":"Review Commit"}}</script></dd>
<dt style="float: left; width: 6em; font-weight: bold">Author</dt> <dd>peterwilsoncc</dd>
<dt style="float: left; width: 6em; font-weight: bold">Date</dt> <dd>2022-08-25 04:21:40 +0000 (Thu, 25 Aug 2022)</dd>
</dl>
<pre style='padding-left: 1em; margin: 2em 0; border-left: 2px solid #ccc; line-height: 1.25; font-size: 105%; font-family: sans-serif'>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 <a href="https://core.trac.wordpress.org/ticket/22176">#22176</a>.</pre>
<h3>Modified Paths</h3>
<ul>
<li><a href="#trunksrcwpincludesclasswpqueryphp">trunk/src/wp-includes/class-wp-query.php</a></li>
<li><a href="#trunktestsphpunittestsquerycommentFeedphp">trunk/tests/phpunit/tests/query/commentFeed.php</a></li>
</ul>
<h3>Added Paths</h3>
<ul>
<li><a href="#trunktestsphpunittestsquerycacheResultsphp">trunk/tests/phpunit/tests/query/cacheResults.php</a></li>
</ul>
</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunksrcwpincludesclasswpqueryphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-includes/class-wp-query.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/class-wp-query.php 2022-08-24 16:30:31 UTC (rev 53940)
+++ trunk/src/wp-includes/class-wp-query.php 2022-08-25 04:21:40 UTC (rev 53941)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1874,11 +1874,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> if ( ! isset( $q['cache_results'] ) ) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- if ( wp_using_ext_object_cache() ) {
- $q['cache_results'] = false;
- } else {
- $q['cache_results'] = true;
- }
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $q['cache_results'] = true;
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> if ( ! isset( $q['update_post_term_cache'] ) ) {
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -3072,6 +3068,77 @@
</span><span class="cx" style="display: block; padding: 0 10px"> */
</span><span class="cx" style="display: block; padding: 0 10px"> $this->posts = apply_filters_ref_array( 'posts_pre_query', array( null, &$this ) );
</span><span class="cx" style="display: block; padding: 0 10px">
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ /*
+ * 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;
+ }
+ }
+ }
+ }
+
</ins><span class="cx" style="display: block; padding: 0 10px"> if ( 'ids' === $q['fields'] ) {
</span><span class="cx" style="display: block; padding: 0 10px"> if ( null === $this->posts ) {
</span><span class="cx" style="display: block; padding: 0 10px"> $this->posts = $wpdb->get_col( $this->request );
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -3082,6 +3149,16 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $this->post_count = count( $this->posts );
</span><span class="cx" style="display: block; padding: 0 10px"> $this->set_found_posts( $q, $limits );
</span><span class="cx" style="display: block; padding: 0 10px">
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ 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' );
+ }
+
</ins><span class="cx" style="display: block; padding: 0 10px"> return $this->posts;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -3094,15 +3171,28 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $this->set_found_posts( $q, $limits );
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> /** @var int[] */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $r = array();
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $post_parents = array();
+ $post_ids = array();
+
</ins><span class="cx" style="display: block; padding: 0 10px"> foreach ( $this->posts as $key => $post ) {
</span><span class="cx" style="display: block; padding: 0 10px"> $this->posts[ $key ]->ID = (int) $post->ID;
</span><span class="cx" style="display: block; padding: 0 10px"> $this->posts[ $key ]->post_parent = (int) $post->post_parent;
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $r[ (int) $post->ID ] = (int) $post->post_parent;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $post_parents[ (int) $post->ID ] = (int) $post->post_parent;
+ $post_ids[] = (int) $post->ID;
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- return $r;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ 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;
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> if ( null === $this->posts ) {
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -3144,12 +3234,12 @@
</span><span class="cx" style="display: block; padding: 0 10px"> */
</span><span class="cx" style="display: block; padding: 0 10px"> $this->request = apply_filters( 'posts_request_ids', $this->request, $this );
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $ids = $wpdb->get_col( $this->request );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $post_ids = $wpdb->get_col( $this->request );
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- if ( $ids ) {
- $this->posts = $ids;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ if ( $post_ids ) {
+ $this->posts = $post_ids;
</ins><span class="cx" style="display: block; padding: 0 10px"> $this->set_found_posts( $q, $limits );
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- _prime_post_caches( $ids, $q['update_post_term_cache'], $q['update_post_meta_cache'] );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ _prime_post_caches( $post_ids, $q['update_post_term_cache'], $q['update_post_meta_cache'] );
</ins><span class="cx" style="display: block; padding: 0 10px"> } else {
</span><span class="cx" style="display: block; padding: 0 10px"> $this->posts = array();
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -3165,6 +3255,18 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $this->posts = array_map( 'get_post', $this->posts );
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ 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' );
+ }
+
</ins><span class="cx" style="display: block; padding: 0 10px"> if ( ! empty( $this->posts ) && $q['update_menu_item_cache'] ) {
</span><span class="cx" style="display: block; padding: 0 10px"> update_menu_item_cache( $this->posts );
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -3201,14 +3303,14 @@
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> $comments_request = "SELECT {$wpdb->comments}.comment_ID FROM {$wpdb->comments} $cjoin $cwhere $cgroupby $corderby $climits";
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $key = md5( $comments_request );
- $last_changed = wp_cache_get_last_changed( 'comment' );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $comment_key = md5( $comments_request );
+ $comment_last_changed = wp_cache_get_last_changed( 'comment' );
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $cache_key = "comment_feed:$key:$last_changed";
- $comment_ids = wp_cache_get( $cache_key, 'comment' );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $comment_cache_key = "comment_feed:$comment_key:$comment_last_changed";
+ $comment_ids = wp_cache_get( $comment_cache_key, 'comment' );
</ins><span class="cx" style="display: block; padding: 0 10px"> if ( false === $comment_ids ) {
</span><span class="cx" style="display: block; padding: 0 10px"> $comment_ids = $wpdb->get_col( $comments_request );
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- wp_cache_add( $cache_key, $comment_ids, 'comment' );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ wp_cache_add( $comment_cache_key, $comment_ids, 'comment' );
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> _prime_comment_caches( $comment_ids, false );
</span><span class="cx" style="display: block; padding: 0 10px">
</span></span></pre></div>
<a id="trunktestsphpunittestsquerycacheResultsphp"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: trunk/tests/phpunit/tests/query/cacheResults.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/tests/phpunit/tests/query/cacheResults.php (rev 0)
+++ trunk/tests/phpunit/tests/query/cacheResults.php 2022-08-25 04:21:40 UTC (rev 53941)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -0,0 +1,896 @@
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+<?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 );
+ }
+}
</ins><span class="cx" style="display: block; padding: 0 10px">Property changes on: trunk/tests/phpunit/tests/query/cacheResults.php
</span><span class="cx" style="display: block; padding: 0 10px">___________________________________________________________________
</span></span></pre></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: svn:eol-style</h4></div>
<ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+native
</ins><span class="cx" style="display: block; padding: 0 10px">\ No newline at end of property
</span><a id="trunktestsphpunittestsquerycommentFeedphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/tests/phpunit/tests/query/commentFeed.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/tests/phpunit/tests/query/commentFeed.php 2022-08-24 16:30:31 UTC (rev 53940)
+++ trunk/tests/phpunit/tests/query/commentFeed.php 2022-08-25 04:21:40 UTC (rev 53941)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -39,6 +39,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> 'update_post_term_cache' => false,
</span><span class="cx" style="display: block; padding: 0 10px"> 'ignore_sticky_posts' => false,
</span><span class="cx" style="display: block; padding: 0 10px"> 'no_found_rows' => true,
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ 'cache_results' => false,
</ins><span class="cx" style="display: block; padding: 0 10px"> );
</span><span class="cx" style="display: block; padding: 0 10px"> $q1->query( $args );
</span><span class="cx" style="display: block; padding: 0 10px"> $num_queries = $wpdb->num_queries;
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -98,6 +99,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> 'update_post_meta_cache' => false,
</span><span class="cx" style="display: block; padding: 0 10px"> 'update_post_term_cache' => false,
</span><span class="cx" style="display: block; padding: 0 10px"> 'ignore_sticky_posts' => false,
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ 'cache_results' => false,
</ins><span class="cx" style="display: block; padding: 0 10px"> );
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> $q1->query( $args );
</span></span></pre>
</div>
</div>
</body>
</html>