From 3f7bc21548bedb76054076b25becc983d40d76cc Mon Sep 17 00:00:00 2001 From: Boone Gorges Date: Wed, 13 Sep 2017 14:48:45 +0000 Subject: [PATCH] Taxonomy: Force a `DISTINCT` term query when result count matters. Generally, duplicate terms returned by a term query are eliminated in PHP, after the database query takes place. This technique doesn't work properly when the query parameters specify the `number` of results, since the results of a `SELECT ... LIMIT x...` query may be deduplicated to a count less than `x`. In these cases, we force the original query to be `DISTINCT`. Props elvishp2006. Fixes #41796. Built from https://develop.svn.wordpress.org/trunk@41377 git-svn-id: http://core.svn.wordpress.org/trunk@41210 1a063a9b-81f0-0310-95a4-ce76da25c4cd --- wp-includes/class-wp-term-query.php | 15 +++++++++++++-- wp-includes/version.php | 2 +- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/wp-includes/class-wp-term-query.php b/wp-includes/class-wp-term-query.php index 12e7dec242..f6f53f210c 100644 --- a/wp-includes/class-wp-term-query.php +++ b/wp-includes/class-wp-term-query.php @@ -551,6 +551,16 @@ class WP_Term_Query { $limits = ''; } + $do_distinct = false; + + /* + * Duplicate terms are generally removed when necessary after the database query. + * But when a LIMIT clause is included in the query, we let MySQL enforce + * distinctness so the count is correct. + */ + if ( ! empty( $limits ) && 'all_with_object_id' !== $args['fields'] ) { + $do_distinct = true; + } if ( ! empty( $args['search'] ) ) { $this->sql_clauses['where']['search'] = $this->get_search_sql( $args['search'] ); @@ -568,8 +578,7 @@ class WP_Term_Query { if ( ! empty( $meta_clauses ) ) { $join .= $mq_sql['join']; $this->sql_clauses['where']['meta_query'] = preg_replace( '/^\s*AND\s*/', '', $mq_sql['where'] ); - $distinct .= "DISTINCT"; - + $do_distinct = true; } $selects = array(); @@ -631,6 +640,8 @@ class WP_Term_Query { $where = implode( ' AND ', $this->sql_clauses['where'] ); + $distinct = $do_distinct ? 'DISTINCT' : ''; + /** * Filters the terms query SQL clauses. * diff --git a/wp-includes/version.php b/wp-includes/version.php index ad11c3615e..79383f07fc 100644 --- a/wp-includes/version.php +++ b/wp-includes/version.php @@ -4,7 +4,7 @@ * * @global string $wp_version */ -$wp_version = '4.9-alpha-41376'; +$wp_version = '4.9-alpha-41377'; /** * Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.