From 765e23a4a6c2969232b930897553f5ca3a36858b Mon Sep 17 00:00:00 2001 From: Boone Gorges Date: Tue, 12 Apr 2016 20:36:31 +0000 Subject: [PATCH] Use `LEFT JOIN` when building `WP_Tax_Query` SQL. `LEFT JOIN` ensures that `NOT EXISTS` queries will not miss posts that have no taxonomy data whatsoever. Props swissspidy, crstauf. Fixes #36343. git-svn-id: https://develop.svn.wordpress.org/trunk@37184 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/class-wp-tax-query.php | 2 +- tests/phpunit/tests/query/taxQuery.php | 45 ++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/src/wp-includes/class-wp-tax-query.php b/src/wp-includes/class-wp-tax-query.php index a842b2c3fe..e220806401 100644 --- a/src/wp-includes/class-wp-tax-query.php +++ b/src/wp-includes/class-wp-tax-query.php @@ -440,7 +440,7 @@ class WP_Tax_Query { // Store the alias with this clause, so later siblings can use it. $clause['alias'] = $alias; - $join .= " INNER JOIN $wpdb->term_relationships"; + $join .= " LEFT JOIN $wpdb->term_relationships"; $join .= $i ? " AS $alias" : ''; $join .= " ON ($this->primary_table.$this->primary_id_column = $alias.object_id)"; } diff --git a/tests/phpunit/tests/query/taxQuery.php b/tests/phpunit/tests/query/taxQuery.php index 8248b196cf..7582eb2e1a 100644 --- a/tests/phpunit/tests/query/taxQuery.php +++ b/tests/phpunit/tests/query/taxQuery.php @@ -409,6 +409,51 @@ class Tests_Query_TaxQuery extends WP_UnitTestCase { $this->assertEqualSets( array( $p1, $p3 ), $q->posts ); } + /** + * @ticket 36343 + */ + public function test_tax_query_operator_not_exists_combined() { + register_post_type( 'wptests_cpt1' ); + register_taxonomy( 'wptests_tax1', 'wptests_cpt1' ); + register_taxonomy( 'wptests_tax2', 'wptests_cpt1' ); + + $t1 = self::factory()->term->create( array( 'taxonomy' => 'wptests_tax1' ) ); + $t2 = self::factory()->term->create( array( 'taxonomy' => 'wptests_tax1' ) ); + $t3 = self::factory()->term->create( array( 'taxonomy' => 'wptests_tax2' ) ); + + $p1 = self::factory()->post->create( array( 'post_type' => 'wptests_cpt1' ) ); + $p2 = self::factory()->post->create( array( 'post_type' => 'wptests_cpt1' ) ); + $p3 = self::factory()->post->create( array( 'post_type' => 'wptests_cpt1' ) ); + $p4 = self::factory()->post->create( array( 'post_type' => 'wptests_cpt1' ) ); + + wp_set_object_terms( $p1, array( $t1 ), 'wptests_tax1' ); + wp_set_object_terms( $p2, array( $t2 ), 'wptests_tax1' ); + wp_set_object_terms( $p3, array( $t3 ), 'wptests_tax2' ); + + $q = new WP_Query( array( + 'post_type' => 'wptests_cpt1', + 'fields' => 'ids', + 'tax_query' => array( + 'relation' => 'OR', + array( + 'taxonomy' => 'wptests_tax1', + 'operator' => 'NOT EXISTS', + ), + array( + 'taxonomy' => 'wptests_tax1', + 'field' => 'slug', + 'terms' => get_term_field( 'slug', $t1 ), + ), + ), + ) ); + + unregister_post_type( 'wptests_cpt1' ); + unregister_taxonomy( 'wptests_tax1' ); + unregister_taxonomy( 'wptests_tax2' ); + + $this->assertEqualSets( array( $p1, $p3, $p4 ), $q->posts ); + } + /** * @ticket 29181 */