Index: wp-includes/query.php =================================================================== --- wp-includes/query.php (revision 15490) +++ wp-includes/query.php (working copy) @@ -1555,15 +1555,17 @@ // First let's clear some variables $distinct = ''; + $fields = "$wpdb->posts.ID"; // see #10964 + $quick_fields = "$wpdb->posts.*"; $whichcat = ''; $whichauthor = ''; $whichmimetype = ''; + $search = ''; + $join = ''; $where = ''; + $groupby = ''; + $orderby = ''; $limits = ''; - $join = ''; - $search = ''; - $groupby = ''; - $fields = "$wpdb->posts.*"; $post_status_join = false; $page = 1; @@ -2207,17 +2209,32 @@ $orderby = $q['orderby']; + // Set up quick_* defaults from the standard placeholders, before filtering + $quick_distinct = $distinct; + $quick_join = $join; + $quick_where = $where; + $quick_groupby = $groupby; + // Apply post-paging filters on where and join. Only plugins that // manipulate paging queries should use these hooks. if ( !$q['suppress_filters'] ) { - $where = apply_filters('posts_where_paged', $where); - $groupby = apply_filters('posts_groupby', $groupby); - $join = apply_filters('posts_join_paged', $join); + $distinct = apply_filters('posts_distinct', $distinct, false); + $quick_distinct = apply_filters('posts_distinct', $quick_distinct, true); + + $fields = apply_filters('posts_fields', $fields, false); + $quick_fields = apply_filters('posts_fields', $quick_fields, true); + + $join = apply_filters('posts_join_paged', $join, false); + $quick_join = apply_filters('posts_join_paged', $quick_join, true); + + $where = apply_filters('posts_where_paged', $where, false); + $quick_where = apply_filters('posts_where_paged', $quick_where, true); + + $groupby = apply_filters('posts_groupby', $groupby, false); + $quick_groupby = apply_filters('posts_groupby', $quick_groupby, true); + $orderby = apply_filters('posts_orderby', $orderby); - $distinct = apply_filters('posts_distinct', $distinct); - $limits = apply_filters( 'post_limits', $limits ); - - $fields = apply_filters('posts_fields', $fields); + $limits = apply_filters( 'post_limits', $limits); } // Announce current selection parameters. For use by caching plugins. @@ -2225,28 +2242,81 @@ // Filter again for the benefit of caching plugins. Regular plugins should use the hooks above. if ( !$q['suppress_filters'] ) { - $where = apply_filters('posts_where_request', $where); - $groupby = apply_filters('posts_groupby_request', $groupby); - $join = apply_filters('posts_join_request', $join); + $distinct = apply_filters('posts_distinct_request', $distinct, false); + $quick_distinct = apply_filters('posts_distinct_request', $quick_distinct, true); + + $fields = apply_filters('posts_fields_request', $fields, false); + $quick_fields = apply_filters('posts_fields_request', $quick_fields, true); + + $join = apply_filters('posts_join_request', $join, false); + $quick_join = apply_filters('posts_join_request', $quick_join, true); + + $where = apply_filters('posts_where_request', $where, false); + $quick_where = apply_filters('posts_where_request', $quick_where, true); + + $groupby = apply_filters('posts_groupby_request', $groupby, false); + $quick_groupby = apply_filters('posts_groupby_request', $quick_groupby, true); + $orderby = apply_filters('posts_orderby_request', $orderby); - $distinct = apply_filters('posts_distinct_request', $distinct); - $fields = apply_filters('posts_fields_request', $fields); - $limits = apply_filters( 'post_limits_request', $limits ); + $limits = apply_filters( 'post_limits_request', $limits); } if ( ! empty($groupby) ) $groupby = 'GROUP BY ' . $groupby; + if ( ! empty($quick_groupby) ) + $quick_groupby = 'GROUP BY ' . $quick_groupby; if ( !empty( $orderby ) ) $orderby = 'ORDER BY ' . $orderby; $found_rows = ''; if ( !empty($limits) ) $found_rows = 'SQL_CALC_FOUND_ROWS'; - $this->request = " SELECT $found_rows $distinct $fields FROM $wpdb->posts $join WHERE 1=1 $where $groupby $orderby $limits"; - if ( !$q['suppress_filters'] ) - $this->request = apply_filters('posts_request', $this->request); + if ( empty($limits) ) { + // do a direct query, as there is no benefit in fetching a huge load of IDs in an IN clause + $this->request = " SELECT $distinct $fields FROM $wpdb->posts $join WHERE 1=1 $where $groupby $orderby"; + $this->quick_request = " SELECT $quick_distinct $quick_fields FROM $wpdb->posts $quick_join WHERE 1=1 $quick_where $quick_groupby $orderby"; - $this->posts = $wpdb->get_results($this->request); + if ( !$q['suppress_filters'] ) { + $this->request = apply_filters('posts_request', $this->request, false); + $this->quick_request = apply_filters('posts_request', $this->quick_request, true); + } + + $this->posts = $wpdb->get_results($this->quick_request); + + $this->found_posts = count($this->posts); + $this->found_posts = apply_filters( 'found_posts', $this->found_posts ); + $this->max_num_pages = ceil($this->found_posts / $q['posts_per_page']); + } else { + $this->request = " SELECT $found_rows $distinct $fields FROM $wpdb->posts $join WHERE 1=1 $where $groupby $orderby $limits"; + if ( !$q['suppress_filters'] ) + $this->request = apply_filters('posts_request', $this->request); + + $post_ids = $wpdb->get_col($this->request); + + if ( !$post_ids ) { + $this->found_posts = 0; + $this->found_posts = apply_filters( 'found_posts', $this->found_posts ); + $this->max_num_pages = ceil($this->found_posts / $q['posts_per_page']); + + $this->quick_request = " SELECT $quick_distinct $quick_fields FROM $wpdb->posts $quick_join WHERE 1=1 $quick_where $quick_groupby $orderby"; + if ( !$q['suppress_filters'] ) + $this->quick_request = apply_filters('posts_request', $this->quick_request, true); + $this->posts = array(); // no point in querying, since there are no posts + } else { + $found_posts_query = apply_filters( 'found_posts_query', 'SELECT FOUND_ROWS()' ); + $this->found_posts = $wpdb->get_var( $found_posts_query ); + $this->found_posts = apply_filters( 'found_posts', $this->found_posts ); + $this->max_num_pages = ceil($this->found_posts / $q['posts_per_page']); + + $this->quick_request = " SELECT $quick_distinct $quick_fields FROM $wpdb->posts $quick_join WHERE 1 = 1 $quick_where AND $wpdb->posts.ID IN ( " . implode(',', $post_ids) . " ) $quick_groupby ORDER BY FIELD( $wpdb->posts.ID, " . implode(',', $post_ids) . ") "; + + if ( !$q['suppress_filters'] ) + $this->quick_request = apply_filters('posts_request', $this->quick_request, true); + + $this->posts = $wpdb->get_results($this->quick_request); + } + } + // Raw results filter. Prior to status checks. if ( !$q['suppress_filters'] ) $this->posts = apply_filters('posts_results', $this->posts); @@ -2264,13 +2334,6 @@ $this->comment_count = count($this->comments); } - if ( !empty($limits) ) { - $found_posts_query = apply_filters( 'found_posts_query', 'SELECT FOUND_ROWS()' ); - $this->found_posts = $wpdb->get_var( $found_posts_query ); - $this->found_posts = apply_filters( 'found_posts', $this->found_posts ); - $this->max_num_pages = ceil($this->found_posts / $q['posts_per_page']); - } - // Check post status to determine if post should be displayed. if ( !empty($this->posts) && ($this->is_single || $this->is_page) ) { $status = get_post_status($this->posts[0]);